I've got a DMA channel feeding interleaved data from a single buffer to both I2S transmit FIFO registers. The buffered values are 32-bit words. It works fine if I set it up with DMOD set for an 8-byte circular buffer (namely the two FIFO registers) and set SOFF = 4. One word goes to the first FIFO, the next to the second FIFO, and then DADDR loops back to the first FIFO. Four words are sent to each FIFO for each DMA request.
The trouble is that the natural ordering of the buffered data has it interleaved in groups of 3 words, e.g. AAABBBAAABBB. The above solution needs it in ABAB order. My plan was to try using the minor loop offset rather than DOFF to alternate destination registers. However, it appears that MLOFF doesn't honor the DMOD modulo setting, which results in it running off and trashing the I2S module's registers until it runs off the end of its memory area and generates a bus fault.
Am I doing something wrong, or is that just how the minor loop offset works? Is there more detailed documentation on its operation? I've been over the DMA section in the K22F1M0's reference manual several times and I can't find anything that would suggest that the modulo mode shouldn't still apply.
This is not a big deal in this case. The code that generates the data to be sent doesn't take a serious efficiency hit to write it in ABAB order, it's just an architectural issue since that code is supposed to be generic across multiple projects. I was previously using separate buffers and separate DMA channels, which also required reordering the data. It looks like I could go back to using separate channels and point them to the same buffer, one channel offset by 3 words, and use the minor link offset on the source address to skip the other channel's data. Using a single channel and changing the sample format reduced the load on the DMA controller by something like 250,000 requests/second, and that's a bigger deal than the code reuse issue. I'm just trying to understand why it's doing what it's doing.