I have an application that brings together TPM demo code to turn on/off LED's and sample ADC to measure battery voltage. The program works fine when in Normal Run mode, however, when I try to use VLPR mode I get a HardFault_Handler exception when trying to configure the ADC Channel.
In VLPR, I have the TPM working fine. Subtle adjustments to the clock source and clock source identifier, but with the ADC setup, I am at a loss.
Using the default SDK 2.0 adc demo configuration when initializing:
void ADC_HWInit(void){
// init the Internal Voltage Referrence Signal
VREF_GetDefaultConfig(&vrefConfigStruct);
VREF_Init(VREF, &vrefConfigStruct);
// init adc
/*
* adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
* adc16ConfigStruct.clockSource = kADC16_ClockSourceAsynchronousClock;
* adc16ConfigStruct.enableAsynchronousClock = true;
* adc16ConfigStruct.clockDivider = kADC16_ClockDivider8;
* adc16ConfigStruct.resolution = kADC16_ResolutionSE12Bit;
* adc16ConfigStruct.longSampleMode = kADC16_LongSampleDisabled;
* adc16ConfigStruct.enableHighSpeed = false;
* adc16ConfigStruct.enableLowPower = false;
* adc16ConfigStruct.enableContinuousConversion = false;
*/
ADC16_GetDefaultConfig(&adc16ConfigStruct);
ADC16_Init(ADC16_BASE, &adc16ConfigStruct);
ADC16_EnableHardwareTrigger(ADC16_BASE, false); /* Make sure the software trigger is used. */
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
if (kStatus_Success == ADC16_DoAutoCalibration(ADC16_BASE))
{
Console_Printf(BOARD_DEBUG_UART_BASEADDR, "\r\nADC16_DoAutoCalibration() Done.\r\n");
}
else
{
Console_Printf(BOARD_DEBUG_UART_BASEADDR, "\r\nADC16_DoAutoCalibration() Failed.\r\n");
//ToDo::save error code and set error transmit flag to report in next packet
}
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
//config channels and interrupt
adc16ChannelConfigStruct.channelNumber = ADC16_USER_CHANNEL;
adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = false;
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
adc16ChannelConfigStruct.enableDifferentialConversion = false;
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
}
The hard fault occurs in fsl_adc16.c, when calling ADC16_SetChannelConfig().
void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config)
{
assert(channelGroup < ADC_SC1_COUNT);
assert(NULL != config);
uint32_t sc1 = ADC_SC1_ADCH(config->channelNumber); /* Set the channel number. */
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
/* Enable the differential conversion. */
if (config->enableDifferentialConversion)
{
sc1 |= ADC_SC1_DIFF_MASK;
}
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
/* Enable the interrupt when the conversion is done. */
if (config->enableInterruptOnConversionCompleted)
{
sc1 |= ADC_SC1_AIEN_MASK;
}
base->SC1[channelGroup] = sc1; // Hard Fault Occurs Here!!!
}
Like I said, this works perfectly in Normal Run mode. Not so in VLPR.
In VLPR, I've tried changing the clock source to the Bus Clock, which uses the system core clock. I've also played with the dividers. In my setup, I am using the default code for clock_config.c when calling BOARD_BootClockVLPR().
Any ideas to a path would be greatly appreciated.
Solved! Go to Solution.
Turns out...this is all on me. Before entering into a VLPS mode, I de-inited the ADC. Upon return from sleep, I was not re-initializing in my power management module. Hence, the hard fault.
With the re-init, all is well.
Turns out...this is all on me. Before entering into a VLPS mode, I de-inited the ADC. Upon return from sleep, I was not re-initializing in my power management module. Hence, the hard fault.
With the re-init, all is well.
By the way, I forgot to mention that Hard Faults like this are most likely due to the clock not being set for the specific module one is trying to write to.
I'm starting to think that there is a default register config for the ADC0 module to operate under Normal Run mode. The SDK 2.0 may not be setting this and, thus, no interface when using VLPR mode??