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++;
}