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.

F28M36P63C2: Problem with flash ECC self-test interrupt

Part Number: F28M36P63C2

Hi,

I am working on implementing a ECC self-test routine for my concerto device. I followed the instructions detailed in the data sheet but I have a problem when entering the interrupt "single flash error". In step-by-step debug, the program never enter the ISR even with PIEFR12 being correctly set to 2 when the ecc test mode is enabled. The code execution stays stuck in unconditional loop. Please see code attached and advise.

#pragma DATA_SECTION(gFlashAECCTest, "FlashAECCTestFile");
uint32_t gFlashAECCTest;

#pragma DATA_SECTION(gFlashBECCTest, "FlashBECCTestFile");
uint32_t gFlashBECCTest;

systemControlError_t testFlashECCLogic(const uint32_t * address, const eccFlashTestType_t testType){
    char ecc;

    /* guidelines detailed in section 5.3.10.3 */
    EALLOW;
    ecc = Fapi_calculateEcc((uint32_t)(address) << 1, (uint64) 0x0000000000000000);
    FlashEccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 1; /* cannot be 0 - see device errata */
    FlashEccRegs.FADDR_TEST.bit.ADDR = (testType == TEST_ADDRESS_SINGLE_BIT) ? (uint32_t)(address) ^ 0x1 : (uint32_t)(address);
    FlashEccRegs.FDATAH_TEST = (testType == TEST_DATAH_SINGLE_BIT) ? 0x00000001 : 0x00000000;
    FlashEccRegs.FDATAL_TEST = (testType == TEST_DATAL_SINGLE_BIT) ? 0x00000001 : 0x00000000;
    FlashEccRegs.FECC_TEST.bit.ECC = (testType == TEST_ECC_SINGLE_BIT) ? ecc ^ 0x1 : ecc;
    FlashEccRegs.FECC_CTRL.bit.ECC_SELECT = (testType == TEST_DATAL_SINGLE_BIT) ? 0 : 1;
    FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 1;
    EDIS;

    asm("  NOP");

    EALLOW;
    FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 0;
    FlashEccRegs.ERR_CNT.bit.ERR_CNT = 0;
    EDIS;

    return SYS_CTL_NO_ERROR;
}

systemControlError_t testFlashBank(const uint32_t * address){
    systemControlError_t ret;

    if((ret = testFlashECCLogic(address, TEST_ADDRESS_SINGLE_BIT)) < 0) return ret;
    if((ret = testFlashECCLogic(address, TEST_DATAL_SINGLE_BIT)) < 0) return ret;
    if((ret = testFlashECCLogic(address, TEST_DATAH_SINGLE_BIT)) < 0) return ret;
    if((ret = testFlashECCLogic(address, TEST_ECC_SINGLE_BIT)) < 0) return ret;

    return SYS_CTL_NO_ERROR;
}

systemControlError_t flashSelfTest(void){
    systemControlError_t ret;

    enableFlashECC();
    if((ret = testFlashBank(&gFlashAECCTest)) < 0) return ret;
    if((ret = testFlashBank(&gFlashBECCTest)) < 0) return ret;

    return SYS_CTL_NO_ERROR;
}

systemControlError_t initializeECC(void){
    systemControlError_t err;

    /* Direct interrupt signals to ISR */
    EALLOW;
    PieVectTable.CFLSINGERR = &flashSingleError;
    PieVectTable.CRAMSINGERR = &ramSingleError;
    EDIS;

    // Enable the PIE
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;

    PieCtrlRegs.PIEIER12.bit.INTx2 = 1;    // Enable PIE Group 12 INT2 (flash single error)
    PieCtrlRegs.PIEIER12.bit.INTx4 = 1;    // Enable PIE Group 12 INT4 (ram single error)

    PieCtrlRegs.PIEACK.all = M_INT12 ; // Enable nesting in the PIE
    asm(" NOP"); // Wait for PIEACK to exit the pipeline Ref. Usage note errata sheet SPRZ272H

    IER |= M_INT12;

    // Enable global Interrupts and higher priority real-time debug events:
    EINT;   // Enable Global interrupt INTM
    ERTM;    // Enable Global realtime interrupt DBGM

    // First we verify that the ECC modules "SECDED" work properly
    // We put the RAM in test mode and inject some error...
   // if((err = RAMECCSelfTest()) < 0){
   //     DINT;   // Disable Global interrupt INTM
   //     DRTM;    // Disable Global realtime interrupt DBGM
   //     return err;
   // }

    if((err = flashSelfTest()) < 0){
        DINT;   // Disable Global interrupt INTM
        DRTM;    // Disable Global realtime interrupt DBGM
        return err;
    }

    DINT;   // Disable Global interrupt INTM
    DRTM;    // Disable Global realtime interrupt DBGM

    return SYS_CTL_NO_ERROR;
}

interrupt void flashSingleError(void){
    EALLOW;
    gFlashECCSingleErrorAddress = FlashEccRegs.SINGLE_ERR_ADDR;
    gFlashECCErrorStatus = FlashEccRegs.ERR_STATUS.all;
    gFlashECCErrorPositionReg = FlashEccRegs.ERR_POS.all;
    gFlashCorrectedErrorCounter++;
    FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 0;
    EDIS;
}

My cmd file:

   FlashAECCTestFile                    : > FLASHA,                    PAGE = 0,             ALIGN(4)
   FlashBECCTestFile                    : > FLASHB,                    PAGE = 0,             ALIGN(4)

  • Cedric,

    I'm writing to let you know that a C2000 team member has been assigned to your post and should be answering shortly.

    Sean
  • Cedric,

    Are you executing this code from RAM or Flash?

    What is the unconditional loop where your code is stuck?  Can you attach a snapshot?

    Thanks and regards,

    Vamsi

  • Cedric,

    Few things I noticed in your code:

    1. The value of ECC_SELECT should be assigned based on the address and not the data.  

        If the address belongs to the lower 64-bits of a 128-bit aligned memory location, then ECC_SELECT should be 0.  

        If the address belongs to the upper 64-bits of a 128-bit aligned memory location, then ECC_SELECT should be 1.

        For example:

        If the address is 0x100000, ECC_SELECT should be 0.

        If the address is 0x100004, ECC_SELECT should be 1.

    2.  FDATAH_TEST and FDATAL_TEST registers together provide the 64-bit data to the ECC logic for a given address.

        For example, if the address is 0x100000,

        FDATAL_TEST should be initialized with data of addresses 0x100000 and 0x100001 (in 32-bit format)

        FDATAH_TEST should be initialized with data of addresses 0x100002 and 0x100003.

    3. When you do a step-by-step debug, you may not enter the ISR immediately after enabling the ECC test mode.  It will take few cycles to enter in to the ISR.  If you don't wait for ISR and instead proceed to next round of ECC test, the ECC registers might get updated with the new error details.  Hence, instead of falling in to the next round of ECC test, wait in a loop for a variable to get updated in the ISR after you enable the ECC test mode.  Clear the ECC_TEST_EN bit and the ERR_CNT in the ISR. See below for an example.  

      // Select lower 64bits for ECC evaluation and enable ECC test mode
      //
      FlashEccRegs.FECC_CTRL.bit.ECC_SELECT = 0;
      FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 1;
    
      // Wait until Single bit interrupt ISR is serviced
      //
      while(SingleErrIntrptISRTaken != 1) {};
      SingleErrIntrptISRTaken = 0;

    And the ISR can be:

    interrupt void Flash_SingleError_ISR(void)
    {
    
        EALLOW;
        FlashSingleErrorISR_count++;
    
        FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 0;
        FlashEccRegs.ERR_STATUS_CLR.bit.FAIL0CLR = 1;
        FlashEccRegs.ERR_STATUS_CLR.bit.FAIL1CLR = 1;
        FlashEccRegs.ERR_INTCLR.bit.SINGLE_ERR_INTCLR = 1;
        FlashEccRegs.ERR_CNT.bit.ERR_CNT = 0;
    
        SingleErrIntrptISRTaken = 1;
    
        PieCtrlRegs.PIEACK.all |= 0x800;  // Issue PIE ACK
    
    }

    Thanks and regards,

    Vamsi

     

     

  • Hi Vamsi,

    Thanks for the detailed answer. My code is running from Flash. Let me implement your recommendations and I willl get back in touch with you for follow up.
  • Hi Vamsi,

    I made some modifications to the functions, created an illegal ISR  function. I enter the illegal ISR function couple clock cycle after     FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 1;

    Here is the updated function.

    systemControlError_t testFlashECCLogic(const uint32_t * address, const eccFlashTestType_t testType){
        char ecc;
        uint64 testPattern = 0;
        gFlashSingleErrorISRTaken = FALSE;

        /* guidelines detailed in section 5.3.10.3 */
        EALLOW;
        ecc = Fapi_calculateEcc((uint32_t)(address) << 1, testPattern);
        FlashEccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 1; /* cannot be 0 - see device errata */
        FlashEccRegs.FADDR_TEST.bit.ADDR = (testType == TEST_ADDRESS_SINGLE_BIT) ? (uint32_t)(address) ^ 0x1 : (uint32_t)(address); // Corrupt address by toggling one bit
        FlashEccRegs.FDATAH_TEST = (testPattern >> 32 & 0xFFFFFFFF) ^ (testType == TEST_DATAH_SINGLE_BIT) ? 0x00000001 : 0x00000000; // Corrupt data by toggling one bit
        FlashEccRegs.FDATAL_TEST = (testPattern & 0xFFFFFFFF) ^ (testType == TEST_DATAL_SINGLE_BIT) ? 0x00000001 : 0x00000000; // Corrupt data by toggling one bit
        FlashEccRegs.FECC_TEST.bit.ECC = (testType == TEST_ECC_SINGLE_BIT) ? ecc ^ 0x1 : ecc; // Corrupt ECC by toggling one bit
        // Flash memory is 128-bit aligned. If the address passed is in the 64 MSB then ECC_SELECT must be set to 1, otherwise it is set 0.
        FlashEccRegs.FECC_CTRL.bit.ECC_SELECT = ((uint32_t)(address) & 0x4) ? 1 : 0;
        FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 1;
        EDIS;

        while(!gFlashSingleErrorISRTaken);

        return SYS_CTL_NO_ERROR;
    }

  • According to the register, it generates an uncorrectable error which generates a NMI as expected. My question is then, why is it so...
  • I am adding a new screenshot to represent the error I get when I challenge DATAL (TEST_DATAL_SINGLE_BIT). The screenshots above was the result of  an address failure (TEST_ADDRESS_SINGLE_BIT). Right after I step FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 1 .

  • Cedric,

    As mentioned in section 5.3.10.3 SECDED Logic Correctness Check of TRM, ECC test mode should be used with code executing from RAM and not from flash.  ECC test mode registers (FDATAH_TEST, FDATAL_TEST, FECC_TEST) are multiplexed with data from the flash. Hence, the CPU should not read/fetch from flash when ECC test mode is enabled.  

    Any code that you want to execute when you enable this mode has to be mapped to .TI.ramfunc section.  

    Thanks and regards,

    Vamsi 

  • I moved the ISRs and functions running the test to RAM but the same problem persists. I don't have any ISR firing up even if PIEIEFR12 is set to 0x2.

    From output file:

    flashSingleErrorRamFunc
    *          0    00139ec1    0000003a     RUN ADDR = 00008cb2
                      00139ec1    0000003a     libSystemControlC28x_F28M36x.lib : libSystemControlC28x.obj (flashSingleErrorRamFunc:retain)

    ramSingleErrorRamFunc
    *          0    00139efb    0000001f     RUN ADDR = 00008cec
                      00139efb    0000001f     libSystemControlC28x_F28M36x.lib : libSystemControlC28x.obj (ramSingleErrorRamFunc:retain)

    illegalISRRamFunc
    *          0    00139f1a    00000011     RUN ADDR = 00008d0b
                      00139f1a    00000011     libSystemControlC28x_F28M36x.lib : libSystemControlC28x.obj (illegalISRRamFunc:retain)

  • Cedric,

    Can you attach your latest code along with the changes in linker?

    Thanks and regards,
    Vamsi
  • Hi Vamsi,

    I figured it out. The interrupt problem was because of my RAM self-test which was clearing the RAM content after I copied the flash ISR routine to flash. Everything works as expected now. Thanks.
  • Hi Vamsi,


    Now that my interrupts are working properly but I don't understand the results of some self-test. I am using the following routine to self test the Flash ECC. For each flash bank I sequentially test for single bit address error, data high single bit error, data low single bit error and ecc single bit error. Here is the results I get, I have highlighted in red the results I think are suspicious:

    • Address 0x0013E5C4 (FLASHA):
      • TEST_ADDRESS_SINGLE_BIT : single error flash ISR generated
      • TEST_DATAL_SINGLE_BIT: single error flash ISR generated
      • TEST_DATAH_SINGLE_BIT: single error flash ISR generated
      • TEST_ECC_SINGLE_BIT: uncorrectable error ISR generated (NMI)
    • Address 0x0013C000 (FLASHB):
      • TEST_ADDRESS_SINGLE_BIT : single error flash ISR generated
      • TEST_DATAL_SINGLE_BIT: single error flash ISR generated
      • TEST_DATAH_SINGLE_BIT: uncorrectable error ISR generated (NMI)
      • TEST_ECC_SINGLE_BIT: uncorrectable error ISR generated (NMI)
    • Address 0x0013A000 (FLASHC):
      • TEST_ADDRESS_SINGLE_BIT : single error flash ISR generated
      • TEST_DATAL_SINGLE_BIT: uncorrectable error ISR generated (NMI)
      • TEST_DATAH_SINGLE_BIT: uncorrectable error ISR generated (NMI)
      • TEST_ECC_SINGLE_BIT: uncorrectable error ISR generated (NMI)
    • Address 0x00139F8C (FLASHD):
      • TEST_ADDRESS_SINGLE_BIT: uncorrectable error ISR generated (NMI)
      • TEST_DATAL_SINGLE_BIT: uncorrectable error ISR generated (NMI)
      • TEST_DATAH_SINGLE_BIT: uncorrectable error ISR generated (NMI)
      • TEST_ECC_SINGLE_BIT: uncorrectable error ISR generated (NMI)
    • Address 0x00133180 (FLASHE):
      • TEST_ADDRESS_SINGLE_BIT: uncorrectable error ISR generated (NMI)
      • TEST_DATAL_SINGLE_BIT: single error flash ISR generated
      • TEST_DATAH_SINGLE_BIT: single error flash ISR generated
      • TEST_ECC_SINGLE_BIT: uncorrectable error ISR generated (NMI)
    • Address 0x00128000 (FLASHF):
      • TEST_ADDRESS_SINGLE_BIT: single error flash ISR generated
      • TEST_DATAL_SINGLE_BIT: single error flash ISR generated
      • TEST_DATAH_SINGLE_BIT: uncorrectable error ISR generated (NMI)
      • TEST_ECC_SINGLE_BIT: uncorrectable error ISR generated (NMI)


    and so on for the other sectors...

    Here the code:

    systemControlError_t testFlashECCLogic(const uint32_t * address, const eccFlashTestType_t testType){
        char ecc;
        uint64 testPattern = 0;
        gFlashSingleErrorISRTaken = FALSE;
        gFlashUncorrectableErrorISRTaken = FALSE;

        /* guidelines detailed in section 5.3.10.3 */
        EALLOW;
        ecc = Fapi_calculateEcc((uint32_t)(address) << 1, testPattern);
        FlashEccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 1; /* cannot be 0 - see device errata */
        FlashEccRegs.FADDR_TEST.bit.ADDR = (testType == TEST_ADDRESS_SINGLE_BIT) ? (uint32_t)(address) ^ 0x1 : (uint32_t)(address); // Corrupt address by toggling one bit
        FlashEccRegs.FDATAH_TEST = (testPattern >> 32 & 0xFFFFFFFF) ^ (testType == TEST_DATAH_SINGLE_BIT) ? 0x00000001 : 0x00000000; // Corrupt data by toggling one bit
        FlashEccRegs.FDATAL_TEST = (testPattern & 0xFFFFFFFF) ^ (testType == TEST_DATAL_SINGLE_BIT) ? 0x00000001 : 0x00000000; // Corrupt data by toggling one bit
        FlashEccRegs.FECC_TEST.bit.ECC = (testType == TEST_ECC_SINGLE_BIT) ? ecc ^ 0x1 : ecc; // Corrupt ECC by toggling one bit

        // Select lower 64bits for ECC evaluation and enable ECC test mode
        FlashEccRegs.FECC_CTRL.bit.ECC_SELECT = 0;
        FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 1; //Enable Flash test mode
        EDIS;

        while(!gFlashSingleErrorISRTaken && !gFlashUncorrectableErrorISRTaken);

        return SYS_CTL_NO_ERROR;
    }

    systemControlError_t testFlashBank(const uint32_t * address){
        systemControlError_t ret;

        if((ret = testFlashECCLogic(address, TEST_ADDRESS_SINGLE_BIT)) < 0) return ret;
        if((ret = testFlashECCLogic(address, TEST_DATAL_SINGLE_BIT)) < 0) return ret;
        if((ret = testFlashECCLogic(address, TEST_DATAH_SINGLE_BIT)) < 0) return ret;
        if((ret = testFlashECCLogic(address, TEST_ECC_SINGLE_BIT)) < 0) return ret;

        return SYS_CTL_NO_ERROR;
    }

    systemControlError_t flashSelfTest(void){
        systemControlError_t ret;

        memcpy(&flashSingleErrorRamFuncRunStart, &flashSingleErrorRamFuncLoadStart, (size_t)&flashSingleErrorRamFuncLoadSize);
        memcpy(&testFlashBankRamFuncRunStart, &testFlashBankRamFuncLoadStart, (size_t)&testFlashBankRamFuncLoadSize);
        memcpy(&testFlashECCLogicRamFuncRunStart, &testFlashECCLogicRamFuncLoadStart, (size_t)&testFlashECCLogicRamFuncLoadSize);
        memcpy(&testMemoryUncorrectableErrorRamFuncRunStart, &testMemoryUncorrectableErrorRamFuncLoadStart, (size_t) &testMemoryUncorrectableErrorRamFuncLoadSize);

        /* Direct interrupt signals to ISR */
        EALLOW;
        PieVectTable.CFLSINGERR = &flashSingleError;
        PieVectTable.NMI = &testMemoryUncorrectableError;
        EDIS;

        PieCtrlRegs.PIEIER12.bit.INTx2 = 1;    // Enable PIE Group 12 INT2 (flash single error)

        PieCtrlRegs.PIEACK.all = M_INT12 ; // Enable nesting in the PIE
        asm(" NOP"); // Wait for PIEACK to exit the pipeline Ref. Usage note errata sheet SPRZ272H

        IER |= M_INT12;

        // Enable global Interrupts and higher priority real-time debug events:
        EINT;   // Enable Global interrupt INTM
        ERTM;    // Enable Global real-time interrupt DBGM

        enableFlashECC();
        if((ret = testFlashBank((uint32_t *)&gFlashAECCTest)) < 0){
            DINT;   // Disable Global interrupt INTM
            DRTM;    // Disable Global real-time interrupt DBGM
            return ret;
        }

        if((ret = testFlashBank((uint32_t *)&gFlashBECCTest)) < 0){
            DINT;   // Disable Global interrupt INTM
            DRTM;    // Disable Global real-time interrupt DBGM
            return ret;
        }

        if((ret = testFlashBank((uint32_t *)&gFlashCECCTest)) < 0){
            DINT;   // Disable Global interrupt INTM
            DRTM;    // Disable Global real-time interrupt DBGM
            return ret;
        }

    [...]

    }

    // NMI ISR rerouted for test purpose

    interrupt void testMemoryUncorrectableError(void){
        asm ("      ESTOP0");
        EALLOW;
        gFlashECCErrorStatus = FlashEccRegs.ERR_STATUS.all;
        gFlashECCErrorPositionReg = FlashEccRegs.ERR_POS.all;
        FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 0;
        FlashEccRegs.ERR_STATUS_CLR.bit.FAIL0CLR = 1;
        FlashEccRegs.ERR_STATUS_CLR.bit.FAIL1CLR = 1;
        FlashEccRegs.ERR_STATUS_CLR.bit.UNCERRCLR = 1;
        FlashEccRegs.ERR_INTCLR.bit.UNC_ERR_INTCLR = 1;
        FlashEccRegs.ERR_CNT.bit.ERR_CNT = 0;
        NmiIntruptRegs.NMIFLGCLR.bit.C28FLUNCERR = 1;
        NmiIntruptRegs.NMIFLGCLR.bit.NMIINT = 1;
        EDIS;

        gFlashUncorrectableErrorISRTaken = TRUE;
    }

    interrupt void flashSingleError(void){
        EALLOW;
        gFlashCorrectedErrorCounter++;

        gFlashECCSingleErrorAddress = FlashEccRegs.SINGLE_ERR_ADDR;
        gFlashECCErrorStatus = FlashEccRegs.ERR_STATUS.all;
        gFlashECCErrorPositionReg = FlashEccRegs.ERR_POS.all;
        FlashEccRegs.FECC_CTRL.bit.ECC_TEST_EN = 0;
        FlashEccRegs.ERR_STATUS_CLR.bit.FAIL0CLR = 1;
        FlashEccRegs.ERR_STATUS_CLR.bit.FAIL1CLR = 1;
        FlashEccRegs.ERR_INTCLR.bit.SINGLE_ERR_INTCLR = 1;
        FlashEccRegs.ERR_CNT.bit.ERR_CNT = 0;

        gFlashSingleErrorISRTaken = TRUE;

        PieCtrlRegs.PIEACK.all |= M_INT12;
        EDIS;
    }

    Thanks for your help!

  • Cedric,

    I tried the ECC test mode earlier and it works fine.  

    I may not be able to check your code today.  Will get back to you in couple of days.

    Thanks and regards,
    Vamsi 

  • Cedric,

    Instead of the code, can you share the actual values written to the ECC test mode registers?
    That will be easy for me to analyze.

    Note: As mentioned in the TRM, an error in address always generates an uncorrectable error and not a single bit error.

    Thanks and regards,
    Vamsi
  • Do you want the watch view of FlashEccRegs for each case shown above?
  • Cedric,

    Please provide the values that you used for below registers in each case.
    FECC_CTRL
    FADDR_TEST
    FDATAH_TEST
    FDATAL_TEST
    FECC_TEST

    Thanks and regards,
    Vamsi
  • Hi Vamsi,

    I have attached the results of the 8 first results. If you cannot find a trend, I can add some more.

  • Cedric,

    One of our team members is trying to reproduce the results using your data. Will update you.

    Thanks and regards,
    Vamsi

  • Cedric,

    For each snap, can you provide the details like what is the correct value (address or data or ECC) and what is the error that you incorporated? Without this info, I can not align on the test register configuration for further debug.

    Thanks and regards,
    Vamsi

  • Hi Vamsi,

    The screenshots are showing sequential testing of:

    • FLASHA, error injected in address (good address is 0x3E414)
    • FLASHA, error injected in data LSB (correct data is 0)
    • FLASHA, error injected in data MSB (correct data is 0)
    • FLASHA, error injected in ECC (correct data is 0)
    • FLASHB, error injected in address (good address is 0x3C000)
    • FLASHB, error injected in data LSB (correct data is 0)
    • FLASHB, error injected in data MSB (correct data is 0)
    • FLASHB, error injected in ECC (correct data is 0)

  • Cedric,

    Considering the first test (FLASHA, error injected in address - good address is 0x3E414) that you mentioned in the list above, how is 0x3E414 a valid Flash address? Please check the description of FADDR_TEST register in TRM (section 5.4.4.13 ECC Test Address Register - FADDR_TEST). 

    Are you considering 0x13E414 as the correct address?  If yes, then you have to left shift the address by 1 position and write 0x27C828 in FADDR_TEST register.

    Also, you might have noticed in TRM that "ECC logic will be bypassed when the 64 data bits and the associated ECC bits fetched from the bank are either all ones or zeros."

    Hope this helps.

    Thanks and regards,
    Vamsi

      

  • Hi Vamsi,

    Thanks for the clarifications. It seems like I get the correct behavior if I call Fapi_remapEccAddress() from the flash API. Also, another weird thing is that ecc value returned by Fapi_calculateEcc is always 0. I have called the function Fapi_initializeAPI() prior to that and copy the whole Fapi to RAM.
  • So I think I have corrected my problem with Fapi_calculateEcc() returning 0. The symbol _CONCERTO needed to be defined , now it is returning a non-zero value. ( I had included F021.h instead of F021_Concerto_C28x.h).
    Also, yes the address I am passing belong to FLASHA and is 0x13E414. When I feed this address to Fapi_remapEccAddress(), I get 0xFFFFE as return value. I may misunderstand the purpose of this function.

  • Other question, do I have to use FADDR_TEST.all or FADDR_TEST.bit.ADDR ?
  • OK it works now, the problem was that I was writing in FADDR_TEST.bit.ADDR instead of .all ... and as you mentioned the test pattern need to be different than 0 and FFFF ....

    Thank you Vamsi and the team for your help!
  • Cedric,

    If you write to ADDR bit field alone, you need to discard the 3 least significant bits of the address as mentioned in the register description in the TRM.

    Glad that everything is working fine now.

    Thanks and regards,
    Vamsi
  • Yes, I facepalmed when I saw that in the datasheet! :)
    Thanks again for all the support! I hope this serves for others!