Hi,
I'm trying to configuration ADC triggering by FTM
so, I referred to AN5303 Rev.0, 06/2016.
In there, Example 12 is useful to me for what I wanted.
But, I'm in trouble. I checked to enter PDB interrupt service.
But, my ADC interrupt did't run. I would attached my source code, Could you help me?
first, I'm using "S32 Design Studio for S32 Platform Version: 3.3 Build id: 200610"
and s32k118 device.
And, I modified example code.
/*!
** Copyright 2020 NXP
** @file main.c
** @brief
** Main module.
** This module contains user's application code.
*/
/*!
** @addtogroup main_module main module documentation
** @{
*/
/* MODULE main */
/* Including necessary configuration files. */
#include "sdk_project_config.h"
#include "interrupt_manager.h"
volatile int exit_code = 0;
/* User includes */
/* FTM0 Initialization */
void FTM0_Init()
{
/* Enable clock for PORTD */
PCC->PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK;
/* Select and enable clock for FTM0 */
PCC->PCCn[PCC_FTM0_INDEX] = PCC_PCCn_PCS(6) | PCC_PCCn_CGC_MASK;
PORTD->PCR[15] = PORT_PCR_MUX(2); // Set PTD15 for FTM0 – Channel0
PORTD->PCR[16] = PORT_PCR_MUX(2); // Set PTD16 for FTM0 – Channel1
PORTD->PCR[2] = PORT_PCR_MUX(1); // Set PTD2 as a PTD2
//PORTD->PCR[3] = PORT_PCR_MUX(1); // Set PTD3 as a PTD3
PTD->PDDR = (1<<2); // Set PTD2 and PTD3 as an output
/* Select up-down counter for Center-Align PWM */
FTM0->SC = FTM_SC_CPWMS_MASK;
/* Enable combine, complementary mode and dead-time for channels pair CH0/CH1 and CH2/CH3 */
FTM0->COMBINE = FTM_COMBINE_SYNCEN0_MASK | FTM_COMBINE_COMP0_MASK | FTM_COMBINE_DTEN0_MASK;
/* Set Modulo (10kHz PWM frequency @112MHz system clock) */
//FTM0->MOD = FTM_MOD_MOD(5600-1);
FTM0->MOD = FTM_MOD_MOD(12000);
/* Set CNTIN */
FTM0->CNTIN = FTM_CNTIN_INIT(0);
/* High-true pulses of PWM signals */
FTM0->CONTROLS[0].CnSC = FTM_CnSC_ELSB_MASK;
FTM0->CONTROLS[1].CnSC = FTM_CnSC_ELSB_MASK;
/* Set Channel Value */
FTM0->CONTROLS[0].CnV=FTM_CnV_VAL(2800); // 50% duty cycle
FTM0->CONTROLS[1].CnV=FTM_CnV_VAL(2800); // 50% duty cycle
/* FTM counter reset */
FTM0->CNT = 0;
/* Insert DeadTime (1us) */
FTM0->DEADTIME = FTM_DEADTIME_DTPS(3) | FTM_DEADTIME_DTVAL(7);
/* Enable trigger generation when FTM counter = CNTIN */
FTM0->EXTTRIG = FTM_EXTTRIG_INITTRIGEN_MASK;
/* Enable clock and PWM */
FTM0->SC |= FTM_SC_CLKS(1) | FTM_SC_PWMEN0_MASK | FTM_SC_PWMEN1_MASK;
}
/* PDB0 Initialization */
void PDB0_Init()
{
PCC->PCCn[PCC_PDB0_INDEX] = PCC_PCCn_CGC_MASK; // Enable clock for PDB0
INT_SYS_EnableIRQ(PDB0_IRQn);// Enable interrupt
//PDB0->MOD = 11200; // Set Modulo
PDB0->MOD = 1120; // Set Modulo
PDB0->CH[0].C1 = PDB_C1_TOS(1) | PDB_C1_EN(1); // Select and enable Channel0
//PDB0->CH[0].DLY[0] = 5600; // Set delay
PDB0->CH[0].DLY[0] = 1000; // Set delay
PDB0->IDLY = 0; // Set interrupt delay
PDB0->SC |= PDB_SC_PRESCALER(0) | PDB_SC_MULT(0); // Select clock prescaler and mult factor
/* Select trigger input source and enable interrupt */
PDB0->SC |= PDB_SC_TRGSEL(0) | PDB_SC_PDBIE_MASK;
/* Enable PDB and update PDB registers */
PDB0->SC |= PDB_SC_PDBEN_MASK | PDB_SC_LDOK_MASK;
}
/* TRGMUX Initialization */
void TRGMUX_Init()
{
//PCC->PCCn[PCC_TRGMUX_INDEX] = PCC_PCCn_CGC_MASK; // Enable clock for TRGMUX module
/* Set FTM as a trigger source for PDB0 */
TRGMUX->TRGMUXn[TRGMUX_PDB0_INDEX] = TRGMUX_TRGMUXn_SEL0(0x16);
}
void ADC0_Init()
{
PCC->PCCn[PCC_ADC0_INDEX] = 0; // Disable clock for ADC0
PCC->PCCn[PCC_ADC0_INDEX] = PCC_PCCn_PCS(6) | PCC_PCCn_CGC_MASK; // Enable clock for ADC0
PCC->PCCn[PCC_ADC0_INDEX] &= ~PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_ADC0_INDEX] &= ~PCC_PCCn_PCS(3);
PCC->PCCn[PCC_ADC0_INDEX] &= ~PCC_PCCn_PCS_MASK;
while(((ADC0->SC1[0] & ADC_SC1_COCO_MASK) >> ADC_SC1_COCO_SHIFT) == 0);
/* Set divide ratio to 1 and select 8-bit conversion */
ADC0->CFG1 = ADC_CFG1_ADIV(0) | ADC_CFG1_MODE(0) | ADC_CFG1_ADICLK(0);
/* Select hardware trigger */
ADC0->SC2 = ADC_SC2_ADTRG_MASK;
/* Select channel 12 as an input and enable conversion complete interrupt */
ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(12);
INT_SYS_EnableIRQ(ADC0_IRQn); // Enable interrupt
}
uint32_t buff;
/* ADC0 interrupt routine */
void ADC0_IRQHandler(void)
{
PTD->PTOR |= 1<<2;
buff = ADC0->R[0]; // Read ADC result register
}
/* PDB0 interrupt routine */
void PDB0_IRQHandler(void)
{
PTD->PTOR |= 1<<2;
// PTD->PTOR |= 1<<2; // Toggle PTD2 to show FTM0 trigger signal
PDB0->SC &= ~PDB_SC_PDBIF_MASK; // Clear PDB interrupt flag
}
void Edge_Align_PWM_Init()
{
/* Enable clock for PORTD */
PCC->PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK;
/* Select and enable clock for FTM0 */
PCC->PCCn[PCC_FTM0_INDEX] = PCC_PCCn_PCS(6) | PCC_PCCn_CGC_MASK;
/* Set PORTD pins for FTM0 */
PORTD->PCR[15] = PORT_PCR_MUX(2); // FTM0, Channel0
PORTD->PCR[16] = PORT_PCR_MUX(2); // FTM0, Channel1
PORTD->PCR[2] = PORT_PCR_MUX(1); // Set PTD2 as a PTD2
//PORTD->PCR[3] = PORT_PCR_MUX(1); // Set PTD3 as a PTD3
PTD->PDDR = (1<<2); // Set PTD2 and PTD3 as an output
/* Enable registers updating from write buffers */
FTM0->MODE = FTM_MODE_FTMEN_MASK;
/* Enable sync, combine mode and dead-time for pair channel n=1 and n=2 */
//FTM0->COMBINE = FTM_COMBINE_COMP0_MASK | FTM_COMBINE_DTEN0_MASK;
/* Set Modulo in initialization stage (10kHz PWM frequency @112MHz system clock) */
FTM0->MOD = FTM_MOD_MOD(11200-1);
/* Set CNTIN in initialization stage */
FTM0->CNTIN = FTM_CNTIN_INIT(0);
/* Enable high-true pulses of PWM signals */
FTM0->CONTROLS[0].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;
FTM0->CONTROLS[1].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;
/* Set channel value in initialization stage */
FTM0->CONTROLS[0].CnV=FTM_CnV_VAL(2800); // 50% duty cycle
FTM0->CONTROLS[1].CnV=FTM_CnV_VAL(5600); // 50% duty cycle
/* Reset FTM counter */
FTM0->CNT = 0;
/* Insert deadtime (1us) */
FTM0->DEADTIME = FTM_DEADTIME_DTPS(3) | FTM_DEADTIME_DTVAL(7);
FTM0->EXTTRIG = FTM_EXTTRIG_INITTRIGEN_MASK;
/* Clock selection and enabling PWM generation */
FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PWMEN0_MASK | FTM_SC_PWMEN1_MASK ;
FTM0->MODE &= ~FTM_MODE_FTMEN(1);
}
/*!
\brief The main function for the project.
\details The startup initialization sequence is the following:
* - startup asm routine
* - main()
*/
volatile uint8_t swit;
FTM_Type * FlexTimer = FTM0;
void Change_DutyA(void)
{
FlexTimer->CONTROLS[0].CnV=FTM_CnV_VAL(1000); // 50% duty cycle
// FlexTimer->CONTROLS[1].CnV=FTM_CnV_VAL(5600); // 50% duty cycle
}
void Change_DutyB(void)
{
FlexTimer->CONTROLS[0].CnV=FTM_CnV_VAL(5000); // 50% duty cycle
// FlexTimer->CONTROLS[1].CnV=FTM_CnV_VAL(2800); // 50% duty cycle
}
int main(void)
{
/* Write your code here */
/*//─────────────────────────────────────────────────────────────────────────────────────────────
* Clock Configuration *
*///─────────────────────────────────────────────────────────────────────────────────────────────
CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT, g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
//FTM0_Init();
Edge_Align_PWM_Init();
ADC0_Init();
TRGMUX_Init();
PDB0_Init();
for(;;)
{
if(swit == 1)
{
swit = 0;
Change_DutyA();
//FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PWMEN0_MASK | FTM_SC_PWMEN1_MASK ;
}
else if(swit == 2)
{
swit = 0;
Change_DutyB();
//FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PWMEN0_MASK | FTM_SC_PWMEN1_MASK ;
}
if(exit_code != 0)
{
break;
}
}
return exit_code;
}
/* END main */
/*!
** @}
*/
Hi,
enabling ADC0 clocks looks quite weird, check actual PCC->PCCn[PCC_ADC0_INDEX] value.
obviously below is used, set PCS as needed...
PCC->PCCn[PCC_ADC0_INDEX] &=~ PCC_PCCn_CGC_MASK; /* Disable clock to change PCS */
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_PCS(1); /* PCS=1: Select SOSCDIV2 */
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable bus clock in ADC */
BR, Petr