AnsweredAssumed Answered

K64F ADC0 multichannel with PDB and DMA

Question asked by Jernej Turnsek on Jan 4, 2018
Latest reply on Jan 5, 2018 by Jernej Turnsek

Hi,

I am sampling two analog channels with ADC0 SC1A and SC1B configuration registers with the help of backtoback mode PDB continuous triggering. Now I would like to transfer results from RA and RB register with the help of eDMA. Reference manual states that DMA trigger signal is asserted during ADC conversion complete event when any of the SC1n COCO flag is asserted, but looking into Example-S32K144-PDB-ADC-back2back-v1_0-S32DS12 source code only one DMA channel is utilized to move both registers at the same time. I feel this could not be the case here, because when SC1A COCO is set DMA is triggered and then also when SC1B COCO is set another DMA trigger is asserted. Thus I would think registers are transferred twice instead of once. Did I have missed something? How should I set DMA?

 

The code in the example is for another type of processor with 4 channels per ADC, but I think peripherials should be very similar to K64F processor. Maybe I am wrong here.

 

void PDB_Init(void)

PCC->PCCn[PCC_PDB0_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable bus clock in PDB0 */

PDB0->SC |= PDB_SC_TRGSEL(0xF) | /* b1111: Software trigger is selected */
PDB_SC_PRESCALER(1) | /* Prescaler: 010 = sysclck/(2*MULT) = 80 / (2*1) = 40MHz */
PDB_SC_MULT(0) | /* 00: Multiplication factor is 1. */
PDB_SC_PDBEN_MASK; /* 1: PDB enabled */
PDB0->CH[0].C1 |= PDB_C1_BB(0xe) | /* DLY[0] : pre-trigger from PDB DLY */
/* DLY[3:1] : back-to-back enabled */
PDB_C1_TOS(0x00) | /* Pretrigger Output Select: 0=bypassed , 1=enabled */
PDB_C1_EN(0xf); /* PDB channel's [3:0] pre-trigger enabled */
// PDB0->MOD = 2200;
// PDB0->IDLY = 2200;
// PDB0->CH[0].DLY[0] = 100; /* Pretrigger 0 : 100 * 25e-9 = 2.5e-6 */
PDB0->SC |= PDB_SC_LDOK_MASK;
}

 

void ADC_Init(void)
{

PCC->PCCn[PCC_ADC0_INDEX] &= ~PCC_PCCn_CGC_MASK; /* Disable clock to change PCS */
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_PCS(6); /* PCS=3: Select SPLL */
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable bus clock in ADC */

ADC0->CFG1 |= ADC_CFG1_ADICLK(0) | /* Only ALTCLK1 is available */
ADC_CFG1_ADIV(2) | /* the clock rate is (input clock)/4 */
ADC_CFG1_MODE(1); /* 0b00: 8-bit, 0b01: 12-bit, 0b10: 10-bit */
ADC0->SC2 |= ADC_SC2_ADTRG(1) | /* Conversion Trigger: 0b0= SW , 0b1 = HW */
ADC_SC2_DMAEN(1); /* enable DMA trigger */

ADC0->SC1[0] = ADC_SC1_ADCH(12); /* Select AD12 (ADC0_SE12) @PTC14 */
ADC0->SC1[1] = ADC_SC1_ADCH(12); /* Select AD12 (ADC0_SE12) @PTC14 */
ADC0->SC1[2] = ADC_SC1_ADCH(12); /* Select AD12 (ADC0_SE12) @PTC14 */
ADC0->SC1[3] = ADC_SC1_ADCH(12); /* Select AD12 (ADC0_SE12) @PTC14 */

}

 

void DMA_init(void)
{

PCC->PCCn[PCC_DMA0_INDEX] |= PCC_PCCn_CGC_MASK; // CGC=1: Clock enabled for DMA0

DMA->TCD[0].CSR &= 0xFFFFFFFF ^ DMA_TCD_CSR_DONE_MASK; // Clear Channel Done flag
DMA->TCD[0].SADDR = DMA_TCD_SADDR_SADDR(&(ADC0->R[0])); // Source Address
DMA->TCD[0].SOFF = DMA_TCD_SOFF_SOFF(4); // Source Offset
DMA->TCD[0].ATTR = DMA_TCD_ATTR_SMOD(0) | // Source address modulo feature is disabled
DMA_TCD_ATTR_SSIZE(2) | // Source data transfer size: 1: 16-bit, 2=32-bit
DMA_TCD_ATTR_DMOD(0) | // Destination address modulo feature: 0=disabled, x= x power of 2 buffer[DMOD=4->buffer of 16bytes]
DMA_TCD_ATTR_DSIZE(2); // Destination data transfer size: 1: 16-bit, 2=32-bit
DMA->TCD[0].NBYTES.MLOFFNO = DMA_TCD_NBYTES_MLNO_NBYTES(4); // Minor Byte Transfer Count is 4-bytes
DMA->TCD[0].SLAST = DMA_TCD_SLAST_SLAST(-16); // Last Source Address Adjustment is -16
DMA->TCD[0].DADDR = DMA_TCD_DADDR_DADDR(&(result[0])); // Destination Address of Buffer
DMA->TCD[0].DOFF = DMA_TCD_DOFF_DOFF(4); // Destination Address Signed Offset is 4
DMA->TCD[0].CITER.ELINKNO = DMA_TCD_CITER_ELINKNO_CITER(4) // Current Major Iteration Count is 4
| DMA_TCD_CITER_ELINKNO_ELINK(0); // The channel-to-channel linking is disabled
DMA->TCD[0].DLASTSGA = DMA_TCD_DLASTSGA_DLASTSGA(-16); // Destination last address adjustment is -16
DMA->TCD[0].BITER.ELINKNO = DMA_TCD_BITER_ELINKNO_BITER(4) | // Starting major iteration count is 4
DMA_TCD_BITER_ELINKNO_ELINK(0); // The minor channel-to-channel linking is disabled
DMA->TCD[0].CSR = DMA_TCD_CSR_BWC(0) | // BWC=0: No eDMA engine stalls - full bandwidth
DMA_TCD_CSR_MAJORELINK(0) | // The channel-to-channel linking is disabled
DMA_TCD_CSR_MAJORLINKCH(0) | // channel 1 will be called from ch0
DMA_TCD_CSR_ESG(0) | // The current channel�fs TCD is normal format - No scatter/gather
DMA_TCD_CSR_DREQ(0) | // The channel's ERQ bit is not affected
DMA_TCD_CSR_INTHALF(0) | // The half-point interrupt is disabled
DMA_TCD_CSR_INTMAJOR(1) | // The end-of-major loop interrupt is enabled
DMA_TCD_CSR_START(0); // The channel is not explicitly started

DMA->SERQ = 0; // enable DMA channel 0 HW trigger
}


void DMAMUX_Init (void)
{
PCC->PCCn[PCC_DMAMUX0_INDEX] |= PCC_PCCn_CGC_MASK; // CGC=1: Clock enabled for DMAMUX0

DMAMUX->CHCFG[0] &= ~ DMAMUX_CHCFG_ENBL(1); // Disabling the DMA channel
DMAMUX->CHCFG[0] |= DMAMUX_CHCFG_SOURCE(40); // ADC0 COCO is the source of the DMA0 channel
DMAMUX->CHCFG[0] |= DMAMUX_CHCFG_ENBL(1); // Enabling the DMA channel
}

 

Regards,

Jernej

Outcomes