lpcware

SPI and DMA

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
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!

Outcomes