This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM1808: coding for NAND-ECC calculation by 518-bytes

Guru 10235 points
Part Number: AM1808

Hello, TI Experts,

 

Our customer sent us an additional question about NAND-ECC function of AM1808 from E2E as below. 

https://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/588247 

 

We can get the sample code which is guided by this E2E thread as below.

Thank you very much.

http://processors.wiki.ti.com/index.php/Serial_Boot_and_Flash_Loading_Utility_for_OMAP-L138

 

We would like to calculate ECC by 518-bytes.

 - But from the sample code, ECC seems to be calculated by 512-bytes.

 - And we also found the explanation such as "The EMIFA supports 4-bit ECC calculation up to 518 bytes" as below.

    19.2.5.6.6.2 4-Bit ECC: http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf

 

Question:

  How do we realize and write the code for ECC calculation by 518-bytes?

  Is there any guide or document?

 

We would appreciate if you tell us the recommended way of coding for  ECC calculation by 518-bytes.

 

Best regards,

 

  • Hi,

    I'm looking into this. Feedback will be posted here.

    Best Regards,
    Yordan
  • Hi,

    Thank you very much for your kindness.
    I really appreciate your help.

    I am waiting for your feedback.

    Best regards,

  • Hi,

    You can also have a look at this thread:
    e2e.ti.com/.../2166281

    It discusses a similar question.

    Best Regards,
    Yordan
  • Hi,

    Thank you for your reply.

    Yes. We understand because of the E2E thread which you show is same as below as I said before.

    https://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/588247

    Please  tell us the recommended way of coding for  ECC calculation by 518-bytes.

    Best regards,

  • Matusan,

    I would like to point you to a Advisory 2.3.24 regarding NAND ECC handling in the BOOT ROM in the device errata. In this we had found that the boot loader handles only errors in 512 bytes and had implemented a work around  to handle complete 518 bytes.

    I would like to share this patch for reference to use to handle complete 518 bytes:

    nand_ecc_patch.c
    /************************************************************
    * Local Function Definitions                                *
    ************************************************************/
    
    #pragma CODE_SECTION(NAND_ECC_correct,".text:nand_ecc_patch")
    static uint32_t NAND_ECC_correct(void *unused, uint8_t *data, uint8_t *readECC)
    {
      volatile uint32_t temp, corrState, numE;
      int i;
      uint16_t addOffset, corrValue;
      uint16_t* syndrome10 = (uint16_t *)readECC;
    
      // Clear bit13 of NANDFCR
      temp = AEMIF->NANDERRADD1;
      
      // Load the syndrome10 (from 7 to 0) values
      for(i=8;i>0;i--)
      {
        AEMIF->NAND4BITECCLOAD = (syndrome10[i-1] & 0x000003FF);
      }
      
      // Read the EMIF status and version (dummy call) 
      temp = AEMIF->ERCSR;
      
      // Check if error is detected
      temp = (AEMIF->NAND4BITECC1 & 0x03FF03FF) | (AEMIF->NAND4BITECC2 & 0x03FF03FF) |
             (AEMIF->NAND4BITECC3 & 0x03FF03FF) | (AEMIF->NAND4BITECC4 & 0x03FF03FF);
      if(temp == 0)
      {
        return 0;
      }
    
      // Start calcuating the correction addresses and values
      AEMIF->NANDFCR |= (0x1U << 13);
    
      // Read the EMIF status and version (dummy call to allow previous write to complete) 
      temp = AEMIF->ERCSR;
      
      // Loop until timeout or the ECC calculations are complete (bit 11:10 == 00b)
      i = 1000;
      do
      {
        temp = (AEMIF->NANDFSR & 0x00000F00)>>10;
        i--;
      }
      while((i>0) && (temp != 0x0));
    
      // Read final correction state (should be 0x0, 0x1, 0x2, or 0x3)
      corrState = (AEMIF->NANDFSR & 0x00000F00) >> 8;
    
      if ((corrState == 1) || (corrState > 3))
      {
        temp = AEMIF->NANDERRVAL1;
        return 1;
      }
      else if (corrState == 0)
      {
        return 0;
      }
      else
      {
        // Error detected and address calculated
        // Number of errors corrected 17:16
        numE = (AEMIF->NANDFSR & 0x00030000) >> 16;
    
        switch( numE )
        {
          case 3:     // Four errors
            addOffset = 519 - ( (AEMIF->NANDERRADD2 & (0x03FF0000))>>16 );
            if (addOffset < 512)
            {
                // Error in the user data region can be corrected
                corrValue = (AEMIF->NANDERRVAL2 & (0x03FF0000))>>16;
                data[addOffset] ^= (uint8_t)corrValue;
            }
            // Fall through to case 2
          case 2:     // Three errors
            addOffset = 519 - (AEMIF->NANDERRADD2 & (0x000003FF));
            if (addOffset < 512)
            {
                // Error in the user data region can be corrected
                corrValue = AEMIF->NANDERRVAL2 & (0x000003FF);
                data[addOffset] ^= (uint8_t)corrValue;
            }
            // Fall through to case 1
          case 1:     // Two errors
            addOffset = 519 - ( (AEMIF->NANDERRADD1 & (0x03FF0000))>>16 );
            if (addOffset < 512)
            {
                // Error in the user data region can be corrected
                corrValue = (AEMIF->NANDERRVAL1 & (0x03FF0000))>>16;
                data[addOffset] ^= (uint8_t)corrValue;
            }
            // Fall through to case 0
          case 0:     // One error
            addOffset = 519 - (AEMIF->NANDERRADD1 & (0x000003FF));
            if (addOffset < 512)
            {
                // Error in the user data region can be corrected
                corrValue = AEMIF->NANDERRVAL1 & (0x3FF);
                data[addOffset] ^= (uint8_t)corrValue;
            }
            break;
        }
        return 0;
      }
    }
    
    
    
    /***********************************************************
    * End file                                                 *
    ***********************************************************/
    

    The fix is provided in the switch statement. Hope this helps.

    Regards,

    Rahul

  • Hi,

    Thank you very much for your kindness.
    I really appreciate your help.

    I'd like to confirm one thing.
    Advisory 2.3.24 in the device errata which you said is "Advisory 2.3.13 —Boot: ECC Data Error in Spare Area Causes NAND Boot Failure" of the errata below.
    www.ti.com/.../sprz313h.pdf

    Is this correct?

    Best regards,
  • Yes, I check the document link that you provided. I was referring to Advisory 2.3.13 Boot: ECC Data Error in Spare Area Causes NAND Boot Failure" of the errata.
  • Hi,

     

    Thank you very much for your kindness.

    I really appreciate your help.

     

    I will send the answer to the customer.

     

    Best regards

  • Hello,

     

    Thank you very much for your help.

    We can get more detail from our customer about this question.

     

    Our customer's NAND Read/Write procedure by 518-bytes is described in attached pdf.

     

    Questions:

     1) Is there any problem of this NAND Read/Write procedure?

     2) How do we correct the data of Fieldx-ECC in which some errors are detected?

     

    We would appreciate if you check the attached pdf and tell us the recommended NAND Read/Write procedure by 518-bytes.

     

    Best regards,

    ECC_procedure.pdf

  • The block diagram is incorrect the 2048 bytes page data usually divided in 512 bytes of equal blocks. The TRM mention that we can support upto 518 bytes for 4bit ECC correction so 512 bytes is within that capability. Also, NAND ECC layout on AM1808 is similar to that described here:

    processors.wiki.ti.com/.../DM365_Nand_ECC_layout

    For Correct process to read and write, you can refer to the Section 3.7 in EMIF16 user guide :
    www.ti.com/.../sprugz3a.pdf

    You can also point them to the software that I have provided in the other post that shows 4 bit ECC read/writ with NAND with 2K pages.

    Regards,
    Rahul

  • Hi,

     

    Thank you very much for your kindness.

    I really appreciate your help.

    I will send the answer to the customer.

    I'd like to confirm one thing. 

    > You can also point them to the software that I have provided in the other post that shows 4 bit ECC read/writ with NAND with 2K pages.

     

    We understand "the software" means "device_nand.c" of the E2E thread below.

       http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/p/588247/2171420#2171420

     

    Is this understanding correct?

     

    Best regards,

  • Hi,

    Thank you for your help.

    We have checked sprugz3a.pdf and device_nand.c from your advice.
    And we can find the statement as below for ECC-area error correction in device_nand.c.
    - if (addOffset > 511) return E_FAIL;

    Our understanding of this statement is as follows;
    - The error detecting address in redundant area (ECC area) is reported properly to NANDERRADDx register.
    - The error correction cannot be supported in the redundant area (ECC area).

    Is this understanding correct?

    Best regards,
  • Matusan,

    Check the explanation of the work around code in the Errata document. The workaround code that I shared
    if (addOffset > 511) return E_FAIL

    Ignores errors in ECC data (these errors do not need to be corrected) so that the boot/ read process can continue, correcting errors only in the user data (up to 4 bit errors total). On the NAND, ECC mechanism is implemented to protect user/page data if errors are detected in redundant area, we are current ignoring it.

    Regards,
    Rahul
  • Hello, Rahul

    Thank you for your detailed explanation.
    I really appreciate your help.

    I will send the answer to the customer.

    Best regards,

  • Hello, Rahul

    Thank you for your help.

    From your explanation, our customer understands "errors in ECC data do not need to be corrected".

    And they require to confirm their understanding as follows.
    - (addOffset > 511) means "error bits exists in redundant area (ECC area)".
    - Even if error bits exists in redundant area (ECC area),
    the number of errors in redundant area (ECC area) can be read from the errors field (ECC_ERRNUM) in NANDFSR register
    and the error address value in redundant area (ECC area) can be read from the NANDERRADD[2:1] register
    to calculate the value of "addOffset" properly.

    Is this understanding correct?

    Best regards,
  • Yes, that matches my understanding.
  • Hi,

     

    Thank you very much for your kindness.

    I really appreciate your help.

    I will send the answer to the customer.

     

    Best regards,