lpcware

Timer trigered DMA transfer

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 Tue Mar 18 17:22:08 MST 2014
Hi, I'm testing DMA on LPC1769. I need to transfer some bytes out using SSP0 as SPI. I want to do this every timer1 MR0 match Timer1 TC.

So I write this code:


#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

char data[25]={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};

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

void SSP0Init();

/*******************************************************************************
**   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 20 useg
LPC_TIM1->MCR = 1 << 1; // reset on Match Compare 0

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

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

LPC_GPDMA->DMACConfig |= 1 << 0; // enable DMA
//LPC_GPDMA->DMACSync |= 1 << 10; // use MAT1.0 for Sync
LPC_SC->DMAREQSEL |= 1 << 2; // Timer1 Match Compare 0 as DMA request

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

LPC_GPDMACH0->DMACCDestAddr = (uint32_t) &(LPC_SSP0->DR); // SSP0
    LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) &data[0]; // hora[] is the array where I have stored alternating 1's and 0's.
LPC_GPDMACH0->DMACCLLI = 0;

LPC_GPDMACH0->DMACCControl = 7 | ( 1 << 26 ); // Transfer size = 25 bytes and enable source increment.

LPC_GPDMACH0->DMACCConfig = ( 0 << 6 ) | ( 1 << 11); // Set MAT1.0 as destination request peripheral and the type pf transfer as Memory to Peripheral.
LPC_GPDMACH0->DMACCConfig |= 1; //enable ch0

//LPC_TIM1->IR |= 0xff; // Clear all timer interrupts if there are any
//LPC_TIM1->TCR |= 2;// Pongo a 0 el Contador del Timer
//LPC_TIM1->TCR &= ~2;// Des-reseteo el Contador del Timer
//LPC_TIM1->TCR = 0x01; // start timer.

while ( 1 ){
}
}
void SSP0Init( void ){

  LPC_SC->PCONP |= (0x1<<21);//Damos alimentacion al módulo SPP0

  LPC_SC->PCLKSEL1 &= ~(3 << 10); //Borramos bits
  LPC_SC->PCLKSEL1 |=  (1 << 10); // set to "01" = Core Clock (100 MHz) 10nseg Tick

  /* P0.15~0.18 as SSP0 */
  LPC_PINCON->PINSEL0 &= ~(0x3UL<<30);
  LPC_PINCON->PINSEL0 |= (0x2UL<<30);
  LPC_PINCON->PINSEL1 &= ~((0x3<<0)|(0x3<<2)|(0x3<<4));
  LPC_PINCON->PINSEL1 |= ((0x2<<0)|(0x2<<2)|(0x2<<4));

  LPC_PINCON->PINSEL1 &= ~(0x3<<0);
  LPC_GPIO0->FIODIR |= (0x1<<16);/* P0.16 defined as GPIO and Outputs */

  /* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 7+1 */
  LPC_SSP0->CR0 = (0x7 | 0x100);

  /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
  LPC_SSP0->CPSR = 0x8;

  /* Device select as master, SSP Enabled */
  /* Master mode */
  LPC_SSP0->CR1 = (1 << 1);

  /* Enable SSP0 for DMA. */
  LPC_SSP0->DMACR = 0x2;
  return;
}


It's a mix of some examples I found.

When I run this I obtain this on SPI CLK pin:

[img=640x480]http://www.flickr.com/photos/117247358@N03/13254512955/[/img]

As you can see SCK is 2V before SSP is configured. When SSP is configured as SPI CLK is going low. 5useg later I read 7 bytes comes out from SPI. But, if you see my code, I've never start the timer. So what am i doing wrong? why DMA activated just before I enable it?

Thk!

Outcomes