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)
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_ECCMODE( 7 ) |
NFC_CFG_IDCNT( 5 ) |
NFC_CFG_TIMEOUT( 6 ) |
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);
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).
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.
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.