Hello,
I cannot figure how to trigger the CRC calculation in Semi-CPU mode as described in Section 3.5 of spna235.
I can trigger the DMA and the transfer completes (to PSA_SECSIGREGL1) but no CRC activity occurs (I see no CRC1 register changes)
After the DMA operation is complete I am enabling the CRC interrupts thinking that maybe that is how to kickoff the calculation but that has no effect:
Thanks in advance,
Mark
Caller:
crcInit();
dmaREG->GCTRL |= 1; // Reset DMA Module
dmaREG->GCTRL &= ~1;
DmaCrcStart(0);
while (!IsDmaCrcFinished())uDMACtr++;
/* after DMA does the transfer,CPU is invoked by CC interrupt to do signature verification */
crcREG1->INTS = 0x1F;
while ((crcREG1->STATUS & 1) == 0)uCRCCtr++; // Check CCIT bit
/// *** NEVER GETS HERE - No CRC register changes occur
/***************************************************************************************************************
DmaCrcStart
Starts a CRC calculation operation for the given sector. Use IsDmaCrcFinished() to determine when finished.
***************************************************************************************************************/
bool DmaCrcStart(UINT32 uSector)
{
UINT32 u64BitChunksToProcess = uSectorSizeBytes[uSector]/8;
// CRC SETUP
crcChannelReset(crcREG1, 0); // Reset channel 0 of CRC 1
crcREG1->CTRL0 &=1; // Reset PSA Sig Reg
crcREG1->CTRL0 &=0xFFFFFFFE;
crcREG1->PCOUNT_REG1 = u64BitChunksToProcess; // Number of chunks to compress before CRC eval
crcREG1->SCOUNT_REG1 = 1; // 1 sector to compress
crcREG1->BCTOPLD1= 0xFFFFF; // Timeout
crcREG1->CTRL2 =0x00000002U; // Semi-CPU Mode
// DMA SETUP
g_dmaCTRL g_dmaCTRLPKT;
dmaDisable(); // Disable DMA for configuration changes - will pause at
// arbitration boundry if in current transaction
dmaReqAssign(CRC_DMA_CH, DMA_CRC_REQ_CH); // Assign the DMA channel for this transaction
// Configure control packet for DMA Channel 0
g_dmaCTRLPKT.SADD = (uint32)GetSectorAddress(uSector); // source address
g_dmaCTRLPKT.DADD = (uint32)&crcREG1 -> PSA_SECSIGREGL1; // destination address = CRC
g_dmaCTRLPKT.CHCTRL = 0; /* channel control */
// Each frame will transmit out FRCNT bytes to CRC engine
// So transfer is the SectorSize/64 * 1 frame
g_dmaCTRLPKT.FRCNT = 1; // Frames to transfer = bytes in message
g_dmaCTRLPKT.ELCNT = u64BitChunksToProcess; // 64-bit transfers to make to DMA
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 Source offset
g_dmaCTRLPKT.PORTASGN = PORTA_READ_PORTB_WRITE; // Read Memory - Write Peripheral
g_dmaCTRLPKT.RDSIZE = ACCESS_64_BIT; // read element size
g_dmaCTRLPKT.WRSIZE = ACCESS_64_BIT; // write element size
g_dmaCTRLPKT.TTYPE = BLOCK_TRANSFER; // transfer type - FRAME or BLOCK
g_dmaCTRLPKT.ADDMODERD = ADDR_INC1; // Increment read pointer after each move
g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED; // Fixed write pointer (PSA_SECSIGREGL1)
g_dmaCTRLPKT.AUTOINIT = AUTOINIT_OFF; /* autoinit */
dmaSetCtrlPacket(CRC_DMA_CH, g_dmaCTRLPKT);
dmaREG->FTCFLAG |= (1<<CRC_DMA_CH); // Clear FRAME transfer finished flag
dmaREG->BTCFLAG |= (1<<CRC_DMA_CH); // Clear BLOCK transfer finished flag
dmaSetChEnable(CRC_DMA_CH, DMA_SW); // Enable DMA chamnnel 0 and enable SW triggering
dmaEnable();
return true;
}