LPC546xx SPI Rx Errors while using DMA

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC546xx SPI Rx Errors while using DMA

1,361 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
8 Replies

1,295 Views
eileen_radzwion
Contributor II

Hi @xiangjun_rong , 

Did you have a chance to consider my reply?  

Thanks

0 Kudos

1,325 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

1,227 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

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

0 Kudos

1,233 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

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

0 Kudos

1,345 Views
frank_m
Senior Contributor III

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

1,314 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

1,310 Views
frank_m
Senior Contributor III

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.

1,349 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