I had two problems, configuring the PDB and configuring the channels for mux1. Here one way of doing dma general.
if(!DMA_Init((uint32_t)&ADC0->SC1[CHANNEL_A], (uint32_t)&ADC0->R[CHANNEL_A], (uint8_t*)uc_adc1_mux, NUM_OF_MUX, (uint16_t*)ui_adc1_result, NUM_OF_MUX*NUM_OF_SAMPLES, DMA_MODULE_ADC1_CONFIG, 1, dmaCallback))
printf("DMA INIT SUCCESS\n");
else
printf("DMA INIT FAILED\n");
typedef struct { uint8_t CHLINK, REQLINK, CHREAD, REQREAD, MUX;} tDMA;
#define DMA_MODULE_ADC0_CONFIG \
(tDMA){ \
/* CHLINK */ ADC0_DMA_CHANNEL_ADCONTROL, \
/* REQLINK */ DMA_MUX0_DMA_MUX_1, \
/* CHREAD */ ADC0_DMA_CHANNEL_ADCREAD, \
/* REQREAD */ DMA_MUX0_ADC0, \
DMA_MUX0, \
}
/* Function redefinition */
/***************************************************************************//*!
* @brief DMA initialization function.
* @param LINKAdr - Pointer to module link register (mux)
* @param READAdr - Pointer to module result register
* @param mux - Pointer to mux array
* @param muxSize - Number of channals to mux
* @param destination - Pointer to destination array
* @param destinationSize - Size of destination array (must be 8 aligned)
* @param cfg - DMA module configuration structure.
* @param ip - IRQ Priority
* @param callback - Pointer to DMA_CALLBACK function
* @return 0 - SUCCESS
* @return 1 - ERROR
* @note Implemented as function call.
******************************************************************************/
int DMA_Init ( const uint32_t LINKAdr,
const uint32_t READAdr,
uint8_t * mux,
uint16_t muxSize,
uint16_t * destination,
uint16_t destinationSize,
tDMA cfg, uint8_t ip, DMA_CALLBACK pCallback)
{
float32_t tmp = 0;
if(cfg.CHLINK > DMA_MUX1_CHANNEL_OFFSET || cfg.CHREAD > DMA_MUX1_CHANNEL_OFFSET)
{
//ERROR: ILLEGAL CHANNEL
return 1;
}
tmp = destinationSize/8;
tmp = tmp-(uint16_t)tmp;
if(tmp > 1.0)
{
//ERROR: DESTINATION BUFFER IS NOT 8 BYTE ALIGNED
return 1;
}
// -------------------------------------------------------------------------------------
// DMA channel 'ADCONTROL' used to transfer next ADCx control from RAM to ADCx_SC1A.
// -------------------------------------------------------------------------------------
// Configure this DMA channel to an always enabled request source and enable this channel
if (cfg.MUX)
{
DMAMUX1->CHCFG[cfg.CHLINK] = (DMAMUX_CHCFG_ENBL_MASK | // Enable routing of DMA request
DMAMUX_CHCFG_SOURCE(cfg.REQLINK)); // Channel Activation Source: DMA MUX always enabled
// Attention: DMA MUX1 is routed to DMA channels 16-31 as described in
// Reference manual MK10FX: chapter '3.3.9.1 DMA MUX request sources'
// We have to use a DMA channel offset of 16 during setup of the DMAs
cfg.CHLINK += DMA_MUX1_CHANNEL_OFFSET;
}
else
{
DMAMUX0->CHCFG[cfg.CHLINK] = (DMAMUX_CHCFG_ENBL_MASK | // Enable routing of DMA request
DMAMUX_CHCFG_SOURCE(cfg.REQLINK)); // Channel Activation Source: DMA MUX always enabled
}
DMA0->TCD[cfg.CHLINK].SADDR = (uint32_t) &mux[0]; //mux array
DMA0->TCD[cfg.CHLINK].SOFF = 0x01; //Source address increment, adding "1"
DMA0->TCD[cfg.CHLINK].SLAST = (uint32_t) -muxSize; //Source address decrement after major loop complete
DMA0->TCD[cfg.CHLINK].DADDR = (uint32_t)LINKAdr; //Destination address ADCx mux selector
DMA0->TCD[cfg.CHLINK].DOFF = 0x00; //Destination address increment, adding "0"
DMA0->TCD[cfg.CHLINK].DLAST_SGA = 0x00; //Destination address shift, go to back to [0]
DMA0->TCD[cfg.CHLINK].NBYTES_MLNO = 0x01; //No of bytes minor loop
DMA0->TCD[cfg.CHLINK].BITER_ELINKNO = muxSize; //Major loop step, x num ADC channel are scaning
DMA0->TCD[cfg.CHLINK].CITER_ELINKNO = muxSize; //Major loop step, x num ADC channel are scaning
DMA0->TCD[cfg.CHLINK].ATTR = DMA_ATTR_SSIZE(0)|DMA_ATTR_DSIZE(0); //Source a destination size, 8bit
DMA0->TCD[cfg.CHLINK].CSR = 0x0000; //
if (pCallback != NULL )
{
pCallbackCH[cfg.CHREAD] = pCallback;
NVIC_EnableIRQ(cfg.CHREAD);
}
// -------------------------------------------------------------------------------------
// DMA channel 'ADCREAD' used to transfer ADCx result data from ADCx_RA to RAM.
// -------------------------------------------------------------------------------------
// Configure this DMA channel to use ADCx CoCo as transfer request source and enable this channel
if (cfg.MUX)
{
DMAMUX1->CHCFG[cfg.CHREAD] = (DMAMUX_CHCFG_ENBL_MASK | // Enable routing of DMA request
DMAMUX_CHCFG_SOURCE(cfg.REQREAD)); // Channel Activation Source: ADCx CoCo
// Attention: DMA MUX1 is routed to DMA channels 16-31 as described in
// Reference manual MK10FX: chapter '3.3.9.1 DMA MUX request sources'
// We have to use a DMA channel offset of 16 during setup of the DMAs
cfg.CHREAD += DMA_MUX1_CHANNEL_OFFSET;
}
else
{
DMAMUX0->CHCFG[cfg.CHREAD] = (DMAMUX_CHCFG_ENBL_MASK | // Enable routing of DMA request
DMAMUX_CHCFG_SOURCE(cfg.REQREAD)); // Channel Activation Source: ADCx CoCo
}
//****************************************************************************
//**** DMA channel, use for Read ADC result data, form ADC to SRAM *********
//****************************************************************************
DMA0->TCD[cfg.CHREAD].SADDR = (uint32_t)READAdr; //Source address ADCx result register
DMA0->TCD[cfg.CHREAD].SOFF = 0x00; //Source address increment, adding "0"
DMA0->TCD[cfg.CHREAD].SLAST = 0x00; //Source address decrement after major loop complete
DMA0->TCD[cfg.CHREAD].DADDR = (uint32_t) &destination[0]; //Destination address, ADCx result buffer
DMA0->TCD[cfg.CHREAD].DOFF = 0x02; //Destination address increment, adding "+2"
DMA0->TCD[cfg.CHREAD].DLAST_SGA = (uint32_t) -destinationSize*2; //Destination address decrement after major loop complete
DMA0->TCD[cfg.CHREAD].NBYTES_MLNO = 0x02; //No of bytes minor loop, 16bit ADC result
DMA0->TCD[cfg.CHREAD].BITER_ELINKYES =
DMA_BITER_ELINKYES_ELINK_MASK | DMA_BITER_ELINKYES_LINKCH(cfg.CHLINK) | DMA_BITER_ELINKYES_BITER(destinationSize); //Channel x Link, Channel 0, Major loop step 3 x 4 = 12
DMA0->TCD[cfg.CHREAD].CITER_ELINKYES =
DMA_CITER_ELINKYES_ELINK_MASK | DMA_CITER_ELINKYES_LINKCH(cfg.CHLINK) | DMA_CITER_ELINKYES_CITER(destinationSize); //Channel x Link, Major loop step 3 x 4 = 12
DMA0->TCD[cfg.CHREAD].ATTR = DMA_ATTR_SSIZE(1)|DMA_ATTR_DSIZE(1); //Source a destination size, 16bit
DMA0->SERQ = DMA_SERQ_SERQ(cfg.CHREAD);
DMA0->TCD[cfg.CHREAD].CSR = (DMA_CSR_MAJORLINKCH(cfg.CHLINK)|DMA_CSR_MAJORELINK_MASK)| //Major loop finished start request for Channel 0
DMA_CSR_INTMAJOR_MASK; //|DMA_CSR_INTHALF_MASK; //Irq. enable, full transfer, half complet transfer
return 0;
}