I want to interface an SD/MMC card using SPI interface. on teh 1611 I had no problems doing so by manually servicing the hardware SPI.
On the 5438 I want to use the DMA feature at least for the 512 byte block transfers, so transfers are executed as fast as possible and maybe completely in the background. After all, this is what DMA was designed for. And with the SPI hardware running at MCLK, it takes only 8 MCLK cycles to transfer a single byte.
Whil is is possible to write hand-optimized code that can feed the SPI at the desired speed, this code would fail if teh SPI speed is lower than MCLK. On the other side, any code that actually checks for the transmit/receive IFGs (and even more using an ISR for this job) would be significantly slow down teh transmission (in case of an ISR by a magnitude). This is where DMA comes to play.
BUT
Usage of the DMA controller is explained very poorly in the documentation. All information is spread over many different locations and seems to be incomplete. Also, my experiences with typos and wrong data due to copy/paste errors or whatever, made me question the correctness of any information I find in the datasheets. So if something does not work as intended, question is: is it my code or is it a typo in the datasheet?
The actual problem is the following: I set up the DMA controller and SPI as required by the datasheet, and nothing happens. No DMA is triggered.
When I set the DMA trigger to manual trigger (DMAREQ), check the SPIs IFGs manually (no, interrupts are not enabled - I found a small sentence somewhere stating that this will prohibit DMA triggering, and I don't use ISRs for SPI anyway) and then set DMAREQ, the transfers are executed as expected. Albeit sloooow of course.
I tried using USCI0A, 0B, 1A, all to no avail. I also tried (with USCI0B) all 32 triggers, also nothing worked.
The trigger table (when searching for MSP and DMA at TI and though the internet, I always found exactly the same table, has any device a different one?) does not list DMA triggers for USCI2 and 3 at all. Is it not possible to do DMA with them?
Posting my code would be of no use, as it is modular and spreads over several header and code files. But here is the basic setup:
DMA channel 0: source = (UCxy)RXBUF, destination = memory buffer, size=512, DMA0CTL=DMASBDB|DMADSTINCR_3|DMADT_SINGLE
DMA channel1: source = memory buffer+1, destination= TXBUF, size=511, DMA1CTL=DMASBDB|DMASRCINCR_3|DMADT_SINGLE
I make a dummy read from RXBUF to clear RXIFG, then set the DMAEN bits for both channels.
the transfer is started by writing the content of TX memory buffer to TXBUF. This clears and re-sets TXIFG After it has been transfered, RXIFG is flagged and nothing happens. No matter which triggers I set in DMACTL0.
I tried to manually trigger DMA channel 1 (TX) to test various triggers for channel 0 (RX) , but it gets never triggered when the first byte arrives in RXBUF and RXIFG is set.
The documentation only talks about I2C and DMA. Does this mean that DMA is only possible for I2C? But then, USCIAx does not have I2C, yet there are triggers for it listed in the trigger table.
So the question remains: how do I make USCIA/B0/1/2/3 RX/TXIFG trigger an DMA transfer?
In the last years, I wrote a LOT of low level code for several MSPs, Atmels and PICs, but this one is really killing me. And since this is DMA, neither debugging code nor a debugger is of any help. Perhaps an electron microscope... ;)