Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN
I am working with MibSPI and HW triggered DMA (wihtout Interrupts/ISR) on TMS570LC4357. I have one dedicated DMA channel fixed to one Mibspi. There are cases where I have to send varying length of MibSPI TX messages using DMA. For changing the length of MibSPI transmission, I play with the Transfer Group Start and End address. But to change the DMA lenght (and sometimes the Source Address of the different buffers), I am not sure what has to be changed.
I have tried changing the dmaRAMREG->PCP[dmaChannel].ITCOUNT and dmaRAMREG->PCP[dmaChannel].ISADDR but changing them only works for some cycles after which the DMA stops working completely. In this case, MibSPI transmits the outdated values.
As an example, this is the MibSPI DMA config I have for MibSPI1:
"
/* Register TX DMA */
g_dmaCTRL g_dmaCTRLPKTSPITx = {0};
g_dmaCTRLPKTSPITx.SADD = (uint32)(au16_txDPRAMSPIData1); /* source address */
g_dmaCTRLPKTSPITx.DADD = (uint32)&(mibspiRAM1->tx[0].data); /* destination address */
g_dmaCTRLPKTSPITx.CHCTRL = 0; /* channel control */
g_dmaCTRLPKTSPITx.FRCNT = 1; /* frame count */
g_dmaCTRLPKTSPITx.ELCNT = MAX_SPI_TX_BUFFER_SIZE; /* element count */
g_dmaCTRLPKTSPITx.ELDOFFSET = 4; /* element destination offset */
g_dmaCTRLPKTSPITx.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKTSPITx.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKTSPITx.FRSOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKTSPITx.PORTASGN = PORTA_READ_PORTB_WRITE;
g_dmaCTRLPKTSPITx.RDSIZE = ACCESS_16_BIT; /* read size */
g_dmaCTRLPKTSPITx.WRSIZE = ACCESS_16_BIT; /* write size */
g_dmaCTRLPKTSPITx.TTYPE = FRAME_TRANSFER ; /* transfer type */
g_dmaCTRLPKTSPITx.ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKTSPITx.ADDMODEWR = ADDR_OFFSET; /* address mode write */
g_dmaCTRLPKTSPITx.AUTOINIT = AUTOINIT_OFF; /* autoinit */
/* Setting DMA control packets */
dmaSetCtrlPacket(DMA_CH16, g_dmaCTRLPKTSPITx);
/* - setting the dma channel to trigger on h/w request */
dmaSetChEnable(DMA_CH16, DMA_HW);
/* Assign Req ID */
dmaReqAssign(DMA_CH16, DMA_REQ1);
uint32 bufid = MAX_SPI_TX_BUFFER_SIZE - 1;
uint32 icount = 0;
uint32_t txchannel = 0UL;
/* setting transmit channels */
mibspiREG1->DMACTRL[0] |= (txchannel) << 16);
/* enabling transmit dma */
mibspiREG1->DMACTRL[0] |= 0x80004000;
/* setting Initial Count of DMA transfers and the buffer utilized for DMA transfer */
mibspiREG1->DMACTRL[0] |= (bufid<<24);
mibspiREG1->DMACNTLEN = 0x1;
mibspiREG1->DMACOUNT[0] = (MAX_SPI_TX_BUFFER_SIZE - 1) << 16;
/* Enable DMA module via HALCoGen driver. */
dmaEnable();
"
where MAX_SPI_TX_BUFFER_SIZE is 128. I trigger the HW DMA using "dmaSetChEnable(DMA_CH16, DMA_HW);".
I only use Transfer Group 0 of MibSPI1 and don't intend to use MibSPI1 Extended buffer.
I change the Length and the Buffer Source Address for the dmaRAMREG->PCP every 10ms. I would also like to use this variable DMA transfer for compatibility mode SPI with HW Triggered DMA (non-Interrupt), SCI and other interfaces also.
I have gone through the examples and other questions on this forum but none were able to solve this issue.
How do I achieve variable length DMA transfer?