LPC546xx SPI Rx Errors while using DMA

cancel
Showing results for 
Search instead for 
Did you mean: 

LPC546xx SPI Rx Errors while using DMA

91 Views
eileen_radzwion
Contributor II

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

Labels (1)
0 Kudos
6 Replies

25 Views
eileen_radzwion
Contributor II

Hi @xiangjun_rong , 

Did you have a chance to consider my reply?  

Thanks

0 Kudos

55 Views
eileen_radzwion
Contributor II

Hello Xiangjun,

I am using the input pin to trigger the transfer.  The ADC we are using is   AD7770ACPZ

eileen_radzwion_0-1613993243435.png

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:   

  1. FAST_ADC_DRDY_0 - this is the signal that goes to an input pin and is used to generate the interrupt.  
  2. FAST_ADC_SYNC - this (with the reset) is an effect reset and sync to the chip.  it is used during startup.  it is a LPC54608 GPIO output
  3.  FAST_ADC_CLOCK - this is the sampling clock for the chip.  it comes from the LPC54608's CLOCKOUT that is generated from the audioPLL.  its running at 5.12MHz
  4. RESET_ADS124S08 - GPIO output that works with the sync to reset the adc chip.

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 );

0 Kudos

74 Views
frank_meyer
Contributor IV

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 ?

 

0 Kudos

43 Views
eileen_radzwion
Contributor II

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  

Tags (1)
0 Kudos

39 Views
frank_meyer
Contributor IV

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.

78 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

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

0 Kudos