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