Hello everyone!
I'm having issues with SCI transfers over DMA in my application. I'm using SCI over DMA as a logger and I'm spitting out quite a bit of data. When I do consecutive calls to the logger to write data over DMA, I typically only see the last message fully come out of the SCI module. Whenever I'm logging something, I create a buffer and then send a pointer to that buffer as well as the length to the SendOverDma function which configures the DMA transfer:
SendOverDma(char * buffer, uint32_t length)
{
uint32 sciTxData;
g_dmaCTRL g_dmaCTRLPKT1;
/*Initialize SCI*/
sciInit();
while (((sciREG->FLR & SCI_TX_INT) == 0U) || ((sciREG->FLR & 0x4) == 0x4))
{
} /* Wait */
/*Assign DMA request SCI transmit to Channel 0*/
dmaReqAssign(DMA_CH0, DMA_REQ);
sciTxData = ((uint32_t)(&(sciREG->TD)) + 3);
/*Configure control packet for Channel 0*/
g_dmaCTRLPKT1.SADD = (uint32_t)buffer; /* source address */
g_dmaCTRLPKT1.DADD = sciTxData; /* destination address */
g_dmaCTRLPKT1.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT1.FRCNT = length; /* frame count */
g_dmaCTRLPKT1.ELCNT = 1; /* element count */
g_dmaCTRLPKT1.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT1.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT1.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT1.FRSOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT1.PORTASGN = 4;
g_dmaCTRLPKT1.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT1.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT1.TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_OFF; /* autoinit */
/*Set control packet for channel 0 and 1*/
dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT1);
/*Set dma channel 0 to trigger on hardware request*/
dmaSetChEnable(DMA_CH0, DMA_HW);
/*Enable DMA*/
dmaEnable();
/*Enable SCI Transmit and Receive DMA Request*/
sciREG->SETINT = (1<<16);
}
If consecutive calls are too close to one another in time, then I typically only see the last string get fully transferred, and only one garbled character from the previous message. Am I setting up the DMA transfers incorrectly? Do I need to buffer the messages? Should I wait for an event before transmitting a new message? I thought the following takes care of the waiting:
while (((sciREGx->FLR & SCI_TX_INT) == 0U) || ((sciREGx->FLR & 0x4) == 0x4))
{
} /* Wait */
Please help me figure out what's wrong. Thanks in advanced for you help!
