PIC32MZ USB DMA doesn't fill buffer when doing step by step
Controller : PIC32MZ2048EFH
IDE : MPLABX 3.6
Compiler XC32
Language : C
Hi !
I'm developing an optical powermeter that reads an ADC and sends data to a PC via High Speed USB. The USB communication works well right up until the DMA takes the DATA from the endpoint FIFO and tries to put it in the input buffer. At this point the first command that is sent to the PIC from the PC, a test command to toggle the LEDs, works and the LEDs light up. The second command (toggle LEDs again) is received and processed, but when the endpoint Read Callback routine is called, the input data buffer that is analyzed by software is empty.
As I'm trying to debug this, the outcomes change. If I go step by step for the first command in the USB ISR (where the DMA transfer is enabled), once I get to the Callback routine, the data buffer is empty, but if I let the program roll (as explained before) the buffer has the command data and the software turns on the LEDs . Also, if I put breakpoints in the USB ISR and don't check the values of the variables the first
toggle LEDs command is OK, but if I let the Variables or my Watches load, the buffer comes out empty.
Has anyone experienced this kind of behavior while debugging DMAs or USB communication? Both the USB and DMAs use interrupt routines, which are working (they are called at the right times in the code leading to this error). Below is the function used to enable the DMA transfer, since the first command works when not in step by step, I don't think the error is here, but then again. The way I see it it seems to be a timing error between the FIFO and the DMA ..
Thank you in advance!
- DC
void _USB_DMA_Enable
(
USB_DMA_CHANNELS channel,
uint8_t endpoint,
uint8_t * address,
uint32_t count,
bool direction
)
{
volatile uint32_t reg;
*(&USBDMA1A + (channel-1)*0x4) = ((uint32_t)(address) & 0x1fffffff);
*(&USBDMA1N + (channel-1)*0x4) = (uint32_t)(count);
reg = (uint32_t) 0x608; // BRSTM = 3, IE = 1, MODE = 0
reg |= ((uint32_t)endpoint)<<4;
reg |= ((uint32_t)(direction))<<1;
*(&USBDMA1C + (channel-1)*0x4) = reg;
*(&USBDMA1C + (channel-1)*0x4) |= 1; // DMA EN
}