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.

F28M35H52C: RAM ECC selftest not triggering single bit error ISR

Part Number: F28M35H52C


Hi,

   I am writing test cases for various ECC related errors on RAM. To start with, I am using RAML1. I could see that all the single bits are corrected as soon as the test mode is turned off. But I cannot see the error address or counter increment on RAMErrRegs. Also, Am I expected to receive a single bit error interrupt? If so, Can you tell me if I am missing any important initialization steps?

I found a note on the TRM saying "During debug accesses (RD/WR) correctable as well as uncorrectable errors are masked." Is this the reason why I cannot see any register updates during a single bit error correction?

Initialization:

    .....
    InitPieVectTable();

    EALLOW;
    //PieVectTable.TINT0 = &cpu_timer0_isr;
    PieVectTable.CFLSINGERR = &singlebitISR;
    PieVectTable.NMI = &uncorrectableNMIErrorISR;
    PieVectTable.CRAMSINGERR = &ramSingleBitError;
    PieVectTable.ILLEGAL = &illegalISR;
    EDIS;

    EALLOW;
    NmiIntruptRegs.NMIFLGCLR.all = 0xFFFF;
    NmiIntruptRegs.NMICFG.bit.NMIEN = 1;
    EDIS;


    // Enable single bit error in the PIE: Group 12 interrupt 2
//  PieCtrlRegs.PIEIER12.bit.INTx2 = 1;
    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

    //Example_CallFlashAPI();
    RAM_ECCSelftest();

==========================================================================

#ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
        #pragma CODE_SECTION(RAM_ECCSelftest, ".TI.ramfunc");
        #pragma CODE_SECTION(ramSingleBitError, ".TI.ramfunc");
        #pragma CODE_SECTION(illegalISR, ".TI.ramfunc");
    #else
        #pragma CODE_SECTION(RAM_ECCSelftest, "ramfuncs");
        #pragma CODE_SECTION(ramSingleBitError, "ramfuncs");
        #pragma CODE_SECTION(illegalISR, "ramfunc");
    #endif
#endif

#pragma DATA_SECTION(gRAMTest1L1, "RAMTestL1File");
#pragma DATA_SECTION(gRAMTest2L1, "RAMTestL1File");
volatile uint32_t gRAMTest1L1;
volatile uint32_t gRAMTest2L1;

uint16_t ramSingleBitErrorISRTaken;

void RAM_ECCSelftest(void)
{
    //enable Ram ECC
    EALLOW;
    RAMErrRegs.CCETRES = 4; // Threshold of error
    RAMErrRegs.CCEIE.bit.C28CEIE = 1;  // Correctable error interrupt is generated when the CCEFLG flag is set.
    EDIS;

    EALLOW;
    //Initialize RAM for self-test by writing all data and ECC/parity bits as 0.
    RAMRegs.CLxRTESTINIT1.bit.RAMINIT_L1 = 1;
    //poll for the RAMINITDONE bit for that RAM block in the RINITDONE register to be set
    while(!RAMRegs.CLxRINITDONE.bit.RAMINITDONE_L1);
    EDIS;


    // ECC error counter should be 0
    if(RAMErrRegs.CCECNTR){
        return; //ECC_RAM_ERRCNTR_FAILURE;
    }

    // ECC error flag should be cleared.
    if(RAMErrRegs.CCEFLG.bit.C28CEFLAG){
        return; //ECC_RAM_CEFLAG_FAILURE;
    }

    // Enable RAM Test mode as mentione in section 5.1.1.8
    EALLOW;
    RAMRegs.CLxRTESTINIT1.bit.ECCPARTEST_L1 = 1;
    EDIS;

    // flip one bit to create correctable errors.
    gRAMTest1L1 ^= 0x1;
    gRAMTest2L1 ^= 0x1;

    //Now, turn off the test mode for the RAM Control Module to capture the error
    EALLOW;
    RAMRegs.CLxRTESTINIT1.bit.ECCPARTEST_L1 = 0;
    EDIS;

    uint32_t errorRegister = RAMErrRegs.CCPUCREADDR;
    uint32_t errorCount = RAMErrRegs.CCECNTR;
    while(!ramSingleBitErrorISRTaken);

    //Clear error register
    RAMErrRegs.CCECLR.bit.C28CECLR = 1;
}

__interrupt void ramSingleBitError (void)
{
    EALLOW;
    // Acknowledge this interrupt to receive more interrupts from group 12
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP12;
    EDIS;
    ramSingleBitErrorISRTaken++;
}

  • Hi Anoja,

    You have put the threshold to 4 (RAMErrRegs.CCETRES = 4; // Threshold of error) but generating only two error. Also I don't see you reading back the location, for which you have generated the error, in your code. So how you know that these locations are corrected ? If you are reading them via CCS memory watch window then that is not correct. You need to read those location in your code.

    Regards,

    Vivek Singh

  • Hi Vivek,

       Thank you for the response. It worked!

    I have another question at the moment. Can we do a RAM test without initializing the RAM section before the test? I have the RAM initialized when the application is setup. But the test for RAM ECC is done later in the code and I do not want to erase the content of RAML0. 

    I commented the RAM initialize and run the test. This is what I observed. During the time between test mode ON and OFF multiple locations change its value. Hence the error occurred is uncorrectable error always. Is it possible to just flip one bit and produce a single bit error without initialization?

  • Hi,

    I have another question at the moment. Can we do a RAM test without initializing the RAM section before the test? I have the RAM initialized when the application is setup. But the test for RAM ECC is done later in the code and I do not want to erase the content of RAML0. 

    Yes, you don't have to RAM INIT again. It need to be done once after power-up.

    [quote] I commented the RAM initialize and run the test. This is what I observed. During the time between test mode ON and OFF multiple locations change its value. Hence the error occurred is uncorrectable error always. Is it possible to just flip one bit and produce a single bit error without initialization? [quote]

    I did not understand this query. After test mode is on, it is user code which is flipping the bits so why would multiple locations change the value unless done by SW code ? I suspect there is some issue with the code which is flipping the bits. It has to be read modify write and make sure one bit get inverted.

    Regards,

    Vivek SIngh

  • Hi,

    Please let me know if you have any further query on this issue. If issue is resolved, please mark it resolved.

    Regards,

    Vivek Singh