LPC824 ADC with DMA example?

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

LPC824 ADC with DMA example?

1,577 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdesbonnet on Mon Jun 15 09:07:09 MST 2015
I need to read from the LPC824 ADC at close to the maximum sample rate.  I'm using SCT0_OUT3 to trigger a sampling operation at regular intervals. My target rate is 480ksps (only one ADC channel needed). I'm currently using an ADC interrupt handler to copy the ADC data register into a SRAM buffer but I can't reach that sampling speed with that approach (ISR works at 240ksps, but at 320ksps it misses every second sample).

I guess ADC data direct to SRAM using a DMA channel would be ideal. But the setup seems rather complex, and I can't find any examples. Any pointers would be great.

Also any other suggestions for achieving the same thing? (I'm currently reading about ADC burst mode, but it's not clear if I can achieve regular sampling from SCT0_OUT3 with that approach).

Thanks,

Joe
Labels (1)
0 Kudos
3 Replies

807 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdesbonnet on Thu Jul 16 13:42:06 MST 2015
I've got an example of reading the ADC with DMA on LPC824 in this GitHub repository:
https://github.com/jdesbonnet/LPC824_ADC_DMA_example
0 Kudos

807 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdesbonnet on Sun Jul 05 10:22:55 MST 2015
I think I've cracked it. I'll try to post an example to GitHub in the coming days... but in the mean time, if anyone needs some sample code to read from ADC to memory using DMA let me know.
Joe.
0 Kudos

807 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdesbonnet on Sat Jun 20 08:54:21 MST 2015
I'm making some very slow headway in this. I'm currently able to get basic DMA functionality working. For example I've been able to read the SCT counter register really fast and see successive reads increment by only two clock cycles. However I'm still stuck on the ADC.

I can get it to read the data register of the ADC, but it does so way way too fast. I'm trying to get the ADC sampling triggered on what would normally be the SEQA interrupt (I'm using SCT0_OUT3 to generate the ADC start of sequence trigger). I think I'm going wrong with the DMA trigger multiplexer. This is what I'm trying but not working:

Chip_DMATRIGMUX_SetInputTrig(LPC_DMATRIGMUX, DMA_CH0, DMATRIG_ADC_SEQA_IRQ);


Here is all my DMA setup code (adapted from the memory to memory example):

// Setup DMA for ADC

/* DMA initialization - enable DMA clocking and reset DMA if needed */
Chip_DMA_Init(LPC_DMA);
/* Enable DMA controller and use driver provided DMA table for current descriptors */
Chip_DMA_Enable(LPC_DMA);
Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));

/* Setup channel 0 for the following configuration:
   - High channel priority
   - Interrupt A fires on descriptor completion */
Chip_DMA_EnableChannel(LPC_DMA, DMA_CH0);
Chip_DMA_EnableIntChannel(LPC_DMA, DMA_CH0);
Chip_DMA_SetupChannelConfig(LPC_DMA, DMA_CH0,
(DMA_CFG_HWTRIGEN
| DMA_CFG_TRIGTYPE_EDGE
| DMA_CFG_TRIGPOL_HIGH
| DMA_CFG_BURSTPOWER_1
 | DMA_CFG_CHPRIORITY(0)
 ));

// Attempt to use ADC SEQA to trigger DMA xfer
Chip_DMATRIGMUX_SetInputTrig(LPC_DMATRIGMUX, DMA_CH0, DMATRIG_ADC_SEQA_IRQ);

DMA_CHDESC_T dmaDesc;

/* DMA descriptor for memory to memory operation - note that addresses must
   be the END address for src and destination, not the starting address.
     DMA operations moves from end to start. */
dmaDesc.source = DMA_ADDR ( (&LPC_ADC->DR[3]) ); // ADC channel 3 data register is source
dmaDesc.dest = DMA_ADDR(&dst[SIZE_BUFFERS - 1]) + 3;
dmaDesc.next = DMA_ADDR(0);

/* Enable DMA interrupt */
NVIC_EnableIRQ(DMA_IRQn);

/* Setup transfer descriptor and validate it */
Chip_DMA_SetupTranChannel(LPC_DMA, DMA_CH0, &dmaDesc);
Chip_DMA_SetValidChannel(LPC_DMA, DMA_CH0);

/* Setup data transfer and software trigger in same call */
// See "Transfer Configuration registers" table 173 §12.6.18 page 179
Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0,
 (
DMA_XFERCFG_CFGVALID  // Channel descriptor is considered valid
| DMA_XFERCFG_SETINTA //
| DMA_XFERCFG_SWTRIG  // When written by software, the trigger for this channel is set immediately.
| DMA_XFERCFG_WIDTH_32 // 8,16,32 bits allowed
| DMA_XFERCFG_SRCINC_0 // do not increment source
| DMA_XFERCFG_DSTINC_1 // increment dest by widthx1
| DMA_XFERCFG_XFERCOUNT(SIZE_BUFFERS)
)
);

0 Kudos