Problems with DMA

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 
9,196件の閲覧回数
kenrenjen
Contributor III

Hi... Another post by me, because some of the other threads wasn't answered Smiley Wink

I am trying to make DMA work using flextimer on a K60. I just made a basic example as I needed to understand the fundamental in setting up DMA.

The problem is that nothing works. I have checked the registers and they are correctly set up. Do I miss something or what do I do wrong here?

uint16 Data_Desti[8];     //destination data space

// Initialisation of timer and interrupts

void ftm_init(void)

{

  POWER_UP(6, SIM_SCGC6_FTM0); // Enable timer

  PORTC_PCR1 = PC_1_FTM0_CH0; // Multiplexer (MUX) for flextimer (FTM) initialized to port FTM0 and channel 0  (route the desired signal to the pin)

  FTM0_MODE = (FTM_MODE_WPDIS | FTM_MODE_FTMEN); // Disable write protection

  FTM0_CONF = FTM_CONF_BDMMODE_3; // FTM_DEBUG_BEHAVIOUR: Allow timer to continue operating when debugging 

  FTM0_CNTIN = 0x0000; // Counter initial value

  FTM0_MOD = 0xFFFF; // Modulo to max

  FTM0_C0SC = ( FTM_CSC_ELSA | FTM_CSC_DMA);

  FTM0_SC = (FTM_SC_CLKS_SYS | FTM_SC_PS_128 | FTM_SC_TOIE); // Sets the source to system clock and define the prescalar. Timer overflow interrupt enabled (1)

  fnEnterInterrupt(irq_FTM0_ID, PRIORITY_HW_TIMER, ftm0_isr); //Configure and enter the ftm0 handling interrupt routine in the vector table

}

// Configure the DMA MUX and DMA controller module.

void dma_init(void)

{

  // Config DMA MUX

  POWER_UP(6, SIM_SCGC6_DMAMUX0);

  // Config DMA controller

  POWER_UP(7, SIM_SCGC7_DMA);

  DMAMUX0_CHCFG0 = (DMAMUX_CHCFG_ENBL | DMAMUX_CHCFG_SOURCE_FTM0_CH0);

  //DMA_CR = (DMA_CR_EMLM| DMA_CR_EDBG);

  DMA_TCD0_SADDR = (uint32)(&FTM0_C0V);

  DMA_TCD0_DADDR = (uint32)(&Data_Desti[0]); // Destination address

  DMA_TCD0_DOFF = 2; // Destination address incremented by two bytes (16 bit)

  DMA_TCD0_DLASTSGA = -32; // Restores the destination address to the initial value (2*16bit)

  DMA_TCD0_BITER_ELINKNO = 0x01; // Channel Linking Disabled

  DMA_TCD0_CITER_ELINKNO = 0x01; // Channel Linking Disabled

  DMA_TCD0_NBYTES_MLNO = 8; // Transfer 8 bytes per transaction

  DMA_TCD0_ATTR = (DMA_TCD_ATTR_DSIZE_8 /*| DMA_TCD_ATTR_SSIZE_8*/); // Source and Destination modulu

  DMA_TCD0_CSR = (DMA_TCD_CSR_DREQ | DMA_TCD_CSR_INTMAJOR); //The end-of-major loop interrupt is enabled

  DMA_ERQ = DMA_ERQ_ERQ0;

  fnEnterInterrupt(irq_DMA0_ID, PRIORITY_DMA0, dma0_isr);

}

// Interrupt service routine

static __interrupt void ftm0_isr(void)

{

  if(FTM0_SC & FTM_SC_TOF)

  {

  FTM0_SC &= ~FTM_SC_TOF;

  OVFcnt++;

  }

}

static __interrupt void dma0_isr(void)

{

  //DMA_CINT = DMA_INT_INT0;

  DMAMUX0_CHCFG0= 0;

  DMA_INT = 0x01;

  DMA_CDNE = 0x01;

  for(i=0;i<8;i++)

  {

  fnDebugDec(i, sizeof(i));

  fnDebugMsg(") cnt=");

  fnDebugDec(Data_Desti[i], sizeof(Data_Desti));

  fnDebugMsg("\r\n");

  }

}

ラベル(1)
1 解決策
8,261件の閲覧回数
jeremyzhou
NXP Employee
NXP Employee

Hi Kenneth,

How about try the following code.

// Configure the DMA MUX and DMA controller module.

void dma_init(void)

{

  SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;  // Config DMA MUX

  SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;     // DMA controller

  DMA_ERQ &= ~(1<<0);

  DMAMUX0_CHCFG0 = DMAMUX_CHCFG_SOURCE_FTM0_CH0;

  /* transfer, making only a single minor loop necessary to complete a major loop */

  DMA_TCD0_SADDR = (uint32)(&FTM0_C0V); /* Set the Source Address */

  /* Source offset disabled */

  DMA_TCD0_SOFF = 0x00;

  /* Source and Destination Modulo off, source and destination size 1 = 16 bits */

  DMA_TCD0_ATTR = DMA_ATTR_SSIZE(1) | DMA_ATTR_DSIZE(1);

  /* Transfer 2 bytes per transaction */

  DMA_TCD0_NBYTES_MLNO = 0x02;

  /* No adjust needed */

  DMA_TCD0_SLAST = 0x00;

  /* Destination address */

  DMA_TCD0_DADDR = (uint32)(&Data_Desti[0]);

  /* Destination offset  */

  DMA_TCD0_DOFF = 0x02;

  /* No link channel to channel, 1 transaction */

  DMA_TCD0_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(8);

  /* No adjustment to destination address */

  DMA_TCD0_DLASTSGA = 0x00;

  DMA_TCD0_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(8);

  DMA_TCD0_CSR |= (DMA_CSR_INTMAJOR_MASK|DMA_CSR_DREQ_MASK);

 

  DMAMUX0_CHCFG0 |=DMAMUX_CHCFG_ENBL_MASK;

  DMA_ERQ |=(1<<0);

  fnEnterInterrupt(irq_DMA0_ID, PRIORITY_DMA0, dma0_isr);

}

If you still have question, please contact with without hesitate.

Good luck.

Ping.

元の投稿で解決策を見る

0 件の賞賛
返信
21 返答(返信)
347件の閲覧回数
kenrenjen
Contributor III

Hi Jing

Here is the answer on the questions:

1: The FTM timer works without DMA. I want to eleminate number of interrupts by using DMA.

2: The K60 I use is  K60FN1M0 (Using TWR-K60F120M module)

3. I have attached the project. I am using uTasker. The task and initialization of DMA and FTM is in the file ir_start.c

Thanks for taking your time :smileyhappy:

// Kenneth

0 件の賞賛
返信