SPI and DMA

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

SPI and DMA

858 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by elgarbe on Mon Mar 24 16:19:35 MST 2014
I'm really need some support about it...
I want to send 256bytes from SPI using DMA. Just use MOSI, I don't use Receiver part and CLK neither.

I'm testing this other code:
char data[64]={1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2};

#include <cr_section_macros.h>
#include <NXP/crp.h>

void SSP0Init();

/*******************************************************************************
**   Main Function  main()
*******************************************************************************/
int main (void){

SSP0Init();// Inicializo el bus SPI

LPC_SC->PCONP |= 1 << 29; // Power up DMA

LPC_GPDMACH0->DMACCConfig = 0; // stop ch0 dma
//LPC_SC->DMAREQSEL |= 1 << 2; // Timer1 Match Compare 0 as DMA request

    LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) &data[0]; // data[] is the array where I have stored alternating 1's and 0's.
LPC_GPDMACH0->DMACCDestAddr = (uint32_t) &(LPC_SSP0->DR); // SSP0
LPC_GPDMACH0->DMACCLLI = 0;
LPC_GPDMACH0->DMACCControl = 32 // Transferencia de 32 bytes, 1 burst
| (1 << 12) // Burst de 1 bytes
| (1 << 15) // Burst de 1 bytes
| ( 1 << 26 ); // Source increment.
LPC_GPDMACH0->DMACCConfig = ( 0 << 6 ) | ( 1 << 11); // Set SPI as destination request peripheral and the type pf transfer as Memory to Peripheral.

LPC_GPDMA->DMACIntErrClr |= 0xff;//Clear all DMA interrupts
LPC_GPDMA->DMACIntTCClear |= 0xff;

LPC_GPDMA->DMACConfig |= 1 << 0; // enable DMA
LPC_GPDMACH0->DMACCConfig |= 1; //enable ch0

while ( 1 ){
}
}


In these case I don't configure DMAREQSEL and set SPI tx as "destination request peripheral". I try to send 32bytes. This is the only code that works well. But I don't understand "destination request peripheral"... what is it? wich is the purpose of DMAREQSEL? when SPI activate the request signal?

In these code I have SPI configured for 8bits long. So when I connect the oscilloscope on SPI Clock I see 32 groups of 8 clock pulse. But I see a litle space (1 clock?) between each byte. Can I remove this space with some configuration change? becouse I need to Send 320 bits...

Now, what if I want to activate DMA with a timer mach register? I configure Timer1 Match register 0 to 20usec. I would like to this match fire DMA to SPI transfer.
So, I write this code:

/*******************************************************************************
**   Main Function  main()
*******************************************************************************/
int main (void){

SSP0Init();// Inicializo el bus SPI

// setup timer1
LPC_SC->PCONP |= 1 << 2; // Power up
LPC_SC->PCLKSEL0 |= 0x01 << 4; // CCLK -> 10nseg ticks
LPC_TIM1->MR0 = 2000;// Match a los 10 segundos
LPC_TIM1->MCR = 1 << 1; // reset on Match Compare 0

LPC_TIM1->IR |= 0xff; // Clear all timer interrupts if there are any
LPC_TIM1->TCR = 2;// Pongo a 0 el Contador del Timer y queda desabilitado

LPC_SC->PCONP |= 1 << 29; // Power up DMA

LPC_GPDMACH0->DMACCConfig = 0; // stop ch0 dma

LPC_SC->DMAREQSEL |= 1 << 2; // Timer1 Match Compare 0 as DMA request

LPC_GPDMA->DMACIntErrClr |= 0xff;
LPC_GPDMA->DMACIntTCClear |= 0xff;

    LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) &data[0]; // hora[] is the array where I have stored alternating 1's and 0's.
LPC_GPDMACH0->DMACCDestAddr = (uint32_t) &(LPC_SSP0->DR); // SSP0
LPC_GPDMACH0->DMACCLLI = 0;
LPC_GPDMACH0->DMACCControl = 16 // Transferencia de 16 bytes
| (1 << 12) // Burst de 8 bytes
| (1 << 15) // Burst de 8 bytes
| (1 << 26 ); // Source increment.
LPC_GPDMACH0->DMACCConfig = ( 10 << 6 ) | ( 1 << 11); // Set MAT1.0 as destination request peripheral and the type pf transfer as Memory to Peripheral.

LPC_GPDMA->DMACConfig |= 1 << 0; // enable DMA
LPC_GPDMACH0->DMACCConfig |= 1; //enable ch0
LPC_TIM1->TCR = 0x01; // start timer.

while ( 1 ){
}
}


As you can see I configure all on main.c to go step by step.
Here I have DMAREQSEL and destination request peripheral doubt. What shoud I use on each register?
On this code I try to send 16 bytes once Timer1 Match0 fire. What I see on my osccilloscope is 20useg, a group of 4byte, 20useg, another group of 4byte and so on until 16 bytes is send.

If I change the code and set SPI as destination request periperal:
LPC_GPDMACH0->DMACCConfig = ( 0 << 6 ) | ( 1 << 11); // Set SPI as destination request peripheral and the type pf transfer as Memory to Peripheral.

What I see is 16 groups of pulse, but no 20usec on the first pulse. When I enable DMA it's fire without waiting for timer1 match0.

So, I can change all my code logic, I can configure Match register 0 to produce interrupt, and on interrupt I can fire DMA manually, but I need to understand each regiter before I use DMA.

Is there any documentation for DMA? I already read UM, but it's not clear.

I'm really needing NXP support on it.

Thk and best regards!
Labels (1)
0 Kudos
2 Replies

716 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by elgarbe on Fri May 23 13:59:05 MST 2014
It's a lpc1769

Thk
0 Kudos

716 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by xianghuiwang on Fri May 23 12:48:53 MST 2014
Hi, elgarbe,

Please let us know which part is this about - so we can help you better? Maybe I missed the part name in your text?
good luck!
0 Kudos