AnsweredAssumed Answered

DMA0_IRQHandler doesn't run [s32k144]

Question asked by Electronica2 Powertrack on Apr 18, 2018
Latest reply on Apr 25, 2018 by Petr Stancik

Hi to the community,

 

I have been trying to run this example, but the "DMA0_IRQHandler" doesn't run. Why is it?

If i look at expressions "counter" is always 0. It should increase its value on each DMA0_IRQ request: counter++;

(DMA is triggered by PDB)

 

On the other hand, i think that interrupts is enable, because i get some "Error:Target...." when i debug step by step on the for(;;){}. So maybe the DMA0 interruption isn't linked correctly.

 

Code:

 

#include "S32K144.h" /* include peripheral declarations S32K144 */


static uint32_t result[4] __attribute__ ((aligned (32)));
uint32_t salidaADC=0;
uint32_t counter=0;

void SCG_Init(void);
void GPIO_Init(void);
void PDB_Init(void);
void ADC_Init(void);
void WDOG_Disable(void);
void PDB_Init(void);
void DMA_init(void);
void DMAMUX_Init(void);
void IRQs_Init(void);
void DMA0_IRQHandler(void);


void SCG_Init(void)
{
// *** System OSC ***
SCG->SOSCDIV=0x00000101; /* SOSCDIV1 & SOSCDIV2 =1: divide by 1 */
SCG->SOSCCFG=0x00000034; /* Range=3: high freq (SOSC betw 8MHz-32MHz)*/
/* HGO=0: Config xtal osc for low power */
/* EREFS=1: Input is external XTAL */
while(SCG->SOSCCSR & SCG_SOSCCSR_LK_MASK); /* Ensure SOSCCSR unlocked */
SCG->SOSCCSR=0x00000001; /* LK=0: SOSCCSR can be written */
/* SOSCCMRE=0: OSC CLK monitor IRQ if enabled */
/* SOSCCM=0: OSC CLK monitor disabled */
/* SOSCERCLKEN=0: Sys OSC 3V ERCLK output clk disabled */
/* SOSCLPEN=0: Sys OSC disabled in VLP modes */
/* SOSCSTEN=0: Sys OSC disabled in Stop modes */
/* SOSCEN=1: Enable oscillator */
while(!(SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK)); /* Wait for sys OSC clk valid */

// *** System PLL ***
SCG->SPLLDIV = 0x00000101; /* SOSCPLL1 & SPLLDIV2 =1: divide by 1 */
SCG->SPLLCFG = 0x00180000; /* PREDIV=0: Divide SOSC_CLK by 0+1=1 */
/* MULT=24: Multiply sys pll by 24+16=40 */
/* SPLL_CLK = 8MHz / 1 * 40 / 2 = 160 MHz */
while(SCG->SPLLCSR & SCG_SPLLCSR_LK_MASK); /* Ensure SPLLCSR unlocked */
SCG->SPLLCSR = 0x00000001; /* LK=0: SPLLCSR can be written */
/* SPLLCMRE=0: SPLL CLK monitor IRQ if enabled */
/* SPLLCM=0: SPLL CLK monitor disabled */
/* SPLLSTEN=0: SPLL disabled in Stop modes */
/* SPLLEN=1: Enable SPLL */
while(!(SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK)); /* Wait for SPLL valid */

// *** MODE CONFIG ***
SCG->RCCR=SCG_RCCR_SCS(6) /* PLL as clock source*/
|SCG_RCCR_DIVCORE(0b01) /* DIVCORE= 2, Core/Sys clock = 80 MHz*/
|SCG_RCCR_DIVBUS(0b11) /* DIVBUS = 4, bus clock = 40 MHz*/
|SCG_RCCR_DIVSLOW(0b111); /* DIVSLOW = 8, SCG slow, flash clock= 20 MHz*/

SMC->PMCTRL = SMC_PMCTRL_RUNM(0b00); //enter RUN

}

void GPIO_Init(void)
{
PCC->PCCn[PCC_PORTD_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: Clock enabled */

PORTD->PCR[0] |= PORT_PCR_MUX(1); /* MUX=1: PTD0, ALT=1 as GPIO */
PORTD->PCR[15] |= PORT_PCR_MUX(1); /* MUX=1: PTD15, ALT=1 as GPIO */
PORTD->PCR[16] |= PORT_PCR_MUX(1); /* MUX=1: PTD16, ALT=1 as GPIO */

PTD->PDDR |= 1<<0 | /* Configure BLUE LED as an output */ //LED on PCOR
1<<15 | /* Configure RED LED as an output */
1<<16; /* Configure GREEN LED as an output */

PTD->PSOR |= 1<<0 | /* Turn off BLUE */
1<<15 | /* Turn off RED */
1<<16; /* Turn off GREEN */

}


void PDB_Init(void)
{
PCC->PCCn[PCC_PDB0_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable bus clock in PDB0 */
// PDB0->CNT especifies de current value of the counter
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 BACK-TO-BACK OPERTATION*/
/* 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; //LOAD OK: activación, cuando PDBEN =0 ---> LDOK=0 por hardware
}


void ADC_Init(void)
{

PCC->PCCn[PCC_ADC0_INDEX] &= ~PCC_PCCn_CGC_MASK; /* Disable clock to change PCS, SINO ERROR */

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 */

/* Configuration Register ADC0 */
ADC0->CFG1 |= ADC_CFG1_ADICLK(0) | /* Only ALTCLK1 is available */ // Selected Clock
ADC_CFG1_ADIV(2) | /* the clock rate is (input clock)/4 */ // Internal clock rate
ADC_CFG1_MODE(1); /* 0b00: 8-bit, 0b01: 12-bit, 0b10: 10-bit */
/* SC: Status and Control Register */
ADC0->SC2 |= ADC_SC2_ADTRG(1) | /* Conversion Trigger: 0b0= SW , 0b1 = HW */
ADC_SC2_DMAEN(1); /* enable DMA trigger */
// Esta leyendo en 4 registros (salidas R[0-3]) la misma entrada
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 WDOG_Disable(void)
{
WDOG->CNT=0xD928C520; /*Unlock watchdog*/
WDOG->CS &= ~WDOG_CS_EN_MASK; /*Disable watchdog*/
}


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 to save the ADC0 data
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
}


void IRQs_Init (void)
{
FSL_NVIC->ICPR[0] = 1 << (0 % 32); /* IRQ0-DMA ch0: clr any pending IRQ*/
FSL_NVIC->ISER[0] = 1 << (0 % 32); /* IRQ0-DMA ch0: enable IRQ */
FSL_NVIC->IP[0] = 0x1; /* IRQ0-DMA ch0: priority 10 of 0-15*/
}


void DMA0_IRQHandler(void)
{
counter++;

salidaADC=result[0]*5000/0xFFF; // El valor máximo que puede medir es 2^12 = 0xFFF = 4095,
// para normalizar hacemos resultado[0]*5000 mV/0xFFF

PDB0->SC |= PDB_SC_SWTRIG_MASK; /* restart PDB counter */

DMA->CINT = 0; // clear DMA channel 0 interrupt flag
}

int main(void)
{


WDOG_Disable();
SCG_Init();
GPIO_Init();
ADC_Init();
PDB_Init();
DMA_init();
DMAMUX_Init();

IRQs_Init();

PDB0->SC |= PDB_SC_SWTRIG_MASK; /* restart PDB counter */

for(;;) {

/* do something with converted data, change color of the LED */
if(salidaADC < 2500 && salidaADC > 10) // El valor máximo que puede medir es 2^12 = 0xFFF = 4095,
{ // para normalizar hacemos resultado[0]*5000 mV/0xFFF

PTD->PSOR |= 1<<16; // PTD16 OFF - GREEN LED

PTD->PCOR |= 1<<15; // PTD15 ON - RED LED

}
if(salidaADC >2500)// El valor máximo que puede medir es [0 - 5000] mV
{

PTD->PSOR |= 1<<15; // PTD15 OFF - RED LED

PTD->PCOR |= 1<<16; // PTD16 ON - GREEN LED

}

}

/* to avoid the warning message for GHS and IAR: statement is unreachable*/
#if defined (__ghs__)
#pragma ghs nowarning 111
#endif
#if defined (__ICCARM__)
#pragma diag_suppress=Pe111
#endif
return 0;
}

 

Thanks,

Jorge

Outcomes