Not triggering SMU alarm0[6] through NMI in TC23xxx

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi,

I am trying to generate the correctable alarm0[6] in SMU (for example: CPU0 SRAM PCACHE/PSPR single-bit correctable). but it was not generating, the code snippet is below--

 

uint16_t endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword();
IfxScuWdt_clearSafetyEndinit(endinitSfty_pw);

    SMU_KEYS.U = (uint32_t)0x000000BC;
    SMU_CMD.U = (unsigned int)0x00000000U;
    SMU_AG0CF0.U &= ~(1 << (6 & 0xFF));
    SMU_AG0CF1.U &= ~(1 << (6 & 0xFF));
    SMU_AG0CF2.U &= ~(1 << (6 & 0xFF));

    SMU_AG0CF0.U |= ((5 >> 0) & 1) << (6 & 0xFF);
    SMU_AG0CF1.U |= ((5 >> 1) & 1) << (6 & 0xFF);
    SMU_AG0CF2.U |= ((5 >> 2) & 1) << (6 & 0xFF);

    SMU_KEYS.U = (uint32_t)0x0;
    IfxScuWdt_setSafetyEndinit(endinitSfty_pw);

    volatile Ifx_SRC_SRCR *src = (Ifx_SRC_SRCR *)&MODULE_SMU;
    IfxSrc_init(src, IfxSrc_Tos_cpu0, 5);
    IfxSrc_enable(src);

     SMU_CMD.U = 0x00000066U;
 
Please let me know where I am making mistake. Thanks!

Regards-

0 Likes
1 Solution
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

According to the 10.4.5.5 Alarm Debug Registers in the user manual the snapshot is taken when reset is executed by the SMU or transition to FAULT and there is nothing about NMI request which you configured by seting SMU_AG0CFx . Check flag SCU_TRAPSTAT.B.SMUT

View solution in original post

0 Likes
24 Replies
LaneYE
Level 3
Level 3
25 sign-ins 10 replies posted 5 replies posted

Hi, Shambhu.

Your code about ALM0[6] configuration parts looks right.Could you read status of the alarm status register(AG0) and check if the status of ALM0[6] is set.

Additional , i wonder to know how do you inject the fault of single-bit correctable.

Best regards,

Lane YE

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi LaneYE,

Thanks for your reply.

I have tried injecting error by --

void inject_memory_error(const uint32 mc_number, const uint32 range) {
  uint32 ResultLoopCount;

  Ifx_MC *Mc;

  /* Get pointer to memory controller SFRs of RAM under test: */
  Mc = (Ifx_MC *)((uint32)&MODULE_MC0 + ((uint32)SRAM_MC_ADDR_RANGE_SIZE * (uint32)mc_number));

  // Enable error tracking
  Mc->ECCS.U |= (uint16)((uint32)0x1u << (uint32)4u);

  //  Mc->RDBFL[0].U = 3; // Double bit error pattern
  Mc->RDBFL[0].U = 1;   // Double bit error pattern
  Mc->RDBFL[1].U = 0;   // Double bit error pattern
  Mc->RDBFL[2].U = 0;   // Double bit error pattern
  Mc->RDBFL[3].U = 0;   // Double bit error pattern
  Mc->RDBFL[4].U = 0;   // Double bit error pattern
  Mc->RDBFL[5].U = 0;   // Double bit error patterns
  Mc->RDBFL[6].U = 0;   // Double bit error pattern
  Mc->RDBFL[7].U = 0;   // Double bit error pattern
  Mc->RDBFL[8].U = 0;   // Double bit error pattern
  Mc->RDBFL[9].U = 0;   // Double bit error pattern
  Mc->RDBFL[10].U = 0;  // Double bit error pattern
  Mc->RDBFL[11].U = 0;  // Double bit error pattern
  Mc->RDBFL[12].U = 0;  // Double bit error pattern
  Mc->RDBFL[13].U = 0;  // Double bit error pattern
  Mc->RDBFL[14].U = 0;  // Double bit error pattern
  Mc->RDBFL[15].U = 0;  // Double bit error pattern
  Mc->RDBFL[16].U = 0;  // Double bit error pattern
  Mc->RDBFL[17].U = 0;  // Double bit error pattern

  Mc->RANGE.U = (uint16)(range & ((uint16)0x7fffu));

  /* Configure writing of single memory address: */
  Mc->CONFIG0.U =
      (uint16)(((uint32)SRAM_CONFIG0_NUMACCS_1 << (uint32)12u) | ((uint32)SRAM_CONFIG0_ACCSTYPE_WR << (uint32)0u));
  Mc->CONFIG1.U = 0U;

  /* Start write operation: */

  Mc->MCONTROL.U = (uint16)(((uint32)0x1u << (uint32)3u) | ((uint32)0x1u << (uint32)0u) |
                            ((uint32)MC_MCONTROL_USERED_MSK << (uint32)MC_MCONTROL_USERED));
  Mc->MCONTROL.U =
      (uint16)(((uint32)0x1u << (uint32)3u) | ((uint32)MC_MCONTROL_USERED_MSK << (uint32)MC_MCONTROL_USERED));
  /*wait for MBIST operation to complete*/
  /*ResultLoopCount is used as count here*/
  for (ResultLoopCount = 0U; ResultLoopCount < 50u; ResultLoopCount++) {
    __asm("nop");
  }
}

void inject_pspr_error(void) {
  uint16_t Timeout = 0x100u;  // Value taken from TestApp.
  uint16_t endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword();
  IfxScuWdt_clearSafetyEndinit(endinitSfty_pw);

  uint16_t passwd = IfxScuWdt_getCpuWatchdogPassword();
  IfxScuWdt_clearCpuEndinit(passwd);
  MTU_CLC.B.DISR = 0U;
  IfxScuWdt_setCpuEndinit(passwd);
  // Check timeout
  while ((MTU_CLC.B.DISS > 0U) && (Timeout > 0U)) {
    Timeout--;
  }

  MTU_MEMTEST0.B.CPU0PSEN = 1U;  // Enable MTU for PSPR0
  do {
    __asm("nop");
  } while ((MTU_MEMSTAT0.U & (1 << (MC_NUMBER_PSPR1 & 0x1F))) != 0U);
  inject_memory_error(MC_NUMBER_PSPR1, 0);
  MTU_MEMTEST0.B.CPU0PSEN = 0U;  // Disable MTU for PSPR0
  do {
    __asm("nop");
  } while ((MTU_MEMSTAT0.U & (1 << (MC_NUMBER_PSPR0 & 0x1F))) != 0U);
  IfxScuWdt_setSafetyEndinit(endinitSfty_pw);
}
0 Likes
LaneYE
Level 3
Level 3
25 sign-ins 10 replies posted 5 replies posted

Hi, Shambhu

After fault injection. Is there any error bits set.Please check ECCD.CERR,ECCD.UCERR,ECCD.MERR.

Additional , some MTU registers need to be configured to propagate CE/UCE/ME to alarm.

LaneYE_0-1659408356299.png

Hints: 13.3.5.1.7 Writing to a Single Memory Location

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi LaneYE,

Thanks for your suggestion!

I have configured according the figure that you had shared --

  Mc->ECCS.B.ECE = 1;
  Mc->ECCD.B.CERR = 0;
  Mc->ECCS.B.CENE = 1;
I didn't find out ALMSRCS.SBE in the manual.
 
 
One more thing, I have observed --- what I am writing below code for MC_CPU0_DSPR, is not written on the actual Mc location(means Mc->ECCS & Mc->RDBFL etc) that I have debugged and found out. I think this might be the root cause.
Please get me a suggestion to how to write successfully. 
 
uint16_t endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword();
  IfxScuWdt_clearSafetyEndinit(endinitSfty_pw);
  uint16_t passwd = IfxScuWdt_getCpuWatchdogPassword();
  IfxScuWdt_clearCpuEndinit(passwd);
  MTU_CLC.B.DISR = 0U;
  while (MTU_CLC.B.DISS);
  IfxScuWdt_setCpuEndinit(passwd);

  MTU_MEMTEST0.B.CPU0DSEN = 1U;  // Enable MTU for DSPR0
  do {
    __asm("nop");
  } while ((MTU_MEMSTAT0.U & (1 << (MC_NUMBER_DSPR0 & 0x1F))) != 0U);
 
Ifx_MC *Mc;
  Mc = (Ifx_MC *)((uint32)&MODULE_MC0 + ((uint32)100* (uint32)14));
  // Enable error tracking
  Mc->ECCS.U |= (uint16)((uint32)IFX_MC_ECCS_TRE_MSK << (uint32)IFX_MC_ECCS_TRE_OFF);
  Mc->ECCD.B.CERR = 0;
  Mc->ECCS.B.CENE = 1;
  Mc->RDBFL[0].U = SramEccTst_SingleBitErrPtrn[0];
  Mc->RDBFL[1].U = SramEccTst_SingleBitErrPtrn[1];
  Mc->RDBFL[2].U = SramEccTst_SingleBitErrPtrn[2];
 .......
 
 
Regards--
 
0 Likes
LaneYE
Level 3
Level 3
25 sign-ins 10 replies posted 5 replies posted

Hi, Shambhu,

>>The first QA, please search "MCi_ALMSRCS" register in page 13-40

LaneYE_0-1659443438502.png

>>The second QA, please reference Infineon-AURIX_TC39x-UserManual-v01_00-EN.pdf and finds SSH instance of CPU0DSPR

LaneYE_1-1659443669503.png

Best regards,

Lane YE

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi LaneYE,

Thanks for your suggestions!

but I am using TC23X processor not the TC39X. Please suggest me according to TC23X.

Regards-

0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

It should be like this:

Mc = (Ifx_MC *) ((uint32) &MODULE_MC0 + ((uint32) 0x100 * (uint32) 14));

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi Waldi,

Thanks for the suggestion.

Actually 100 was mistakenly written in place of 0x100. sorry for that. as I am already using  (uint32)&MODULE_MC1 - (uint32)&MODULE_MC0 which is 0x100.

 

Reset happens after the function inject_memory_error(MC_NUMBER_DSPR0, 0);

and when it comes to disable the MTU for DSPR0.
  MTU_MEMTEST0.B.CPU0DSEN = 0U;  // Disable MTU for DSPR0
  do {
    __asm("nop");
  } while ((MTU_MEMSTAT0.U & (1 << (MC_NUMBER_DSPR0 & 0x1F))) != 0U);
 
Please suggest!
Regards-
0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

Please take a look at the (9.6.1.3) MEMSTAT Implementation from the user manual. CPU0DSAIU is reserved. You probably have inifinite loop there. I think you can remove it completely. Please update your function inject_memory_error for further analysis.

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi Waldi,

Thanks for your precious suggestions. You are very right about the  MEMSTAT.

I have removed the loop after enabling/disabling the MTU_MEMTEST0.B.CPU0DSEN. still I got the reset.

Please suggest on this.

 

For reference I have sharing the code for inject_memory_error--

Ifx_MC *Mc;
  /* Get pointer to memory controller SFRs of RAM under test: */
  Mc = (Ifx_MC *)((uint32)&MODULE_MC0 + ((uint32)0x100* (uint32)14));
  // Enable error tracking
  Mc->ECCS.U |= (uint16)((uint32)IFX_MC_ECCS_TRE_MSK << (uint32)IFX_MC_ECCS_TRE_OFF);

  Mc->RDBFL[0].U = SramEccTst_SingleBitErrPtrn[0];
  Mc->RDBFL[1].U = SramEccTst_SingleBitErrPtrn[1];
  Mc->RDBFL[2].U = SramEccTst_SingleBitErrPtrn[2];
  Mc->RDBFL[3].U = SramEccTst_SingleBitErrPtrn[3];
  Mc->RDBFL[4].U = SramEccTst_SingleBitErrPtrn[4];
  Mc->RDBFL[5].U = SramEccTst_SingleBitErrPtrn[5];
  Mc->RDBFL[6].U = SramEccTst_SingleBitErrPtrn[6];
  Mc->RDBFL[7].U = SramEccTst_SingleBitErrPtrn[7];
  Mc->RDBFL[8].U = SramEccTst_SingleBitErrPtrn[8];
  Mc->RDBFL[9].U = SramEccTst_SingleBitErrPtrn[9];
  Mc->RDBFL[10].U = SramEccTst_SingleBitErrPtrn[10];

  /* Configure writing of single memory address: */
  Mc->CONFIG0.U =
      (uint16)(((uint32)SRAM_CONFIG0_NUMACCS_1 << (uint32)12u) | ((uint32)SRAM_CONFIG0_ACCSTYPE_WR << (uint32)0u));
  Mc->CONFIG1.U = 0U;
  Mc->RANGE.U = (uint16)(0& ((uint16)0x7fffu));
  /* Start write operation: */

  Mc->MCONTROL.U = (uint16)(((uint32)0x1u << (uint32)3u) | ((uint32)0x1u << (uint32)0u) |
                            ((uint32)MC_MCONTROL_USERED_MSK << (uint32)MC_MCONTROL_USERED));
  Mc->MCONTROL.U =
      (uint16)(((uint32)0x1u << (uint32)3u) | ((uint32)MC_MCONTROL_USERED_MSK << (uint32)MC_MCONTROL_USERED));
 

Regards-

0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

If you really want to know the exact reason, please read  CPU_Trap_Recognition_1_KIT_TC275_LK-TR It could be an asynchronus trap and if it is, the source is before the line you might think it is. Read CPU0_DEADD register.

 

MCONTROL must have Res4 = 4. MCONTROL reset value is 4008h. Try this:

Mc->MCONTROL.U = (uint16) (((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF)
| ((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF)
| ((0x1 & IFX_MC_MCONTROL_START_MSK) << IFX_MC_MCONTROL_START_OFF));


Mc->MCONTROL.U = (uint16) (((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF)
| ((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF));

 

Isn't the address in the RANGE register too high? How are you going to trigger the ALM0[10]? What address are you going to read?

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi Waldi,

I have tried with the configuration you suggested, but still the same behavior.

range register now I have configured is:                                                                                                                                     Mc->RANGE.U = (0 << 15) | (0xFF << 7) | (0x0 << 0);

Is this correct?

 

Also, I trigger theALM0[10] alarm by --

  p = (unsigned long *)0x70002044;
  *(p + 1) = 4;
  p = (unsigned long *)0x70002044;

Regards-

0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

To inject an error you need to write data with error to single DSPR location. By default it is zero and ECC is set. That is why Mc->RDBFL[0].U = 0x0001 is enough. The error is there but first the ECCMAP must be set to test mode where only data bits are mapped to RDBFLx. What is the value of SramEccTst_SingleBitErrPtrn[x]? Maybe you are doing it in different way.

Try this. Before write:

Mc->ECCS.U = (uint16) ((0x01 & IFX_MC_ECCS_ECCMAP_MSK) << IFX_MC_ECCS_ECCMAP_OFF); //test mode - data only

After write (MBIST done):

Mc->ECCS.U = (uint16) (((0x1 & IFX_MC_ECCS_TRE_MSK) << IFX_MC_ECCS_TRE_OFF)
| ((0x1 & IFX_MC_ECCS_ECE_MSK) << IFX_MC_ECCS_ECE_OFF)
| ((0x1 & IFX_MC_ECCS_AENE_MSK) << IFX_MC_ECCS_AENE_OFF)
| ((0x1 & IFX_MC_ECCS_UENE_MSK) << IFX_MC_ECCS_UENE_OFF)
| ((0x1 & IFX_MC_ECCS_CENE_MSK) << IFX_MC_ECCS_CENE_OFF)); //all on

Please read 9.4.4.6 Writing to a Single Memory Location in the user manual.

The RANGE works in different way (and why do you have there << 7). When RAEN is 0 (CONFIG0 = 0x1000) it holds memory location and for DSPR the value under address ADDR *16 will be changed i.e. if ADDR is 0x1000 check 0x70010000 to trigger an error, if ADDR is 0x1001  check 0x70010010

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi Waldi,

I was using below pattern for Mc->RDBFL[x].U ---
const uint16 SramEccTst_SingleBitErrPtrn[11] = {0x0001U, 0x0003U, 0x00C0U, 0x3000U, 0x0000U, 0x000CU, 0x0300U, 0xC000U, 0x0000U, 0x0030U, 0x0C00U};
 

I have tried with your suggestions but still issues.

I think to post the whole code here so that you can review once what I am doing ---- 

int main(void) {
volatile unsigned long *p;

hw_mainInit();

uint16_t endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword();
IfxScuWdt_clearSafetyEndinit(endinitSfty_pw);
SMU_KEYS.U = (uint32_t)0x000000BC;
SMU_AG0CF0.U = (1 << 10);
SMU_AG0CF1.U = (0 << 10);
SMU_AG0CF2.U = (1 << 10);
SMU_KEYS.U = (uint32_t)0x00000000;
IfxScuWdt_setSafetyEndinit(endinitSfty_pw);
enable_trap();

SMU_CMD.U = (unsigned int)0x00000000U;
for (int i = 0; i < 10000; i++) {
} // kill some time
inject_dspr_error();
p = (unsigned long *)0x70002040;
*(p + 1) = 4;
p = (unsigned long *)0x70002040;

while(1)
{}
}

void inject_dspr_error(void) {
uint16_t endinitSfty_pw = IfxScuWdt_getSafetyWatchdogPassword();
IfxScuWdt_clearSafetyEndinit(endinitSfty_pw);

uint16_t passwd = IfxScuWdt_getCpuWatchdogPassword();
IfxScuWdt_clearCpuEndinit(passwd);
MTU_CLC.B.DISR = 0U;
while (MTU_CLC.B.DISS)
;
IfxScuWdt_setCpuEndinit(passwd);
MTU_MEMTEST0.B.CPU0DSEN = 1U; // Enable MTU for DSPR0
inject_memory_error(14);
MTU_MEMTEST0.B.CPU0DSEN = 0U; // Disable MTU for DSPR0
IfxScuWdt_setSafetyEndinit(endinitSfty_pw);
}


void inject_memory_error(const uint32 mc_number) {
uint32 ResultLoopCount;

Ifx_MC *Mc;
Mc = (Ifx_MC *)((uint32)&MODULE_MC0 + ((uint32)0x100* (uint32)mc_number));

Mc->ECCS.U = (uint16)((0x01 & IFX_MC_ECCS_ECCMAP_MSK) << IFX_MC_ECCS_ECCMAP_OFF);
Mc->RDBFL[0].U = 0x0001;
Mc->ECCS.U = (uint16)(((0x1 & IFX_MC_ECCS_TRE_MSK) << IFX_MC_ECCS_TRE_OFF) |
((0x1 & IFX_MC_ECCS_ECE_MSK) << IFX_MC_ECCS_ECE_OFF) |
((0x1 & IFX_MC_ECCS_AENE_MSK) << IFX_MC_ECCS_AENE_OFF) |
((0x1 & IFX_MC_ECCS_UENE_MSK) << IFX_MC_ECCS_UENE_OFF) |
((0x1 & IFX_MC_ECCS_CENE_MSK) << IFX_MC_ECCS_CENE_OFF)); //all on

/* Configure writing of single memory address: */
Mc->CONFIG0.U =
(uint16)(((uint32)SRAM_CONFIG0_NUMACCS_1 << (uint32)12u) | ((uint32)SRAM_CONFIG0_ACCSTYPE_WR << (uint32)0u));
Mc->CONFIG1.U = 0U;
Mc->RANGE.U = 0x0204;

Mc->MCONTROL.U = (uint16)(((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF) |
((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF) |
((0x1 & IFX_MC_MCONTROL_START_MSK) << IFX_MC_MCONTROL_START_OFF));

Mc->MCONTROL.U = (uint16)(((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF) |
((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF));
for (ResultLoopCount = 0U; ResultLoopCount < 50; ResultLoopCount++) {
__asm("nop");
}
}

Regards-

0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

Try this:

p = (unsigned long *) 0x70002040;
uint32_t a;
a = *p;

With this:

static inline __attribute__((always_inline)) void inject_dspr_error (void)
{
IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[0], IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[0]));
MTU_CLC.U = 0U;
IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[0], IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[0]));

IfxScuWdt_clearSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
MTU_MEMTEST0.B.CPU0DSEN = 1U; // Enable MTU for DSPR0
inject_memory_error(14);
MTU_MEMTEST0.B.CPU0DSEN = 0U; // Disable MTU for DSPR0
IfxScuWdt_setSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
}

static inline __attribute__((always_inline)) void inject_memory_error (const uint32 mc_number)
{
uint32 ResultLoopCount;

switch (mc_number)
{
case 14 :
MODULE_MC14.ECCS.U = (uint16) ((0x01 & IFX_MC_ECCS_ECCMAP_MSK) << IFX_MC_ECCS_ECCMAP_OFF);

MODULE_MC14.RDBFL[0].U = SramEccTst_SingleBitErrPtrn[0];
MODULE_MC14.RDBFL[1].U = SramEccTst_SingleBitErrPtrn[1];
MODULE_MC14.RDBFL[2].U = SramEccTst_SingleBitErrPtrn[2];
MODULE_MC14.RDBFL[3].U = SramEccTst_SingleBitErrPtrn[3];
MODULE_MC14.RDBFL[4].U = SramEccTst_SingleBitErrPtrn[4];
MODULE_MC14.RDBFL[5].U = SramEccTst_SingleBitErrPtrn[5];
MODULE_MC14.RDBFL[6].U = SramEccTst_SingleBitErrPtrn[6];
MODULE_MC14.RDBFL[7].U = SramEccTst_SingleBitErrPtrn[7];
MODULE_MC14.RDBFL[8].U = SramEccTst_SingleBitErrPtrn[8];
MODULE_MC14.RDBFL[9].U = SramEccTst_SingleBitErrPtrn[9];
MODULE_MC14.RDBFL[10].U = SramEccTst_SingleBitErrPtrn[10];

MODULE_MC14.RANGE.U = 0x0204;

/* Configure writing of single memory address: */
MODULE_MC14.CONFIG0.U = (uint16) (((0x0 & IFX_MC_CONFIG0_ACCSTYPE_MSK) << IFX_MC_CONFIG0_ACCSTYPE_OFF)
| ((1 & IFX_MC_CONFIG0_NUMACCS_MSK) << IFX_MC_CONFIG0_NUMACCS_OFF));
MODULE_MC14.CONFIG1.U = 0U;

MODULE_MC14.MCONTROL.U = (uint16) (((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF)
| ((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF)
| ((0x1 & IFX_MC_MCONTROL_START_MSK) << IFX_MC_MCONTROL_START_OFF));

MODULE_MC14.MCONTROL.U = (uint16) (((0x10 & IFX_MC_MCONTROL_RES4_MSK) << IFX_MC_MCONTROL_RES4_OFF)
| ((0x1 & IFX_MC_MCONTROL_DIR_MSK) << IFX_MC_MCONTROL_DIR_OFF));

for (ResultLoopCount = 0U; ResultLoopCount < 50; ResultLoopCount++)
{
__asm("nop");
}

MODULE_MC14.ECCS.U = (uint16) (((0x1 & IFX_MC_ECCS_TRE_MSK) << IFX_MC_ECCS_TRE_OFF)
| ((0x1 & IFX_MC_ECCS_ECE_MSK) << IFX_MC_ECCS_ECE_OFF)
| ((0x1 & IFX_MC_ECCS_AENE_MSK) << IFX_MC_ECCS_AENE_OFF)
| ((0x1 & IFX_MC_ECCS_UENE_MSK) << IFX_MC_ECCS_UENE_OFF)
| ((0x1 & IFX_MC_ECCS_CENE_MSK) << IFX_MC_ECCS_CENE_OFF)); //all on
break;
default :
break;
}
}

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi Waldi,

still no alarm generated. I have tried every possible scenario but wondering what is the missing step or thing in the code.

Regards-

0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

Please check if this function will return true value:

boolean IsDsprCorrectableError(void)
{
Ifx_MC *mc = (Ifx_MC *)(0xF0061000U + 0x100 * 14);
return (mc->ECCD.B.CERR == 1);
}

What is inside enable_trap function?

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi Waldi,

enable_trap(): I am only enabling the SMU error as below --

  uint16_t endinitSfty_pw = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[0]);

  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[0], endinitSfty_pw);
  SCU_TRAPCLR.B.SMUT = 1;
  SCU_TRAPDIS.U = 0x0000fff7;
  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[0], endinitSfty_pw);
 
and after injecting error, once I trying to read mc->ECCD.B.CERR  then the trap occurs with trap class: 4 and Id:2 means Data access synchronous error. I am not able to read the status of ECCD.B.CERR.
 
Regards-
0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

There shoudn't be a trap while reading mc->ECCD.B.CERR if the MTU module is enabled. Could you check CPU0_DEADD register when the trap is generated.

You can also use something like this to check if SMU knows about DSPR correctable error:

boolean IsSmuAg0Sf10Raised(void)
{
return (SMU_AG0.B.SF10 == 1);
}

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi Waldi,

I have checked all the registers. No register has any fault.

Shambhu_1-1660133655167.png

Regards-

 

0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

Try something simple and forget about SMU configuration for now:

volatile unsigned long *p;

for (uint32 i = 0; i < 16; ++i) {
*((uint8 *)(0x70002040 + i)) = 0x00;
}
__nop();
inject_dspr_error();
__nop(); // check  if MC14_ECCD = 0x7C00
p = (unsigned long *) 0x70002040;
uint32_t a;
a = *p;
__nop();  // check  if MC14_ECCD = 0x7C23
if( IsDsprCorrectableError() )
{
__nop();
__nop();
__nop();
}

if ( IsSmuAg0Sf10Raised() )
{
__nop();
__nop();
__nop();
}

Check MC14_ECCD values

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Hi Waldi,

Thanks for suggestion!

yes it works as you have suggested. like the value of MC14_ECCD comes 0x7C23 (means correctable errors) come but the exact alarm alm0[10] is not being generated (I think because we haven't configured the same?).

But I have configured the alm0[10] then I tried, I got SMU_AG0.B.SF10 as 1 means alm0[10]. but the SMU_AD0.B.DF10 still 0 and in the code, we check the SMU_AD0.B.DF10 for DSPR correctable error. please suggest how to get the values in SMU_ADx...

Regards-

0 Likes
Waldi
Level 4
Level 4
5 solutions authored 10 sign-ins 10 replies posted

According to the 10.4.5.5 Alarm Debug Registers in the user manual the snapshot is taken when reset is executed by the SMU or transition to FAULT and there is nothing about NMI request which you configured by seting SMU_AG0CFx . Check flag SCU_TRAPSTAT.B.SMUT

0 Likes
Shambhu
Level 2
Level 2
50 sign-ins 10 replies posted 25 sign-ins

Thanks a lot Waldi for your help!

Regards-

0 Likes