I am developing a USB audio device using a Kinetis K20D7 MCU. My application has an isochronous IN endpoint for transmitting sync data back to the host (which tells it how fast to send audio frames). The sync data is stored in a uint32_t:
uint32_t usb_audio_sync_feedback = 786432; // 48 << 14;
I have 2 buffer descriptor table entries, one for each of the TX buffers (odd and even). Each entry is identical and the following descriptor bits are set:
OWN = 1. Buffer is owned by USB-FS.
KEEP = 1. USB-FS should not change ownership after a transaction - I want the USB controller to read from the `usb_audio_sync_feedback` variable each time, without triggering an interrupt.
NINC = 1. Don't increment the DMA address after each transaction.
And the address points to `usb_audio_sync_feedback`. Code:
bdt[BDT_INDEX(1, TX, EVEN)].descriptor = (3<<16) | BD_OWN_MASK | BD_KEEP_MASK | BD_NINC_MASK;
bdt[BDT_INDEX(1, TX, EVEN)].address = &usb_audio_sync_feedback;
bdt[BDT_INDEX(1, TX, ODD)].descriptor = (3<<16) | BD_OWN_MASK | BD_KEEP_MASK | BD_NINC_MASK;
bdt[BDT_INDEX(1, TX, ODD)].address = &usb_audio_sync_feedback;
I expected the same value of 786432 to be sent on each transaction however only one IN transaction is processed correctly before I get an error interrupt with USB0->ERRSTAT bit 5 set which corresponds to DMAERR.
This seems to indicate that the USB controller has requested DMA access to `usb_audio_sync_feedback` but has been unable to acquire it before the data was due to be sent.
What could be stopping the USB controller from getting DMA access?