S32K144 2 ADC with PDB Trigger Hi, I am trying to sample 2 ADCs with 4 Channels each with 1 PDB module. i am trying to sample both ADCs continuously and send an interrupt on when the 4th Conversion is done (for each ADC) then write it to my terminal. I have multiple questions: 1. it samples only ADC0 one time and stops (ADC1 is not sampled at all and ADC0 is only sampled once). why? 2. The results are not written to my terminal. i programmed a print function in the ADC handler. why? PS: i tried the continous mode for the pdb and the back to back mode for the pretriggers. void print(const char *sourceStr) { uint32_t bytesRemaining; /* Send data via LPUART */ LPUART_DRV_SendData(INST_LPUART_1, (uint8_t *) sourceStr, strlen(sourceStr)); // LPUART_DRV_SendDataPolling(INST_LPUART_1, (uint8_t *) sourceStr, strlen(sourceStr)); /* Wait for transmission to be successful */ while (LPUART_DRV_GetTransmitStatus(INST_LPUART_1, &bytesRemaining) != STATUS_SUCCESS) { } } /* The IRQ handler uses the default IRQ handler weak symbol defined in startup (.S) file */ void PDB0_IRQHandler(void) { /* Clear PDB instance Interrupt flag */ PDB_DRV_ClearTimerIntFlag(INST_PDB_0); print("Timer restarting"); } void ADC0_IRQHandler(void) { /* Clear PDB instance Interrupt flag */ PDB_DRV_ClearTimerIntFlag(INST_PDB_0); if(ADC_DRV_GetConvCompleteFlag(INST_ADC_CONFIG_1, 3)){ ADC_DRV_GetChanResult(INST_ADC_CONFIG_1,0U, &res[0]); ADC_DRV_GetChanResult(INST_ADC_CONFIG_1,1U, &res[1]); ADC_DRV_GetChanResult(INST_ADC_CONFIG_1,2U, &res[2]); ADC_DRV_GetChanResult(INST_ADC_CONFIG_1,3U, &res[3]); adcConvDone = true; inc++; for(int i = 0; i<4 ; i++){ print("ADC 0 results are :"); uint16ToStr(&res[i], msg[i], 5); print(msg[i]); } } else counter++; } void ADC1_IRQHandler (void){ // /* Clear PDB instance Interrupt flag */ PDB_DRV_ClearTimerIntFlag(INST_PDB_0); if(ADC_DRV_GetConvCompleteFlag(INST_ADC_CONFIG_2, 3)){ ADC_DRV_GetChanResult(INST_ADC_CONFIG_2,0U, &res1[0]); ADC_DRV_GetChanResult(INST_ADC_CONFIG_2,1U, &res1[1]); ADC_DRV_GetChanResult(INST_ADC_CONFIG_2,2U, &res1[2]); ADC_DRV_GetChanResult(INST_ADC_CONFIG_2,3U, &res1[3]); for(int j = 0; j<4 ; j++){ print("ADC 1 results are :"); uint16ToStr(&res1[j], msg1[j], 5); print(msg1[j]); } } } bool calculateIntValue(const pdb_timer_config_t * const pdbConfig, const uint32_t uSec, uint16_t * const intVal) { /* Local variables used to store different parameters * such as frequency and prescalers */ uint32_t intVal_l = 0; uint8_t pdbPrescaler = (1 << pdbConfig->clkPreDiv); uint8_t pdbPrescalerMult = 0; uint32_t pdbFrequency; bool resultValid = false; /* Get the Prescaler Multiplier from the configuration structure */ switch (pdbConfig->clkPreMultFactor) { case PDB_CLK_PREMULT_FACT_AS_1: pdbPrescalerMult = 1U; break; case PDB_CLK_PREMULT_FACT_AS_10: pdbPrescalerMult = 10U; break; case PDB_CLK_PREMULT_FACT_AS_20: pdbPrescalerMult = 20U; break; case PDB_CLK_PREMULT_FACT_AS_40: pdbPrescalerMult = 40U; break; default: /* Defaulting the multiplier to 1 to avoid dividing by 0*/ pdbPrescalerMult = 1U; break; } /* Get the frequency of the PDB clock source and scale it * so that the result will be in microseconds */ CLOCK_SYS_GetFreq(CORE_CLK, &pdbFrequency); pdbFrequency /= 1000000; /* Calculate the interrupt value for the prescaler, multiplier, frequency * configured and time needed. */ intVal_l = (pdbFrequency * uSec) / (pdbPrescaler * pdbPrescalerMult ); /* Check if the value belongs to the interval */ if((intVal_l == 0) || (intVal_l >= (1 << 16))) { resultValid = false; (*intVal) = 0U; } else { resultValid = true; (*intVal) = (uint16_t)intVal_l; } return resultValid; } //char msg[30]; uint16_t dutyCycle = 0U; int main(void) { status_t error; /* Configure clocks for PORT */ CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT, g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT); CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT); /* Set pins as GPIO */ error = PINS_DRV_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0); DEV_ASSERT(error == STATUS_SUCCESS); /* Set Output value LED_Green & LED_Red */ PINS_DRV_SetPins(LED_Green_PORT, 1 << LED_Green_PIN); // //PINS_DRV_SetPins(LED_Red_PORT, 1 << LED_Red_PIN); uint16_t pdbTimerVal; char value[30]; if (LPUART_DRV_Init(INST_LPUART_1, &lpUartState0, &lpuart_0_InitConfig0) != STATUS_SUCCESS) __asm("bkpt #255"); ftm_state_t ftmStateStruct; /* Initialize FTM instance */ FTM_DRV_Init(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_InitConfig, &ftmStateStruct); /* Initialize FTM PWM */ FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig); /*ADC0 and ADC1 Configuration*/ ADC_DRV_ConfigConverter(INST_ADC_CONFIG_1, &adc_config_1_ConvConfig0); ADC_DRV_ConfigConverter(INST_ADC_CONFIG_2, &adc_config_2_ConvConfig0); /*ADC0 and ADC1 Auto Calibration*/ ADC_DRV_AutoCalibration(INST_ADC_CONFIG_1); ADC_DRV_AutoCalibration(INST_ADC_CONFIG_2); /*PDB Configuration*/ PDB_DRV_Init(INST_PDB_0,&pdb_config_1_timerConfig0); /*ADC0 Channel Configuration*/ ADC_DRV_ConfigChan(INST_ADC_CONFIG_1, 0U, &Current_Sense_3); ADC_DRV_ConfigChan(INST_ADC_CONFIG_1, 1U, &Voltage_Sense_2); ADC_DRV_ConfigChan(INST_ADC_CONFIG_1, 2U, &Voltage_Sense_3); ADC_DRV_ConfigChan(INST_ADC_CONFIG_1, 3U, &Current_Sense_2); /*ADC1 Channel Configuration*/ ADC_DRV_ConfigChan(INST_ADC_CONFIG_2, 0U, &Current_Sense_1); ADC_DRV_ConfigChan(INST_ADC_CONFIG_2, 1U, &Current_Sense_4); ADC_DRV_ConfigChan(INST_ADC_CONFIG_2, 2U, &Voltage_Sense_1); ADC_DRV_ConfigChan(INST_ADC_CONFIG_2, 3U, &Voltage_Sense_4); /*Check if the Interrupt value is ok*/ DEV_ASSERT(calculateIntValue(&pdb_config_1_timerConfig0, TIMEOUT_US, &pdbTimerVal) == true); /*Pre-Trigger Configuration for ADC0 (CH0 of the PDB)*/ PDB_DRV_ConfigAdcPreTrigger(INST_PDB_0,0,&pdb_config_1_adc0TrigConfig0); PDB_DRV_ConfigAdcPreTrigger(INST_PDB_0,0,&pdb_config_1_adc0TrigConfig1); PDB_DRV_ConfigAdcPreTrigger(INST_PDB_0,0,&pdb_config_1_adc0TrigConfig2); PDB_DRV_ConfigAdcPreTrigger(INST_PDB_0,0,&pdb_config_1_adc0TrigConfig3); /*Pre-Trigger Configuration for ADC1 (CH1 of the PDB)*/ PDB_DRV_ConfigAdcPreTrigger(INST_PDB_0,1,&pdb_config_1_adc1TrigConfig0); PDB_DRV_ConfigAdcPreTrigger(INST_PDB_0,1,&pdb_config_1_adc1TrigConfig1); PDB_DRV_ConfigAdcPreTrigger(INST_PDB_0,1,&pdb_config_1_adc1TrigConfig2); PDB_DRV_ConfigAdcPreTrigger(INST_PDB_0,1,&pdb_config_1_adc1TrigConfig3); /*set the Modulus value*/ PDB_DRV_SetTimerModulusValue(INST_PDB_0, pdbTimerVal); /*set Pre-Trigger Delays for PDB CH0*/ PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB_0, 0, 0, 400); PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB_0, 0, 1, 800); PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB_0, 0, 2, 1200); PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB_0, 0, 3, 1400); /*set Pre-Trigger Delays for PDB CH1*/ PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB_0, 1, 0, 400); PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB_0, 1, 1, 800); PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB_0, 1, 2, 1200); PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB_0, 1, 3, 1400); INT_SYS_EnableIRQ(PDB0_IRQn); /*set the Interrupt value*/ PDB_DRV_SetValueForTimerInterrupt(INST_PDB_0, pdbTimerVal); print("pdbTimerVal :"); uint16ToStr(&pdbTimerVal, value, 5); print(value); /*Load Values into the PDB*/ PDB_DRV_LoadValuesCmd(INST_PDB_0); /*Enable the PDB*/ PDB_DRV_Enable(INST_PDB_0); /*enable NVIC Interrupts for ADC0*/ INT_SYS_EnableIRQ(ADC0_IRQn); /*enable NVIC Interrupts for ADC1*/ INT_SYS_EnableIRQ(ADC1_IRQn); /* Trigger PDB timer */ PDB_DRV_SoftTriggerCmd(INST_PDB_0); Re: S32K144 2 ADC with PDB Trigger I'm using PTD2 (ADC1 channe2)and PTE6(ADC1 channel 11) to read analog values.The structure defined for PDB_DRV_ConfigAdcPreTrigger API is shown below. const pdb_adc_pretrigger_config_t pdb_1_adcTrigConfig0 = { .adcPreTriggerIdx = 0U, .preTriggerEnable = true, .preTriggerOutputEnable = true, .preTriggerBackToBackEnable = false }; const pdb_adc_pretrigger_config_t pdb_1_adcTrigConfig1 = { .adcPreTriggerIdx = 3U, .preTriggerEnable = true, .preTriggerOutputEnable = true, .preTriggerBackToBackEnable = true }; const adc_chan_config_t adConv1_ChnConfig0 = { .interruptEnable = true, .channel = ADC_INPUTCHAN_EXT2 }; const adc_converter_config_t adConv1_ConvConfig0 = { .clockDivide = ADC_CLK_DIVIDE_1, .sampleTime = 12U, .resolution = ADC_RESOLUTION_12BIT, .inputClock = ADC_CLK_ALT_1, .trigger = ADC_TRIGGER_HARDWARE, .pretriggerSel = ADC_PRETRIGGER_SEL_PDB, .triggerSel = ADC_TRIGGER_SEL_PDB, .dmaEnable = false, .voltageRef = ADC_VOLTAGEREF_VREF, .continuousConvEnable = true, .supplyMonitoringEnable = false }; const adc_chan_config_t adConv1_ChnConfig1 = { .interruptEnable = true, .channel = ADC_INPUTCHAN_EXT11 }; I'm not able read the analog value from PTE6 pin. Please let me know where I'm going wrong. I have attached the codebase below. Re: S32K144 2 ADC with PDB Trigger hi,I Have a problem, What is TrgmuxOut2? I can't understand what is TrgmuxOut2 as Trigger object? Re: S32K144 2 ADC with PDB Trigger Hi@snow3847
if you use FTM Init Trigger as PDB trigger source then you don't need to do it, because it is a internal signal. Re: S32K144 2 ADC with PDB Trigger do i need to map the TRGMUX also in the pinout section? Re: S32K144 2 ADC with PDB Trigger Hi@snow3847
For FTM,you can use FTM init as Trigger source.
For example:
Enable FTM init trigger:
Re: S32K144 2 ADC with PDB Trigger Hi, Thank you for the response. Now i understand that PDB0 is for ADC0 and PDB1 is for ADC1 but i have a question : how do i synchronise them? i want the conversion on ADC0 and on ADC1 to start on the same time. if i understood correctly we should use TRGMUX and FTM. if so can you tell me to parametrise TRGMUX (in the pinout section and peripheral section of s32DS) because i barely found documentation on that. i will attach what i did under my reply. thank you . Re: S32K144 2 ADC with PDB Trigger Hi@snow3847
But in your code, One PDB instance to trigger two ADC instances.
View full article