AnsweredAssumed Answered

Why is DMA skipping array values?

Question asked by Paul Swanson on Jul 29, 2019
Latest reply on Jul 29, 2019 by Paul Swanson

Hello,

 

On the FRDM-KL25Z, I'm attempting to get DMA to transfer data to DAC, however, it appears to only be transferring only every other value in the source array (second, fourth, sixth etc).

 

I've gone over the settings and manual countless times and cannot explain this behaviour.

 

What I'm looking to achieve is:

  1. PIT triggers a DMA transfer (CS - one transfer per trigger)
  2. DMA transfers one 16-bit integer from the array to the DAC
  3. DMA source address increments two bytes
  4. Repeat until finished

 

However, what I'm observing is that only every second integer in the array is transferred, the others are just skipped (no errors etc).

 

How I read the manual is that:

  • BCR - is the total number of bytes to complete a DMA transfer
  • SSIZE - '2' = 16-bit source values
  • DSIZE - '2' = 16-bit destination values
  • SINC - given the above, increments source by two bytes each time

 

With these settings and an 8 value array of 16-bit integers, only four PIT trigger events occur, on each event the BCR is decremented by 4 bytes and only the even numbered values in the array ever touch the DAC.

 

I can't reconcile the behaviour I'm seeing with the configuration I've provided.

 

Please see the source code below, this example just attempts varying levels on the DAC analog out pin (other boiler plate code is assumed), the odd numbered sample values are never transferred (ie. 1000), regardless of value:

 

#define SAMPLES_SIZE (8)
uint16_t SAMPLES[SAMPLES_SIZE] = { 1000, 3000, 1000, 3000, 1000, 3000, 1000, 3000 };

 

#define LED1 7
const uint32_t LED_DMA = (1UL << LED1);

 

// These are just debug counter values

volatile uint32_t dma_count = 0;
volatile uint32_t pit_count = 0;

 

void config_dma(void);
void config_dma(void)
{
/* Set source and destination for DMA transfer */
DMA0->DMA[0].SAR = DMA_SAR_SAR((uint32_t) SAMPLES);
DMA0->DMA[0].DAR = DMA_DAR_DAR((uint32_t) (&(DAC0->DAT[0])));
/* Set byte count */
DMA0->DMA[0].DSR_BCR = DMA_DSR_BCR_BCR(SAMPLES_SIZE*2);
/* Clear done flag */
DMA0->DMA[0].DSR_BCR &= ~DMA_DSR_BCR_DONE_MASK;
/* Enable DMA muxer */
DMAMUX0->CHCFG[0] |= DMAMUX_CHCFG_ENBL_MASK;
}

 

void PIT_IRQHandler(void)
{
pit_count++; // Debug
PRINTF("p:%u d:%u b:%u\n",pit_count,dma_count, DMA0->DMA[0].DSR_BCR & DMA_DSR_BCR_BCR_MASK); // Debug
PIT->CHANNEL[0].TFLG |= PIT_TFLG_TIF(0);
}


void DMA0_IRQHandler(void)
{
DMA0->DMA[0].DSR_BCR |= DMA_DSR_BCR_DONE_MASK;
config_dma();
dma_count++; // Debug
}


int main(void) {

 

// Board initialising code omitted

 

// Configure clock for PORTE, DMA Multiplexer, DMA, DAC & PIT
SIM->SCGC5 |= SIM_SCGC5_PORTE(1);
SIM->SCGC6 |= SIM_SCGC6_DMAMUX(1) | SIM_SCGC6_PIT(1) | SIM_SCGC6_DAC0(1);
SIM->SCGC7 |= SIM_SCGC7_DMA(1);

/* Set Port E pin 30 to analog */
PORTE->PCR[30] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[30] |= PORT_PCR_MUX(0);

 

/* Disable buffer mode */
DAC0->C1 = 0;
DAC0->C2 = 0;

 

/* Enable DAC with VDDA as ref voltage */
DAC0->C0 = DAC_C0_DACEN_MASK | DAC_C0_DACRFS_MASK;

 

// Disable DMAMUX channel and PIT timer
DMAMUX0->CHCFG[0] = 0;
PIT->CHANNEL[0].TCTRL &= ~PIT_TCTRL_TEN(1);

 

// Configure DMA Source and Destination addresses
DMA0->DMA[0].DCR = DMA_DCR_ERQ_MASK | DMA_DCR_CS_MASK | DMA_DCR_EINT_MASK
| DMA_DCR_SINC_MASK
| DMA_DCR_SSIZE(2)
| DMA_DCR_DSIZE(2);

 

// Configure PIT - runs off bus clock 24mhz!
PIT->CHANNEL[0].LDVAL = (SystemCoreClock/2) - 1; // one second interval
PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN(1) | PIT_TCTRL_TIE(1);
PIT->MCR = 0; /* Module enabled, don't freeze in debug */

// Enable DMAMUX0 Channel 0, always on and triggered
DMAMUX0->CHCFG[0] |= DMAMUX_CHCFG_TRIG(1);

 

/* Set up interrupt controller */
NVIC_SetPriority(PIT_IRQn, 2);
NVIC_ClearPendingIRQ(PIT_IRQn);
NVIC_EnableIRQ(PIT_IRQn);

 

NVIC_SetPriority(DMA0_IRQn, 0);
NVIC_ClearPendingIRQ(DMA0_IRQn);
NVIC_EnableIRQ(DMA0_IRQn);

 

DMAMUX0->CHCFG[0] |= DMAMUX_CHCFG_SOURCE(60);

config_dma();

 

As always, any help greatly appreciated.

 

Regards,

 

Paul Swanson

Outcomes