MCF54418, How to read NFC ECC bit correction count

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCF54418, How to read NFC ECC bit correction count

Jump to solution
704 Views
dwarkentin
Contributor II

Hi, I'm using an MCF54418 Coldfire processor connected to a Micron NAND FLASH device and am not able to get the NFC to provide the ECC bit error correction count.

 

How do I configure the NFC to output the ECC correction result?

 

This is my current code, which is based on the example code provided by NXP. It uses the ECCAD field in the NFC CFG register to tell the NFC that the ECC result should be written to the first byte of the spare area in NFC SRAM, or at least that’s how I understand it from the reference manual. I’ve also tried other locations in NFC SRAM for the ECC result, and none have worked so far. The snippets from the reference manual that specify how this is supposed to work are included below my code.

 

/**

* Transfer a page from the NAND FLASH device to NFC RAM.

*

* \param[in] page    the page number

*

* \return  the number of ECC corrected bit errors, an error count greater than or equal to 128 indicates

*          the page could not be fully corrected and the read failed

*/

uint32_t flash_nfc_transfer_nf_page_to_nfc_ram(uint32_t page)

{

    NFC_MemMapPtr nfc_ptr;

    uint32_t i;

    uint32_t block = flash_page_to_block(page);

    uint32_t page_offset = flash_page_offset_in_block(page);

    uint32_t bit_error_count = 0;

 

 

    /* Get the pointer to nfc registers structure */

    nfc_ptr = ( & ( ( VMCF5441_STRUCT_PTR ) _PSP_GET_IPSBAR( ) )->NFC );

 

 

    /* Clearing interrupts bits */

    nfc_ptr->ISR |= ( NFC_ISR_DONECLR_MASK | NFC_ISR_DONEEN_MASK | NFC_ISR_IDLECLR_MASK | NFC_ISR_IDLEEN_MASK );

 

 

    /* Clearing buf in use */

    //!!!for( i = 0; i < BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE; i ++ )

    for( i = 0; i < NFC_SRAM_BUFFER_LENGTH; i ++ )

    {

        NFC_SRAM_B0_REG( nfc_ptr, i )= 0x00; //0x5A;

    }

 

 

    /* setting ROW and COLUMN address */

    page_offset &= 0x3F;

    block &= 0x7FF;

    nfc_ptr->RAR = 0x11000000 + page_offset + ( block << 6 );

    nfc_ptr->CAR = 0x00000000;

 

 

    nfc_ptr->CMD1 = NFC_CMD1_BYTE2( NANDFLASH_CMD_PAGE_READ_CYCLE2 );

    nfc_ptr->CMD2 = NFC_CMD2_BYTE1( NANDFLASH_CMD_PAGE_READ_CYCLE1 ) | NFC_CMD2_CODE( 0x7EE0 ) | NFC_CMD2_BUFNO( 0 );

 

 

    /* configuring Sector size */

    nfc_ptr->SECSZ = BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE;

 

 

    /* 32bit ECC, 16bit data bus, 1 page cnt */

    nfc_ptr->CFG = NFC_CFG_ECCAD(0) | //NANDFLASH_SPARE_AREA_SIZE - 1) |

                   NFC_CFG_ECCSRAM_MASK |

                   NFC_CFG_ECCMODE( 7 ) |

                   NFC_CFG_IDCNT( 5 ) |

                   NFC_CFG_TIMEOUT( 6 ) |

                   NFC_CFG_BITWIDTH_MASK |

                   NFC_CFG_PAGECNT( 1 );

 

 

    /* Sending START */

    nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

 

 

    /* Polling for cmd done IRQ */

    while( ! ( nfc_ptr->ISR & NFC_ISR_IDLE_MASK ) )

    {

        //TODO limit this infinite loop

    }

   

    bit_error_count = NFC_SRAM_B0_REG( nfc_ptr, BSP_PHYSICAL_PAGE_SIZE ); //BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE - 1);

   

    return bit_error_count;

}

 

 

The two snippets below are from Section 22.4 of the reference manual and are the only places in the reference manual that I can find information about the ECC status. Not sure if the “auxiliary area” refers to the spare area of the page, but I believe these sections are telling me that when the read is complete, I should find the ECC status byte at a location ECCAD bytes from the start of the spare data. It isn’t there and I also have not been able to make it appear at the end of the spare area (ECCAD=63), or one byte past the spare area (ECCAD=64).

 

Snippet 1:

The error corrector can write ECC status to the spare area, since the read is pipelined. This means, while

the current page is transferred from flash to buffer, the previous page is ECC corrected, and the page before

that is transferred using DMA. Because of the pipelining, it is difficult to inform the CPU in the foreground

of ECC errors. To solve this, ECC status is written to the auxiliary area of the sector, and transferred to

memory. See Section 22.4.2, “Error Corrector Status” for more information. It’s up to the CPU to inspect

the ECC result in memory, and act appropriately.

 

Snippet 2:

The error corrector writes the status word to a byte location to the SRAM buffer, defined by

NFC_CFG[ECCAD]. It is selectable if the status is written or not with NFC_CFG[ECCSRAM]. If the

status is written to the SRAM buffer, it becomes effectively part of the flash data, and is processed like the

flash data. Most likely, the status byte is written to memory as part of the page header. Once in memory,

the ECC status is visible to the CPU, while CPU parses the rest of the flash header. No interrupt on error

or status is available because this increases the interrupt load on the CPU. (The interrupt would be

independent of the command done interrupt.) It is not possible to stop reading when ECC failed.

 

 

Thank-you

Labels (1)
0 Kudos
1 Solution
529 Views
dwarkentin
Contributor II

Thank-you Tom, was looking for example code and you pointed me right to it. vf610_nfc.c matches my processor.

From that driver I found out that ECCAD needs to be right shifted by 3. This was not described in the MCF54418 manual, but the same bit field is described in the K70 manual as ECCAD[11:3]. K70 is also supported by vf610_nfc.c. The status byte is then written to (ECCAD<<3)+7 bytes from the start of the NFC SRAM buffer. The ECC status word is a 64-bit value, of which only the least significant byte is actually written to SRAM, and the MCF54418 is a big endian platform, so that's where the status byte ends up.

The last fix that was required to get it all working was to reduce the size of my page transfer to 2k + 60 bytes which is the exact number of bytes including the ECC bytes. I was transfering 2k plus the full spare data length (2k + 64 bytes).

nfc_ptr->SECSZ = BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE;

changed to

nfc_ptr->SECSZ = BSP_PHYSICAL_PAGE_SIZE + 60;

The oversized transfer was overloading the ECC engine causing it to always reported 32 bit corrections and likely making it impossible for the engine to correct any actual flipped bits.

So, problem solved, but an interesting note ... I was trying to figure out how that bug got into my code and I traced it all the way back to MQX. This bug is straight from the MQX twrmcf54418 bsp code in the file mqx/source/bsp/twrmcf54418/bootstrap.c. Will be adding a forum post to ask for this to be fixed.

Sorry, I haven't measured the bandwidth because my application is not time critical. The boot image is the only thing in the NAND FLASH. I don't think it's better than 1MB/s though from a rough stop watch measurement. I'm not using DMA or pipelining, just a page request and then a memcpy transfer from NFC SRAM.

View solution in original post

0 Kudos
2 Replies
529 Views
TomE
Specialist II

Does the controller match any of the Linux NFC controllers here:

http://lxr.free-electrons.com/source/drivers/mtd/nand/

Some of them might help a bit.

> The error corrector can write ECC status to the spare area, since the read is pipelined.

> This means, while the current page is transferred from flash to buffer, the previous page

> is ECC corrected, and the page before that is transferred using DMA.

What kind of raw read data rate can you get from Flash on that chip and through that controller?

I'm using an i.MX53 and the Boot only manages 4MB/second. It reads one 2k sector, waits for it, then copies from the SRAM buffer to main memory. The latter is the bottleneck as the SRAM is terribly slow on the i.MX5x. I got it to 8MB/second by reading the SRAM 32 bits at a time instead of 16. The OS can manage about 13 MB/sec somehow.

Tom

0 Kudos
530 Views
dwarkentin
Contributor II

Thank-you Tom, was looking for example code and you pointed me right to it. vf610_nfc.c matches my processor.

From that driver I found out that ECCAD needs to be right shifted by 3. This was not described in the MCF54418 manual, but the same bit field is described in the K70 manual as ECCAD[11:3]. K70 is also supported by vf610_nfc.c. The status byte is then written to (ECCAD<<3)+7 bytes from the start of the NFC SRAM buffer. The ECC status word is a 64-bit value, of which only the least significant byte is actually written to SRAM, and the MCF54418 is a big endian platform, so that's where the status byte ends up.

The last fix that was required to get it all working was to reduce the size of my page transfer to 2k + 60 bytes which is the exact number of bytes including the ECC bytes. I was transfering 2k plus the full spare data length (2k + 64 bytes).

nfc_ptr->SECSZ = BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE;

changed to

nfc_ptr->SECSZ = BSP_PHYSICAL_PAGE_SIZE + 60;

The oversized transfer was overloading the ECC engine causing it to always reported 32 bit corrections and likely making it impossible for the engine to correct any actual flipped bits.

So, problem solved, but an interesting note ... I was trying to figure out how that bug got into my code and I traced it all the way back to MQX. This bug is straight from the MQX twrmcf54418 bsp code in the file mqx/source/bsp/twrmcf54418/bootstrap.c. Will be adding a forum post to ask for this to be fixed.

Sorry, I haven't measured the bandwidth because my application is not time critical. The boot image is the only thing in the NAND FLASH. I don't think it's better than 1MB/s though from a rough stop watch measurement. I'm not using DMA or pipelining, just a page request and then a memcpy transfer from NFC SRAM.

0 Kudos