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.
Hi,
In my bootloader I want to utilize embedded CRC Controller to calculate the CRC of the application image before jumping to it.
I think Auto mode with DMA would be fastest.
could TI provide sample code calculating single CRC of a large flash region? (let's say the application image is larger than 1 MB)
I want to produce single CRC, not multiple for every 1Kb etc.
thank you in advance
Thank you QJ.
I decided to go with Semi-CPU mode . Odd thing is that the first time I calculate CRC , PSA_SECSIGREGL1/H1 are 0x0 and some value stored in PSA_SIGREGL1/H1. However on subsequent calculations, PSA_SIGREGL1/H1 are 0x0, and PSA_SECSIGREGL1/H1 have the value I observed in PSA_SECSIGREGL1/H1 after calculatingCRC for the first time.
In Semi-CPU mode, I know I should read PSA_SECSIGREGL1/H1 to get the CRC value.
No idea why CRC value is stored in PSA_SIGREGL1/H1 for the first CRC calculation?
here is what I got:
int main()
{
..
rtiInit();
sciInit();
/** - configuring crc */
crcInit();
sciEnableNotification ( sciREG, SCI_RX_INT );
sciEnableNotification ( sciREG, SCI_TX_INT );
rtiEnableNotification ( rtiNOTIFICATION_COMPARE0 );
_enable_IRQ();
..
crc_tms570(start_address, size);
// PSA_SECSIGREGL1/H1 are 0x0 and some value stored in PSA_SIGREGL1/H1, let's say X and Y
crc_tms570(start_address, size);
// PSA_SIGREGL1/H1 are 0x0, and PSA_SECSIGREGL1/H1 have X and Y
crc_tms570(start_address, size);
// PSA_SIGREGL1/H1 are 0x0, and PSA_SECSIGREGL1/H1 have X and Y
}
uint64_t crc_tms570(uint32_t start_address, uint32_t size)
{
volatile uint32_t counter = 0;
uint32_t Pcount = size / 8;
/** - Setup the Channel mode */
crcREG->CTRL2=0x00000000;
crcREG->CTRL2 |= (CRC_SEMI_CPU);
dmaEnable();
crcREG->CTRL2 &=0xFFFFFFFCU;
crcREG->CTRL2 |= CRC_SEMI_CPU;
crcREG->PCOUNT_REG1 = Pcount;
crcREG->SCOUNT_REG1 = 1;
crcChannelReset(crcREG, 0);
/* - assigning dma request: channel-0 with request line - 26 */
dmaReqAssign(DMA_CH0, 26 );
/* - configuring dma control packets */
dmaConfigCtrlPacket(start_address, (uint32_t)(&(crcREG->PSA_SIGREGL1)), Pcount, ADDR_INC1, ADDR_FIXED, AUTOINIT_ON);
/* - setting dma control packets */
dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT);
/* - setting the dma channel to trigger on s/w request */
dmaSetChEnable(DMA_CH0, DMA_SW);
while ((crcREG->BUSY & 0x1))
{
counter++;
if ((counter % 0x20000) == 0)
{
dwdReset();
}
}
dmaDisable();
// at first call to this crc_tms570(), PSA_SECSIGREGL1/H1 are 0x0 and some value stored in PSA_SIGREGL1/H1
uint64_t crc_actual = (((uint64)crcREG->PSA_SIGREGL1 << 32U) | (uint64)crcREG->PSA_SIGREGH1);
// however on subsequent calls to this crc_tms570(), PSA_SIGREGL1/H1 are 0x0, and PSA_SECSIGREGL1/H1 have some value
// PSA_SECSIGREGL1/H1 should store CRC value no matter first or latter calls
// so, why are CRC values stored in PSA_SIGREGL1/H1 for the first CRC calculation
//uint64_t crc_actual = (((uint64)crcREG->PSA_SECSIGREGL1 << 32U) | (uint64)crcREG->PSA_SECSIGREGH1);
return crc_actual;
}
It looks like the device is going through a system reset. Can you probe the nRST pin to see if it goes low when this happens?
I don;t see the "BAD0BAD0" pattern any more. however CRc complete interrupt does not fire sometimes. Could you please review the function below? Not sure what I am doing wrong?
int main()
{.....
crcInit();
enableCRCNotification(CrcREG, CRC_CH1_CC);
......}
static uint64_t crc_64(uint32_t start_address, uint32_t size)
{
uint32_t Pcount = size / 8;
/** - Setup the Channel mode */
crcREG->CTRL2=0x00000000;
crcREG->CTRL2 |= (CRC_SEMI_CPU);
dmaEnable();
crcREG->CTRL2 &=0xFFFFFFFCU; // ch 0
crcREG->CTRL2 |= CRC_SEMI_CPU;
crcREG->PCOUNT_REG1 = Pcount;
crcREG->SCOUNT_REG1 = 1;
crcChannelReset(crcREG, 0);
/* - assigning dma request: channel-0 with request line - 26 */
dmaReqAssign(DMA_CH0, 26 );
/* - configuring dma control packets */
dmaConfigCtrlPacket(start_address, (uint32_t)(&(crcREG->PSA_SIGREGL1)), Pcount, ADDR_INC1, ADDR_FIXED, AUTOINIT_OFF);
/* - setting dma control packets */
dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT);
/* - setting the dma channel to trigger on s/w request */
dmaSetChEnable(DMA_CH0, DMA_SW);
while ((dmaREG->GCTRL & (1 << 14)) && (crcREG->BUSY & 0x1));
dmaDisable();
uint64_t crc = crcGetSectorSig(crcREG, 0);
/* Clear CH1_CCIT bit */
crcREG->STATUS = CRC_CH1_CC;
return crc;
}
static void dmaConfigCtrlPacket(uint32_t sadd,uint32_t dadd,uint32_t dsize,uint8_t ADD_RD_MODE,uint8_t ADD_WR_MODE,uint8_t AIM)
{
g_dmaCTRLPKT.SADD = sadd; /* source address */
g_dmaCTRLPKT.DADD = dadd; /* destination address */
g_dmaCTRLPKT.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT.FRCNT = 1; /* frame count */
g_dmaCTRLPKT.ELCNT = dsize; /* element count */
g_dmaCTRLPKT.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT.FRSOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT.PORTASGN = 4; /* port b */
g_dmaCTRLPKT.RDSIZE = ACCESS_64_BIT; /* read size */
g_dmaCTRLPKT.WRSIZE = ACCESS_64_BIT; /* write size */
g_dmaCTRLPKT.TTYPE = BLOCK_TRANSFER ; /* transfer type */
g_dmaCTRLPKT.ADDMODERD = ADD_RD_MODE; /* address mode read */
g_dmaCTRLPKT.ADDMODEWR = ADD_WR_MODE; /* address mode write */
g_dmaCTRLPKT.AUTOINIT = AIM; /* autoinit */
}