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.

ESMSR3 not signaling 2-bit flash errors

Other Parts Discussed in Thread: HALCOGEN

I created my own bootloader,not using HALcogen.

When I perform an ECC check for flash, I can see that the code catches 1 bit errors to flash in ESMSR1, but it doesn't catch 2-bit errors to flash, even though it cacthes 2-bit errors in RAM.

I'm certainly missing a setting, but I don't see where.

void checkFlashECC() {
    volatile uint32_t flashRead;

    F021Reg->FEDACTRL1 = 0x000A060AU; /*Configuration of registers for the flash ECC check*/
    F021Reg->FPAR_OVR = 0x00005A01U;
    F021Reg->FDIAGCTRL = 0x01050007U;   /*Configure and enable diagnostic mode*/
    
    flashRead = (*(volatile uint32_t *)0x20000000); /*Causes a 1-bit ECC error*/

    F021Reg->FDIAGCTRL = 0xA0007U;  /*Disable diagnostic mode*/

    if (!(F021Reg->FEDACSTATUS & 0x2)) {    /*If the error wasn't caught by this register, then the boot process cannot continue*/
        while(1);
    } else {
        F021Reg->FEDACSTATUS = 0x2U; /*Clears status flag*/
        ESMReg->ESMSR1 = 0x40U; /*Clears ESM flag*/

        /*Now the code must reset the ECC check for a 2-bit error*/
        F021Reg->FDIAGCTRL = 0x50007U; /*Configure diagnostic mode*/
        F021Reg->FPAR_OVR = 0x00005A03U;
        F021Reg->FDIAGCTRL |= 0x01000000U;    /*Enable diagnostic mode*/

        flashRead = (*(volatile uint32_t *)0x20000010); /*Causes a 2-bit ECC error*/

        flashRead = F021Reg->FUNC_ERR_ADD; /*Reads func error address to clear it*/

        F021Reg->FDIAGCTRL = 0x000A0007;
    }
}

I compared it to the one created by HALcogen and I noticed that they are practically identical. I checked both start ups (especially the asm files) and they do the exact same thing. Maybe I'm not setting a register correctly? Any ideas?

  • I can verify that the ATCMPCEN bit is set. The value of the auxiliary control register at the time of the error is:

    0x0E000027

  • Hello Pablo,

    Unfortunately, I am not able to spot the problem on a quick review of your code. I have forwarded your issue to one of our other experts so they can work with you to resolve your problem.

  • I'll add the bootloader here so you can take a better look. Sorry I won't be able to post the entire code here.1263.project.zip

    The workaround I had for this was on line 39. Now it says:

    subs    pc, lr, #8            ; restore state of CPU when abort occurred, and branch back to instruction that was aborted

    It used to be:

    subs    pc, lr, #4            ; restore state of CPU when abort occurred, and branch back to instruction that was aborted

  • Hello Pablo,

      Please note that the data abort is of a severe error. Error handler for the data abort is expected to correct the problem first and the return instruction will retry the access again. The return instruction from a data abort  will be subs pc, lr, #8 generated by the compiler. I think what might have happened in your case is that the first time you do the checkFlashECC() it is setting the ESMSR3 and before you exit the abort routine the flags are cleared. When you exit out of the abort handler the return instruction is bringing you to the  below instruction again. 

    flashRead = (*(volatile uint32_t *)0x20000010); /*Causes a 2-bit ECC error*/

      So you are reading the address again. However, the second time you read the same address you no longer have the trigger to the diagnostic mode and hence there is no ESMSR3 getting set. You can try to put a asm(" b #-8) statement at the beginning of the data abort handler and see if the ESMSR3 get set the first time. After you see the ESMSR3 set, you can do a move line to the next instruction to see how the flags are cleared.

    regards,

    Charles

    If my reply answers your question please click on the green button "Verify Answer".

  • That is the first thing I thought when this error happened, since it had already happened before so I did exactly that, and as you can imagine the same thing happened.

    ESMSR3 had the values 0x8, 0x20 and 0x0, where 0x80 and 0x20 are 2-bit errors in RAM, and the 0 points to the flash error, which means it wasn't able to get it. Since I am able to catch 1 and 2-bit errors in RAM and 1-bit errors in flash, I can only imagine that there is something I'm missing.

    But so far I haven't been able to catch this error. Maybe not using HALcogen, and using a differente entry_point is causing this?

  • Pablo,

      I'm not too clear on your statement "ESMSR3 had the values 0x8, 0x20 and 0x0, where 0x80 and 0x20 are 2-bit errors in RAM, and the 0 points to the flash error". The flash uncorrectable error is at bit7 of the ESMSR3 so it is 0x80. But you are stating 0x80 and 0x20 are for RAM and 0 is for flash. So if you ever see 0x80 in ESMSR3 then it is for the flash.

    regards,

    Charles

  • Hello Pablo,

      Attached is a simple project. It will call the checkFlashECC() twice. First time it was called in sys_startup.c. This is generated by the HalcoGen. I insert another call in the main(). Both times, I can see the 0x80 in the ESMSR4 for the flash uncorrectable error.

     8231.LS31x_checkFlashECC.zip

    regards,

    Charles

  • Sorry I didn't explain it well enough. I was in a hurry. I ment to say the following. 

    I already tried to put the "b #-8"  at the beginning of the data abortion treatment. When I check the ESMSR3 register I can see that it only catches bit 5 and bit 3 of the ESMSR3, which are uncorrectable ECC errors in RAM. 

    When I do the "move to" and let the program run, when it gets to the ECC flash check I notive that the ESMSR3 module is not signaled (bit 7 of ESMSR3 should be set, and that's what the code generated by HALcogen does). 

    The exception treatment compares the content of ESMSR3 with 0x80, and when it gets here I can see that the bit is not being set. 

    PS: Sorry it took me such a long time to answer, I wasn't near a computer.  

  • About this code. I know that the uC works properly and that HALcogen generates the correct code. The thing is that my code is not signaling this bit, which is strange in my opinion. But I can see clearly that it works ok with the code generated by HALcogen. This means that I'm forgetting to set something somewhere, and I have no idea where. I need to find the missing bit to be set (if it's just a bit, it could be a chunk of code that I'm either not coding properly, or forgot to put)

  • Hello Pablo,

      When CPU detects an uncorrectable error, it will signal the error event to the flash module. The flash module FEDACSTATUS register should be updated for bit 8. Do you see this bit getting set? Once the flash module captures the error event from the CPU, it will then send route the error signal to the ESM module. The flags in the FEDACSTATUS can only write-clear. Once the uncorrectable errors are set, the current error address is stored in the UNC_ERR_ADD register. The UNC_ERR_ADDR is then frozen. It will not change again unless it is first un-frozen by being read. Subsequent uncorrrectable errors are blocked from setting additional error bits until the UNC_ERR_ADD is unfrozen.

      So the question is if the FEDACSTATUS ever get set? If it ever gets set once, did you read the UNC_ERR_ADDR so that subsequent errors can be captured again? 

    regards,

    Charles

  • Just tested this again. FEDACSTATUS is not being set. But when I try this piece of code with the bootloader generated ny HALcogen it works. I know I'm missing something,I just don't know what.

    I've followed the Initialization document, but I just can't find what I'm missing

  • Pablo,

      I added the line highlighted in red to read the uncorrectable error addr register and it now works. You should see the flash uncorrectable flag getting set. For some reason, you may have an uncorrectable flash ECC error happening before the checkFlashECC() is called. Because of this the flash uncorrectable error address and its related flag is frozen from generating error to the ESM.

    		F021Reg->FEDACSTATUS = 0x2U; /*Clears status flag*/
    		ESMReg->ESMSR1 = 0x40U; /*Clears ESM flag*/
    
            flashRead = F021Reg->FUNC_ERR_ADD; /*Reads func error address to clear it*/
    
    
    		/*Now the code must reset the ECC check for a 2-bit error*/
            F021Reg->FDIAGCTRL = 0x50007U; /*Configure diagnostic mode*/
    		F021Reg->FPAR_OVR = 0x00005A03U;
    		F021Reg->FDIAGCTRL |= 0x01000000U;    /*Enable diagnostic mode*/
    
    		flashRead = (*(volatile uint32_t *)0x20000010); /*Causes a 2-bit ECC error*/
    
            flashRead = F021Reg->FUNC_ERR_ADD; /*Reads func error address to clear it*/

     regards,

    Charles

  • Pablo,

      I think I found the cause of the problem in your code. In your boot code you first call flashSECDED() to test out flash module's built-in ECC. After the two bit error is tested, you didn't read the uncorrectable error address and hence it is frozen. After I added below then it works when you call the checkFlashECC().

    FLASHReg->FEDACSTATUS = (1 << 17) | (1 << 11) | (1 << 8);

    flashRead = F021Reg->FUNC_ERR_ADD;

    regards,

    Charles

     

  • You are a genious!!!

    Everything works now. Thank you very much

  • Pablo,

     I'm glad you solved the problem.

    regards,

    Charles