mchck / programmer

SWD programmer
GNU General Public License v3.0
21 stars 11 forks source link

add support for K22 family #2

Closed acornejo closed 10 years ago

acornejo commented 10 years ago

This adds support for multiple sector blocks, and phrase size different than 4 bytes. Tested succesfuly on K22DX chip.

Currently, to differentiate between K22 and K20 we check FAMID and DIEID.

The DIEID is a bit of a hack, but is reliable enough for the OpenOCD people. Also, FAMID+DIEID should be unique to chip. While its possible that future revisions of the K22 change the DIEID, at least this will work for "some" versions of the K22, other can be added in the future.

acornejo commented 10 years ago

Found an alternative to differentiate between K20 and K22.

K20 devices have <= 128kb flash, while K22 devices have >= 128kb of flash, thus the only overlap is exactly @128kb flash. However, the K20 model with 128kb flash has 16kb of ram, and the K22 model with 128kb flash has 32kb of ram.

Would you prefer that @corecode? Let me know, I would really like to get this merged so I don't have to mantain the fork of my own and others can benefit of the work (especially since MK20's are so hard to come by, while MK22 are more readily available and still elegible for free samples).

kfoltman commented 10 years ago

On 21/05/14 05:26, Alex Cornejo wrote:

Found an alternative to differentiate between K20 and K22.

There is an MK20DX256 model AFAIK.

K.

acornejo commented 10 years ago

afaik there is no MK20DX256 with 48 pins (i.e. mchck compatible), or at least none that I can find in freescale.com. Could you provide a reference?

kfoltman commented 10 years ago

On 21/05/14 13:07, Alex Cornejo wrote:

afaik there is no MK20DX256 with 48 pins (i.e. mchck compatible), or at least none that I can find in freescale.com. Could you provide a reference?

Yes, I meant a 64-pin one - used one in a different project, but with mchck as an SWD programmer, with some changes.

K.

acornejo commented 10 years ago

Yup, that would be the mk20dx256vlh7.

Fortunately, there is no mk22dx256vlh7 (i.e. 256kb and 64 pins on K22 family).

Thus, we can still detect it. So to summarize, the two proposed detection mechanisms are.

  1. Use FAMID+DIEID (current patch).
  2. Use FAMID+PINID+PFSIZE+RAMSIZE

The OpenOCD people use FAMID+DIED, but this is a bit hacky since a particular model could potentially may have one or more DIED on different revisions, and they are not specified in the datasheet.

Using FAMID+PINID+PFSIZE+RAMSIZE seems a "tad" les hackish, since their values ARE specified on the datasheet.

corecode commented 10 years ago

Let's use the DIEID, but abort if it is all 0. Have a hash that maps FAMID+DIEID to the different sizes.

On 05/21/2014 02:27 PM, Alex Cornejo wrote:

Yup, that would be the mk20dx256vlh7.

Fortunately, there is no mk22dx256vlh7 (i.e. 256kb and 64 pins on K22 family).

Thus, we can still detect it. So to summarize, the two proposed detection mechanisms are.

  1. Use FAMID+DIEID (current patch).
  2. Use FAMID+PINID+PFSIZE+RAMSIZE

The OpenOCD people use FAMID+DIED, but this is a bit hacky since a particular model could potentially may have one or more DIED on different revisions, and they are not specified in the datasheet.

Using FAMID+PINID+PFSIZE+RAMSIZE seems a "tad" les hackish, since their values ARE specified on the datasheet.

— Reply to this email directly or view it on GitHub https://github.com/mchck/programmer/pull/2#issuecomment-43747558.

acornejo commented 10 years ago

Just want to confirm what you mean by abort.

Read DIED, if it all zeros, then assume it has sector_size=1024, sector_blocks=1, phrase_size=4 (i.e. assume it is a MK20DX32VLF5).

Actually, we will always assume its a MK20DX32VLF5 unless:

DIED is non zeros, FAMID+DIEID exists in our hash (we can add support for more processors as we go along).

corecode commented 10 years ago

No, if it is all 0, abort programming. If it is something we don't know, we don't proceed.

On 05/21/2014 02:52 PM, Alex Cornejo wrote:

Just want to confirm what you mean by abort.

Read DIED, if it all zeros, then assume it has sector_size=1024, sector_blocks=1, phrase_size=4 (i.e. assume it is a MK20DX32VLF5).

Actually, we will always assume its a MK20DX32VLF5 unless:

DIED is non zeros, FAMID+DIEID exists in our hash (we can add support for more processors as we go along).

— Reply to this email directly or view it on GitHub https://github.com/mchck/programmer/pull/2#issuecomment-43749860.

acornejo commented 10 years ago

ok. will do.

@corecode, @kfoltman please report the DIEID together with the sector_size/sector_blocks/phrase_size of any kinetis processors you can get your hands on.

acornejo commented 10 years ago

Hi all, I think I figured out how the K2X family works.

They subdivide this family into what I wall call relatives (i just made up that term). The relatives available in the K2X family are:

K20_50, K21_50, K22_50, K20_72, K20_100, K20_120, K21_120, K22_100, K22_120, K24_120

These subdivisions correspond to what they have on their website at http://www.freescale.com/webapp/sps/site/taxonomy.jsp?nodeId=01624698C9DE2DDDA7

All chips within one of these relative category share the same reference manual.

To identify which relative a chip belongs to, we can read bits 11-7 of the SIM_SDID register.

If you read the reference manuals of each of these relatives you will observe, each of them defines different values for these bits. What is confusing is that some of them call these bits "reserved" and others call them DIEID.

Example (from their respective reference manuals)

K20_50 relatives call these bits RESERVED and specify them as 00000 K20_72 relatives call these bits RESERVED and specify them as 00001 K20_120 relatives call these bits RESERVED and specify them as 00011 K21_120 relatives call these bits DIED and specify them as 00110 K22_50 relatives call these bits DIED and specify them as 00100

Now, the beauty is that all chips within each of the relatives share the same sector_size, sector_blocks and phrase_size. Thus, by reading the FAMID + DIEID bits (even if they are not called DIEID by the reference manual), we can safely and accurately determine these parameters.

After this very long discussion, @corecode: If I abort when DIEID is zeros, then I will abort with the K20_50 (i.e. the official mchck chip), since the reference manual for that chip defines these bits as being zero.

Instead I propose the following code

    case @sim.SDID.FAMID + (@sim.SDID.DIEID<<3)
    when 1 # K20_50
        @sector_size = 1024
        @sector_blocks = 1
        @phrase_size = 4
    when 9 # K20_72
        @sector_size = 2048
        @sector_blocks = 2
        @phrase_size = 8
    when 33 # K22_50
        @sector_size = 2048
        @sector_blocks = 1
        @phrase_size = 8
    else
        raise RuntimeError, "unknown family-id and die-id combination"
    end

Support for additional relatives can be added later as needed. These cases already cover the official mchck (K20_50), the chip I am using (K22_50) and the chip @kfoltman is using (K20_72).

Thoughts?

corecode commented 10 years ago

Very good work! I suggest using a constant hash in the class:

FlashConfig = { 0b00000 => { :sector_size => 1024, :sector_blocks => 1, :phrase_size => 4 }, ...

On 05/21/2014 05:20 PM, Alex Cornejo wrote:

Hi all, I think I figured out how the K2X family works.

They subdivide this family into what I wall call |relatives| (i just made up that term). The |relatives| available in the K2X family are:

K20_50, K21_50, K22_50, K20_72, K20_100, K20_120, K21_120, K22_100, K22_120, K24_120

These subdivisions correspond to what they have on their website at http://www.freescale.com/webapp/sps/site/taxonomy.jsp?nodeId=01624698C9DE2DDDA7

All chips within one of these |relative| category share the same reference manual.

To identify which |relative| a chip belongs to, we can read bits 11-7 of the SIM_SDID register.

If you read the reference manuals of each of these |relatives| you will observe, each of them defines different values for these bits. What is confusing is that some of them call these bits "reserved" and others call them DIEID.

Example (from their respective reference manuals)

K20_50 relatives call these bits RESERVED and specify them as 00000 K20_72 relatives call these bits RESERVED and specify them as 00001 K20_120 relatives call these bits RESERVED and specify them as 00011 K21_120 relatives call these bits DIED and specify them as 00110 K22_50 relatives call these bits DIED and specify them as 00100

Now, the beauty is that all chips within each of the relatives share the same sector_size, sector_blocks and phrase_size. Thus, by reading the FAMID + DIEID bits (even if they are not called DIEID by the reference manual), we can safely and accurately determine these parameters.

After this very long discussion, @corecode https://github.com/corecode: If I abort when DIEID is zeros, then I will abort with the K20_50 (i.e. the official mchck chip), since the reference manual for that chip defines these bits as being zero.

Instead I propose the following code

case @sim.SDID.FAMID + (@sim.SDID.DIEID<<3)
when 1 # K20_50
    @sector_size = 1024
    @sector_blocks = 1
    @phrase_size = 4
when 9 # K20_72
    @sector_size = 2048
    @sector_blocks = 2
    @phrase_size = 8
when 33 # K22_50
    @sector_size = 2048
    @sector_blocks = 1
    @phrase_size = 8
else
    raise RuntimeError, "unknown family-id and die-id combination"
end

Support for additional |relatives| can be added later as needed. These cases already cover the official mchck (K20_50), the chip I am using (K22_50) and the chip @kfoltman https://github.com/kfoltman is using (K20_72).

Thoughts?

— Reply to this email directly or view it on GitHub https://github.com/mchck/programmer/pull/2#issuecomment-43769241.

acornejo commented 10 years ago

Updated the pull request to use a constant hash to store the supported flash configurations.