SSP & DMA

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

SSP & DMA

1,211 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Thu Mar 20 12:12:36 MST 2014
Hi,

here's what I want to do, but I'm not use how to do it and if it's even possible to do it...

- Acquire a 16bit sample at a specific sampling rate from an ADC using a SPI link.
- Use the DMA to achieve that.

If my understanding if correct, I could setup a DMA channel in P2M mode using the SSP1 RX peripheral to achieve that. Since I must respect a specific sampling rate, it would be great if I could trigger the transfer from a timer (matching).

Is it possible to connect the DMA to the SSP1 RX, but to use the Timer1 match 1 to trigger the transfer periodically ??

What are my options ?

Thanks !
Labels (1)
0 Kudos
Reply
8 Replies

1,072 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by danny_com on Tue Apr 12 07:18:38 MST 2016
Hi,

Could you resolve the automatic aquisition of 500KSPS using DMA?
If so could you explain me how you resolve your problem, I need to acquire at 100kSPS and save data on SD and I am loosing data because the acquistion is not too fast.

Thanks!
0 Kudos
Reply

1,072 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Tue Mar 25 13:19:22 MST 2014
Yeah, I started trying to do this on the M0 core. I tested with a naked application on the M4 core and time-wise, everything is fine. Now I want to build it as a M0 application and start the acquisition from my M4, but I can't seem to make it build.

Is there any dual-core examples using IAR???

I've created a new thread for this:
http://www.lpcware.com/content/forum/dual-core-examples-using-iar
0 Kudos
Reply

1,072 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rocketdawg on Tue Mar 25 10:35:16 MST 2014
Yea, CS controls conversion.
I have never used it, but there is Frame Mode.  Not sure how it works or if it will work for you.
or use the M0 core to do the work
or worst case is hack AN11210

perhaps contact NXP Field Engineer
0 Kudos
Reply

1,072 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Mon Mar 24 18:11:57 MST 2014
That's the ADC I had in mind of using...

http://www.ti.com/lit/ds/symlink/ads7947.pdf

I think the only possible approach would be large transfers via DMA. But I'm not sure how to set this up, because the CS must toggle to start a new conversion. I don't know how the DMA will handle that on the SSP. I would assume that if my transfer size if 100000 for example, it will put the CS down at the first sample, transfer 100000 samples and then put CS back high?
0 Kudos
Reply

1,072 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rocketdawg on Fri Mar 21 10:46:15 MST 2014
maybe post a link to the device datasheet?
if the device will continuously sample, then make a big buffer and transfer a large number of samples via DMA
if it needs some sort of command sequence for each sample, then create a DMA with a TX and RX buffer, with the TX buffer filled with the (command + dummy bytes) * number of samples requested
if it can not, then you will have to work out the numbers.  interrupting at 500khz for each single sample DMA will place a large burden on the CPU.
0 Kudos
Reply

1,072 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Fri Mar 21 09:27:44 MST 2014
Just to be clear, like rocketdawg said :


Quote:
you have an external ADC device connected to the uC via SPI.
you want a periodic sample based upon a timer.
The DMA is between a peripheral (SPI) and RAM



But, I want it fully automatic. When I start the trigger (configured to reset on matching interrupt and to continue), I want it to periodically acquire all the samples from the SSP without any interrupts, except the last one indicating that DMA is complete.

The more I try and read, the more it feels like I'll need to implement the timer ISR and to execute a DMA enable at each interrupt, but ideally, that's not what I want.

Is it possible?

PS: the reason I want it fully automatic is because my sampling rate is quite high (500k samples per sec (12bits, but considered 16 for the SPI), SPI SCLK at 10MHz. So that leaves me ~400ns to do stuff in between samples, which is not that big...)
0 Kudos
Reply

1,072 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Fri Mar 21 07:46:00 MST 2014
Ok I checked the example you proposed, but I'm not really using LPCOpen, so tried to understand it more than copy it. Also based on other examples I found. So to test it up, I made a mem-2-mem DMA working fine. It was triggered by the GPDMA_ChannelCmd(0, ENABLE) call. After that, I decided to to do the same, but to trigger the transfer from a Timer match. So, using Timer 1 Match register 1, I tried to do this.

I know that my trigger works, because I break in the matching interrupt. But it doesn't start the DMA transfer.


// Init buffers
for (u32Idx = 0; u32Idx < DMA_SIZE; ++u32Idx)
{
g_bufferSrc[u32Idx] = u32Idx;
g_bufferDest[u32Idx]= 0;
}

Channel0_TC = 0;
Channel0_Err = 0;

NVIC_DisableIRQ(DMA_IRQn);
NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01));

GPDMA_Init();

LPC_GPDMA->CONFIG = 1;// enable the GPDMA controller
LPC_GPDMA->SYNC &= ~(1<<4);        // enable synchro

    LPC_GPDMA->C0SRCADDR  = (uint32_t) &g_bufferSrc[0];
    LPC_GPDMA->C0DESTADDR = (uint32_t) &g_bufferDest[0];//(LPC_DAC->CR);
    LPC_GPDMA->C0LLI      = 0; // linked lists for ch0
    LPC_GPDMA->C0CONTROL  = DMA_SIZE   // transfer size (0 - 11) = 64
                            | (0 << 12)            // source burst size (12 - 14) = 1
                            | (0 << 15)            // destination burst size (15 - 17) = 1
                            | (1 << 18)            // source width (18 - 20) = 32 bit
                            | (1 << 21)            // destination width (21 - 23) = 32 bit
                            | (0 << 24)            // source AHB select (24) = AHB 0
                            | (1 << 25)            // destination AHB select (25) = AHB 1
                            | (1 << 26)            // source increment (26) = increment
                            | (1 << 27)            // destination increment (27) = increment
                            | (0 << 28)            // mode select (28) = access in user mode
                            | (0 << 29)            // (29) = access not bufferable
                            | (0 << 30)            // (30) = access not cacheable
                            | (1 << 31);           // terminal count interrupt disabled

    LPC_GPDMA->C0CONFIG   =  0   // channel disabled (0)
                            | (0 << 1) // source peripheral (1 - 5) = none
                            | (4 << 6)// destination peripheral (6 - 10) = Timer 1 Match 1
                            | (1 << 11)// flow control (11 - 13) = mem to per
                            | (1 << 14)// (14) = mask out error interrupt
                            | (1 << 15)// (15) = mask out terminal count interrupt
                            | (0 << 16)// (16) = no locked transfers
                            | (0 << 18);// (27) = no HALT


GPDMA_ChannelCmd(0, ENABLE);
NVIC_EnableIRQ(DMA_IRQn);
TIM_Cmd(LPC_TIMER1, ENABLE);

while ((Channel0_TC == 0) && (Channel0_Err == 0));

0 Kudos
Reply

1,072 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rocketdawg on Thu Mar 20 13:05:18 MST 2014
you have an external ADC device connected to the uC via SPI.
you want a periodic sample based upon a timer.
The DMA is between a peripheral (SPI) and RAM

what starts the DMA is up to you, and a timer ISR will work fine.
The DMA complete ISR will let you know when it is finished.

you probably should have some checking in the timer ISR to determine if the DMA really completed and if so, it starts up a new DMA.
it should also check for any SPI faults and correct them.

a simplistic sample exists in LPCOpen for the 43xx series.
0 Kudos
Reply