Hello,
I am using the LPC54608 controller and have configured Flexcomm 5 interface for SPI communication in master mode. The RX FIFO is emptied by the DMA controller, which is triggered for a transfer by an external pin (burst mode is enabled for a transfer of 32 bytes upon each pin interrupt). Therefore, the "source" address for the DMA transfer is the SPI's RX FIFO. The "destination" address of the transfer is in the EMC's address range.
For your reference, the SPI interface is connected to an external 8-channel ADC, the external pin that triggers the transfer is a data ready input for reading all channel's data (8-chan *4B/chan = 32Bytes). For generating the SPI interface clock, and due to the data rates, we are using the Audio PLL at a frequency of 5.12 MHz.
This entire process of SPI->DMA->EMC (SDRAM) works for a period of time (ranges from 30mins to 8 hours) as configured. Then, the SPI status register begins indicating an Rx FIFO Error, which indicates the FIFO is overflowing, and, since this is being emptied by the DMA controller, that the DMA controller is not emptying it fast enough.
Unfortunately, there's not much available regarding the status of the DMA controller itself. I can see the triggers are still occurring, and that there are no errors for the channel (channel 10). Nor is there any ability to increase the DMA contoller's clock (SYS clock is at 180MHz).
Can you direct me to where I can look to identify what happens, and why the FIFO is no longer getting emptied fast enough?
Thanks,
Eileen
Hello Xiangjun,
I am using the input pin to trigger the transfer. The ADC we are using is AD7770ACPZ
The 4 yellow signals at the bottom are part of the SPI interface (I can share the specific pins if needed, but they are configured correctly for SPI). The other 4 signals are:
The hardware triggering off the pin interrupt is configured as such:
INPUTMUX_AttachSignal( INPUTMUX, kPINT_PinInt0, kINPUTMUX_GpioPort0Pin1ToPintsel);
INPUTMUX_AttachSignal( INPUTMUX, DMA_FC5_RX_CHANNEL, kINPUTMUX_PinInt0ToDma);
INPUTMUX_AttachSignal( INPUTMUX, DMA_FC5_TX_CHANNEL, kINPUTMUX_PinInt0ToDma);
PINT_PinInterruptConfig( PINT, kPINT_PinInt0, kPINT_PinIntEnableFallEdge, NULL );
You see it is used to trigger both tx and rx. Tx is only triggered to generate the spi clock. The priorities are then set:
DMA_SetChannelPriority( DMA0, DMA_FC5_TX_CHANNEL, kDMA_ChannelPriority1 );
DMA_SetChannelPriority( DMA0, DMA_FC5_RX_CHANNEL, kDMA_ChannelPriority0 );
The channel configuration registers are set to use a hardware trigger:
trigger.burst = kDMA_EdgeBurstTransfer32;
trigger.type = kDMA_FallingEdgeTrigger;
trigger.wrap = kDMA_NoWrap;
DMA_SetChannelConfig( DMA0, DMA_FC5_RX_CHANNEL, &trigger, true );
DMA_SetChannelConfig( DMA0, DMA_FC5_TX_CHANNEL, &trigger, true );
Hi, Eileen,
I have checked the hardware connection, I think it is okay.
Regarding the cause that the SPI status register begins indicating an Rx FIFO Error, which indicates the FIFO is overflowing after the DMA has worked fine for some time(several hours), I think it is difficult to track the cause.
This is another solution that you do not use FAST_ADC_DRDY_0 to trigger DMA, in the case, you do not need to modify any hardware signal connection, just modify firmware. You can use DMA request to request DMA transfer by setting the DMARX bit in FIFOCFG reg, when the SPI FIFO receive full happens, DMA will be requested automatically, this can avoid the phenomenon you faced.
Another solution is to keep current design, but you can enable the Rx FIFO Error interrupt, when the error happens, in the ISR, you can stop SPI transfer, reinitialize SPI and DMA, restart SPI and DMA.
Hope it can help you
BR
XiangJun Rong
Hi, Eileen,
Sorry for the delay, I will look into the data sheet of AD7770ACPZ, give you a reply before the Monday next week.
BR
Xiangjun Rong
Just an idea...
While DMA does not need the core, it needs the bus. Do you have another routine/process that might block the bus to the SDRAM ?
Like a routine performing periodical calculations over the gathered values, or saving them to mass storage ?
Hi Frank,
Thank you so much for the idea! To test this out, I thought I'd stop all other tasks reading and writing to the SDRAM, to see if this had an effect. Unfortunately, it did not - it didn't seem to make a difference at all, with the SPI Rx Errors starting to increment about 30mins after running. Do you see an obvious flaw in this test, maybe? Or if you have any other ideas, I'd love to hear them.
Thanks again,
Eileen
Such delayed problems are usually not so easy to debug, and sometimes tend to fall into the Heisenberg category.
But often, such errors are related to stack overflows, out-of-bound access (arrays), or race conditions. Especially race conditions with interrupts are sometimes quite elusive.
Perhaps you could instrument you code to toggle IO signals on entry/exit of routines supposedly involved, and watch them with a scope or logic analyzer . A proper (scope) trigger at the error condition would give you a visual signal representation of the application behaviour at the critical point.
But by instinct, I would consider to change the ADC DMA destinationto SRAM, and either move them manually to SDRAM, or by another DMA. Internal SRAM is faster, and has 32-bit width.
Hi, Eileen,
I would like to confirm which source triggers the DMA transfer.
case 1: the spi ADC device has an output pin, it is connected to Pin interrupt pin, it triggers the DMA transfer.
Case 2: You use the DMA channel 10 (Flexcomm Interface 5 RX / I2C Slave) to request the DMA transfer
Pls check, if you use case 1, can you give the external SPI ADC part number and connection?
If you use case 2, I think we have to find out a workaround.
BR
XiangJun Rong