AnsweredAssumed Answered

KL25Z ADC triggering PIT with KSDK 2.0

Question asked by Gustavo Leal on Oct 4, 2016
Latest reply on Oct 21, 2016 by Mark Wyman

I'm using a custom board with KL25Z and trying to convert a single ADC input using the ADC interrupt.

Starting from the KSDK 2.0 ADC low power example, I have tried to convert it from using LPTMR to use PIT.

However, it seems that even after setting the SIM->SOPT7 register, the interrupt won't trigger. I never see the toggling LED and the ADC doesn't convert.

 

How do I implement this?

 

Here's my code:

 

/*******************************************************************************
* Definitions
******************************************************************************/
#define PIT_LED_HANDLER PIT_IRQHandler
#define PIT_IRQ_ID PIT_IRQn
/* Get source clock for PIT driver */
#define PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
#define ADC_BASE_ADDR ADC0
#define ADC_CHANNEL_GROUP 0U
#define ADC_USER_CHANNEL 0U

#define ADC_IRQ_ID ADC0_IRQn
#define ADC_IRQ_HANDLER_FUNC ADC0_IRQHandler


/*******************************************************************************
* Variables
******************************************************************************/
volatile static uint32_t adcValue = 0; /*! ADC value */
volatile bool conversionCompleted = false; /*! Conversion is completed Flag */
volatile bool pitIsrFlag = false;
volatile static uint16_t samplesCounter = 0;


/*******************************************************************************
* Code
******************************************************************************/

void BOARD_ConfigTriggerSource(void)
{
/* Configure SIM for ADC hw trigger source selection */
SIM->SOPT7 |= (SIM_SOPT7_ADC0ALTTRGEN(1) | SIM_SOPT7_ADC0PRETRGSEL(0) | SIM_SOPT7_ADC0TRGSEL(0x4));
}

 

void PIT_InitADCTriggerSource(void)
{
// Initialise PIT0 module and enable run in debug
pit_config_t pitConfig =
{
.enableRunInDebug = true
};
/* Init PIT */
PIT_Init(PIT,&pitConfig);


/* Set 62us interrupt */
PIT_SetTimerPeriod(PIT,kPIT_Chnl_0, USEC_TO_COUNT(62U, PIT_SOURCE_CLOCK));


/* Start counting on channel 0 */
PIT_StartTimer(PIT, kPIT_Chnl_0);


/* Configure SIM for ADC hw trigger source selection */
BOARD_ConfigTriggerSource();
}

static void ADC16_PauseConversion(ADC_Type *base)
{
adc16_channel_config_t adcChnConfig;
adcChnConfig.channelNumber = 0U; /*!< AD0 channel */
adcChnConfig.enableInterruptOnConversionCompleted = false;
adcChnConfig.enableDifferentialConversion = false;
ADC16_SetChannelConfig(base, ADC_CHANNEL_GROUP, &adcChnConfig);
}


static void ADC16_CalibrateParams(ADC_Type *base)
{
adc16_config_t adcUserConfig;
adc16_channel_config_t adcChnConfig;

ADC16_GetDefaultConfig(&adcUserConfig);
adcUserConfig.resolution = kADC16_Resolution16Bit;
adcUserConfig.enableContinuousConversion = false;
adcUserConfig.clockSource = kADC16_ClockSourceAsynchronousClock;
adcUserConfig.enableLowPower = 1;
ADC16_Init(base, &adcUserConfig);
adcChnConfig.enableInterruptOnConversionCompleted = false;
ADC16_SetChannelConfig(base, ADC_CHANNEL_GROUP, &adcChnConfig);
/* Wait for the conversion to be done */
while (!ADC16_GetChannelStatusFlags(base, ADC_CHANNEL_GROUP))
{
}
ADC16_PauseConversion(base);
}


static bool ADC16_InitHardwareTrigger(ADC_Type *base)
{
adc16_config_t adcUserConfig;
adc16_channel_config_t adcChnConfig;

ADC16_GetDefaultConfig(&adcUserConfig);
adcUserConfig.resolution = kADC16_Resolution16Bit;
/* enabled hardware trigger */
ADC16_EnableHardwareTrigger(base, true);
adcUserConfig.enableContinuousConversion = false;
adcUserConfig.clockSource = kADC16_ClockSourceAsynchronousClock;
adcUserConfig.longSampleMode = kADC16_LongSampleCycle24;
adcUserConfig.enableLowPower = 1;
ADC16_Init(base, &adcUserConfig);
adcChnConfig.channelNumber = ADC_USER_CHANNEL;
adcChnConfig.enableDifferentialConversion = false;
adcChnConfig.enableInterruptOnConversionCompleted = true;
/* Configure channel 0 */
ADC16_SetChannelConfig(base, ADC_CHANNEL_GROUP, &adcChnConfig);
return true;
}


void ADC16_IRQ_HANDLER_FUNC(void)
{
/* Get current ADC value */
adcValue = ADC16_GetChannelConversionValue(ADC_BASE_ADDR, ADC_CHANNEL_GROUP);
/* Set conversionCompleted flag. This prevents an wrong conversion in main function */
conversionCompleted = true;
LED_BLUE_TOGGLE();
}


void LEDInit(void)
{
LED_RED_INIT(LOGIC_LED_OFF);
LED_GREEN_INIT(LOGIC_LED_OFF);
LED_BLUE_INIT(LOGIC_LED_OFF);
LED_YELLOW_INIT(LOGIC_LED_OFF);
}

 

int main(void)
{
pit_config_t pitConfig
   {
   .enableRunInDebug = true
   };

BOARD_InitPins();
BOARD_BootClockRUN();
LEDInit();
ADC16_CalibrateParams(ADC0);
if (!ADC16_InitHardwareTrigger(ADC_BASE_ADDR))
{
   LED_RED_ON();
   return -1;
}
PIT_GetDefaultConfig(&pitConfig);
/* Init pit module */
PIT_Init(PIT, &pitConfig);
/* Set timer period for channel 0 */
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, USEC_TO_COUNT(100U, PIT_SOURCE_CLOCK));
PIT_StartTimer(PIT, kPIT_Chnl_0);
/* Enable timer interrupts for channel 0 */
//PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable);
BOARD_ConfigTriggerSource();
/* Enable at the NVIC */
EnableIRQ(ADC_IRQ_ID);
/* Start channel 0 */
PIT_StartTimer(PIT, kPIT_Chnl_0);
   for(;;) /* Infinite loop to avoid leaving the main function */
   {
/* Check whether occur interupt and toggle LED */
   if (conversionCompleted)
      {
      LED_GREEN_ON();
      }
   }
}   

Outcomes