What I'm trying to do: Send a 16byte packet out of SSI1 using DMA Channel 11 on a TM4C1294NCPDT MCU.
What happens:
A burst of data is seen equal to ARBSIZE and the data is correct. Then nothing. If ARBSIZE is changed the burst size seen changes to match it. Can anybody see why the DMA doesn't continue after the first burst?
In IAR EW, if I halt the program, the DMASTAT register STATE shows the DMA controller stalled at the 0x06 state, which means 'Waiting for μDMA request to clear.' If I manually set and reset the TXDMAE bit in the SSICMACTL register I can eject the rest of the data from SSI1 Tx, which is also correct data. After the correct number of data bytes for the DMA transfer the transfer ends and STATE in the DMASTAT register shows the DMA controller halted at an 0x01 state, as expected.
What I've tried:
If I write an IRQ service routine to reset and set the TXDMAE bit each time it gets called I can get the SSI1 TX to send the complete 16 byte packet but it causes the routine to be continuously called and it's not the right way to solve the problem. It's the first time I've used DMA and I'm expecting to be able to set up transfer that will happen in the background and not have to service it before it completes.
What I think is going on:
I think I have a setup problem here but I can't spot it. I've been through the registers and looked at their settings and they check out. I 'think' that for some reason that SSI1 doesn't continue the DMA for a reason I can't see.
It's written in assembler, and before somebody says it, I don't have any interest in 'C'. I have looked at some of the TIVAware DMA setup routines but they make little sense to me.
I can post code if it helps, but here's what happens in order of execution in English:
SSI1 module initialised as a master. (This works fine for polled and and interrupt based transfers) The TX FIFO is enabled.
DMA module enabled - RCGCDMA Bit0 = 1
DMA controller reset using SRDMA
Wait for DMA controller to be available by polling PRDMA
Enable DMA controller - DMACFG = 1
Program channel control table base address using DMACTLBASE aligned to a 1024byte boundary in RAM.
DMA channel 11 assigned to SSI1 TX - DMACHMAP1 Bits 12:15 = 0x01
Set DMA Channel 11 to default priority - DMAPRIOCLR Bit11 =1
Enable DMA Channel 11 primary control structure - DMAALTCLR Bit 11 = 1
Enable single and burst requests for the channel - DMAUSEBURSTCLR Bit11 =1
Allow µDMA controller to recognize requests for channel 11. - DMAREQMASKCLR Bit 11 = 1
DMA Channel 11 DMA_SOURCE_END_POINTER is set to the last byte to be sent (16byte buffer - 1)
DMA_CHANNEL 11 DMA_DESTINATION_END_POINTER is set to SSI1 data register as the DMA destination is not incremental
DMA control word setup:
Destination address increment = 0x03 = address not incremental
DSTSIZE. Destination data size = 0x0 =8bit.
SRCINC. Source address increment. = 0x0 =8bit.
SRCSIZE Source data size. 0x0 = 8bit.
Bits 22:23 reserved. Set to 0
DSTPROT0. Bit21 = 0 = The write access is non-privileged.
Bits 20:19 reserved. Set to 0
SRCPROT0. Bit18 = 0 = The write access is non-privileged.
ARBSIZE = 0x02 = 4 to match FIFO level.
XFERSIZE =15 = transfer 16 items
NXTUSEBURST Bit3 = 0
XFERMODE = #0x1 = Basic mode
Enable DMA channel DMAENASET = 1
Enable DMA for SSI1 TX FIFO in SSI1 module, TXDMAE in SSIDMACTL set to 1
Enable TX DMA IRQ (DMATXIM) for QSSI1. In DMATXIM in SSIIM is set to 1