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!