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.

TMS570LC4357 DMA transfer didn't fail on ECC invalid flash

Other Parts Discussed in Thread: TMS570LS3137, TMS570LC4357, HALCOGEN

Hello,

We want to check ECC of flash during boot sequence. For this functionality we start DMA transfer from flash to CRC controler and after this test we need tot have CRC of complete flash and ESM signals about soft/hard ECC errrors. 

It works fine on TMS570LS3137, but not on TMP570LC4357AZWTQQ1. I am absolutely sure that we have broken ECC in flash (we test it, read by LDR instruction provide ESM error).

TMS570LS3137 has reaction as we expect. It sets ESM group 1 channel 5 and/or ESM group 3 channel 7

TMS570LC4357 has no reaction to ECC error in ESM unit. Why? How to detect ECC fail when we use DMA channel to read flash?

Here is dump of ESM and flash controller registers before DMA transfer (all numbers in HEX):

0000001E-boot: ESM00:        0        0        0        0
0000001E-boot: ESM10:        0        0        0        0
0000001E-boot: ESM20:        0        1        0        0
0000001E-boot: ESM30:     3fff     3fff        0        0
0000001F-boot: ESM40:        0        0        0        0
0000001F-boot: ESM50:        0        0        0        0
0000001F-boot: ESM60:        0        0        0        0
0000001F-boot: ESM70:        0        0        0        0
0000001F-boot: ESM80:        0        0        0        0
00000020-boot: ESM90:        0        0        0        0
00000020-boot: ESMa0:        0        0        0        0

00000020-boot: FMC00:      303        0        0        0
00000020-boot: FMC10:        0        0        0        0
00000020-boot: FMC20:        0        0    12441    12441
00000020-boot: FMC30:        0        0       7c        f
00000021-boot: FMC40:     ffff   7c80ff   c80001        0
00000021-boot: FMC50:        0        0        0        0
00000021-boot: FMC60:        0     55aa        0    a0000
00000021-boot: FMC70:        0        0        0     5400
00000021-boot: FMC80:        b   eb0055   db0000    f0000
00000021-boot: FMC90:      716     a000        4  700010a
00000022-boot: FMCa0:        0        0        0        0
00000022-boot: FMCb0:        0        3      5ff     1000
00000022-boot: FMCc0:        0        0        0        0
00000022-boot: FMCd0: ffffffff      3ff        0        0

And here is same dump after (all numbers in HEX). Test needs 30ms to run.:

00000040-boot: ESM00:        0        0        0        0
00000040-boot: ESM10:        0        0        0        0
00000040-boot: ESM20:        0        1        0        0
00000041-boot: ESM30:     3fff     3fff        0        0
00000041-boot: ESM40:        0        0        0        0
00000041-boot: ESM50:        0        0        0        0
00000041-boot: ESM60:        0        0        0        0
00000041-boot: ESM70:        0        0        0        0
00000041-boot: ESM80:        0        0        0        0
00000042-boot: ESM90:        0        0        0        0
00000042-boot: ESMa0:        0        0        0        0
00000042-boot: FMC00: 303 0 0 0 00000042-boot: FMC10: 0 0 0 0 00000042-boot: FMC20: 0 0 bd61 bd61 00000043-boot: FMC30: 0 0 7c f 00000043-boot: FMC40: ffff 7c80ff c80001 0 00000043-boot: FMC50: 0 0 0 0 00000043-boot: FMC60: 0 55aa 0 a0000 00000043-boot: FMC70: 0 0 0 5400 00000043-boot: FMC80: b eb0055 db0000 f0000 00000044-boot: FMC90: 716 a000 4 700010a 00000044-boot: FMCa0: 0 0 0 0 00000044-boot: FMCb0: 0 3 5ff 1000 00000044-boot: FMCc0: 0 0 0 0 00000044-boot: FMCd0: ffffffff 3ff 0 0

Here is simplified code snippet which we use to start DMA:

#ifdef TMS570LCx3
  #define CRC_UNIT crcREG1
  #define CRC_TARGET (0xFE000000u + 0x60u)
  #define FLASH_MB 4
#else
  #if defined(TMS570LSx1)
    #define CRC_UNIT crcREG
    #define CRC_TARGET (0xFE000000u + 0x60u)
    #define FLASH_MB 3
  #else
      #error unknown MCU
  #endif
#endif

void flashCheck(U32 begin, U32 len)
{
  const g_dmaCTRL dmaCtl0 = {
    begin,                     //uint32 SADD;       /* Initial source address           */
    CRC_TARGET,             //uint32 DADD;       /* Initial destination address      */
    0,                      //uint32 CHCTRL;     /* Next channel to be triggered + 1 */
    FLASH_FRAGMENTS,        //uint32 FRCNT;      /* Frame   count                    */
    FLASH_ELEMENTS(len),    //uint32 ELCNT;      /* Element count                    */
    0,                      //uint32 ELDOFFSET;  /* Element destination offset       */
    0,                      //uint32 ELSOFFSET;  /* Element source offset            */
    0,                      //uint32 FRDOFFSET;  /* Frame destination offset         */
    0,                      //uint32 FRSOFFSET;  /* Frame source offset              */
  #if defined(TMS570LSx1)
    4,                      //uint32 PORTASGN;   /* DMA port                         */
  #else
    PORTA_READ_PORTB_WRITE, //uint32 PORTASGN;   /* DMA port                         */
  #endif
    ACCESS_64_BIT,          //uint32 RDSIZE;     /* Read element size                */
    ACCESS_64_BIT,          //uint32 WRSIZE;     /* Write element size               */
    BLOCK_TRANSFER,         //uint32 TTYPE;      /* Trigger type - frame/block       */
    ADDR_INC1,              //uint32 ADDMODERD;  /* Addressing mode for source       */
    ADDR_FIXED,             //uint32 ADDMODEWR;  /* Addressing mode for destination  */
    AUTOINIT_OFF            //uint32 AUTOINIT;   /* Auto-init mode                   */
  #if defined(TMS570LSx1)
    ,0                      //uint32 COMBO;      /* next ctrl packet trigger(Not used) */
  #endif
  };

  CRC_UNIT->CTRL0 = (U32)((U32)1U << 0U)
                  | (U32)((U32)1U << 8U);
  CRC_UNIT->CTRL0=0u;

  CRC_UNIT->INTS=0u;
  CRC_UNIT->PCOUNT_REG1=0u;
  CRC_UNIT->PCOUNT_REG2=0u;
  CRC_UNIT->SCOUNT_REG1=0u;
  CRC_UNIT->SCOUNT_REG2=0u;
  CRC_UNIT->WDTOPLD1=0u;
  CRC_UNIT->WDTOPLD2=0u;
  CRC_UNIT->BCTOPLD1=0u;
  CRC_UNIT->BCTOPLD2=0u;
  CRC_UNIT->REGL1=0u;
  CRC_UNIT->REGL2=0u;
  CRC_UNIT->REGH1=0u;
  CRC_UNIT->REGH2=0u;

  /** - Setup the Channel mode */
  CRC_UNIT->CTRL2 |= (U32)(CRC_FULL_CPU)  | (U32)((U32)CRC_FULL_CPU << 8U);

  dmaEnable();
  dmaSetCtrlPacket(DMA_CH0, dmaCtl0);
  dmaSetPriority(DMA_CH0, LOWPRIORITY);
  dmaSetChEnable(DMA_CH0, DMA_SW);

  while (dmaIsChannelActive(DMA_CH0) != False)
  {
    watchDogRefresh();
  }
}

void test(void)
{
  dump_ECC_ESM();  
  flashCheck(0u, FLASH_MB * 1024u*1024u);
  dump_ECC_ESM();
}

Have a nice day,
Jiri

  • Hi Jiri,

      GP1.5 and GP3.7 are reserved in LC4357. The LC4357 has different architecture. Unlike LS3137 where the ECC errors are detected by the CPU when the DMA accesses the flash, in LC4357 the ECC errors are detected by the CPU interconnect. Note that there is no more TCM interface in the LC4357. The DMA does not go through the CPU's AXI-S interface to access the flash on the TCM interface. In LC4357 when the CPU interconnect detects an ECC error due to an access from the DMA it will route the error to the EPC module. Please read about the EPC module for details. In short, the EPC module has built in CAM (Content Addressable Memory) where single bit error addresses will be stored in the CAM. If a single bit error is repeated on an address that is already stored in the CAM then the EPC will not generate error signal to the ESM. This is to prevent a tightly loop with ECC errors from generating interrupts to the CPU constantly for single bit errors.

     Please check GP1.4 and GP2.21 instead for EPC correctablea and uncorrectable errors.

     

  • Thanks for the information.
    It he only one complication. It isn't possible to check ECC without FIQ interrupt from EPC->ESM.
    And it also need enable ECC in interconnect module (Halcogen function epcEnableIP1ErrorGen). Why it isn't enabled by default in HalCoGen HL_sys_startup.c ?
  • Hi Jiri,

      There is API to enable the CPU interconnect ECC error generation to the EPC. Please use epcEnableIP1ErrorGen() and epcEnableIP2ErrorGen() to enable the EPC errors to the ESM module.

      I like your suggestion that that it could have been enabled by default in HalCoGen.