Is there a description somewhere of the I2S driver's buffer handling and status callbacks? I'm working on porting an audio processing project from Kinetis to the LPC55S69 and on Kinetis I was using my own I2S DMA driver and I need to figure out which pieces of my driver I can replace with the MCUX SDK driver - or if I should just skip it and adapt my own driver to the new hardware.
From what I can tell from the sparse SDK docs, it looks like the driver has a queue that takes I2S_NUM_BUFFERS (4) entries. It doesn't mention any size limits so I'm assuming that queue is just taking four pointers.
All of the provided example projects use only a single, fixed buffer. They'll queue the same buffer twice in a row to avoid gaps in the playback, but they don't illustrate how to manage multiple buffers. The loopback examples have the sender and receiver using the same buffer, so the contents are changing, but there's no synchronization mechanism of any kind - they simply rely on the fact that both are clocked together and won't ever pause or experience desynchronization. The demos only change the contents, not the buffer being sent, which isn't safe for most real-world applications.
There's a callback of i2s_transfer_callback_t, which provides a parameter "completionStatus" of type status_t, but status_t is simply typedef'd to int32_t with no documentation of the values it can return.
There is an anonymous enum with BufferComplete, Done, and Busy values - but nothing to explicitly that these are used in the callback. I'm assuming these are the values for status_t and that BufferComplete means a single buffer has been sent, and Done means all of them are done. It'd be nice to know in advance if the final buffer generates both a BufferComplete and a Done, or if it's just Done.
That's provided in the basic I2S driver. In the I2S_DMA driver there's a separate I2S_DMACallback. It doesn't appear to be documented at all in the manual. From the code, it looks like this is strictly an internal function used by the ISR. Is that correct? Is there some way to distinguish in the SDK docs what's an exported function and what's only used internally? Or maybe exclude the internal stuff entirely if it's not relevant?
I assume the completion callback happens when the DMA transfer completes? Or is there a callback when the I2S FIFO empties? My application doesn't normally send audio continuously so I need to know when to shut down the I2S transmitter without cutting off the last transmission. (Kudos to the hardware designers for letting you select whether an idle I2S transmitter sends zeroes or repeats the last value - that's one of those little touches that really makes things easier. I have applications that need it both ways.)
Edit: My main concern right now is figuring out with certainty which buffer just completed. The callback doesn't seem to specify, the user data is associated with the handle and not the individual transfer, and the DMA handle data is private. First in, first out is an obvious assumption but I'm trying to avoid the possibility of buffer desynchronization if a transfer is aborted or something.
Thanks,
Scott