ADCv1 and adcerrorcallback (Analog watchdog problem) Topic is solved
Posted: Sun Nov 03, 2019 10:25 am
Brief description
ADC struct defines:
ADC conversion group:
Error Callback function define (set global flag and on LED)
Callback from ADC (half and complete)
Main code
Now the main problem
1) Starting ADC with value lower than treshold (2000)
All is Ok.
2) Now give at one channel ADC value higher than treshold (more than 2000)
ADC driver stop to call adccallback to update value. All value now is zero.
But main problem - ADC driver never call adcerrorcallback
if ADC set low then treshold then all rollback to normal state.
- - chibios_trunk (latest build from github)
- stm32L031F6
- Enabled Oversampling ADC (16X)
- Enabled Analog WatchDog
- Used ADC 4pcs Channel (0,1,2,4)
ADC struct defines:
Code: Select all
#define ADC_GRP2_NUM_CHANNELS 4
#define ADC_GRP2_BUF_DEPTH 2
/* Variable containing ADC conversions data */
static adcsample_t aADCxConvertedData[ADC_GRP2_NUM_CHANNELS*ADC_GRP2_BUF_DEPTH];
ADC conversion group:
Code: Select all
static const ADCConversionGroup adcgrpcfg2 = {
TRUE,
ADC_GRP2_NUM_CHANNELS,
adccallback,
adcerrorcallback,
ADC_CFGR1_CONT | ADC_CFGR1_RES_12BIT | ADC_CFGR1_AWDEN , /* CFGR1 [glow=red]Enabled Analog WatchDog for all channel[/glow] */
ADC_CFGR2_OVSE | ADC_CFGR2_OVSR_16X, /* CFGR2 [glow=red]Enabled Oversampling ADC[/glow] (16X) */
ADC_TR(0, 2000), /* TR [glow=red]Analog watchdog high treshold set to 2000 [/glow]*/
ADC_SMPR_SMP_41P5, /* SMPR */
ADC_CHSELR_CHSEL0 | ADC_CHSELR_CHSEL1 |
ADC_CHSELR_CHSEL2 | ADC_CHSELR_CHSEL4 /* CHSELR */
};
Error Callback function define (set global flag and on LED)
Code: Select all
volatile uint8_t Blocked_by_WatchDog;
Code: Select all
static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) {
//if(adcp == &ADCD1 && err == ADC_ERR_AWD) {
Blocked_by_WatchDog = 1;
palWriteLine(LINE_LED_STAT, PAL_HIGH);
//}
}
Callback from ADC (half and complete)
Code: Select all
volatile adcsample_t Global_CURR;
volatile adcsample_t Global_AB;
volatile adcsample_t Global_16V;
volatile adcsample_t Global_TEMP;
Code: Select all
static void adccallback(ADCDriver *adcp) {
if (adcIsBufferComplete(adcp)) { // [glow=red]analize all buffer[/glow]
Global_16V=(aADCxConvertedData[3]+aADCxConvertedData[7])/(2*SET_ADC_OVERSAMPLING);
Global_TEMP=(aADCxConvertedData[2]+aADCxConvertedData[6])/(2*SET_ADC_OVERSAMPLING);
Global_AB=(aADCxConvertedData[1]+aADCxConvertedData[5])/(2*SET_ADC_OVERSAMPLING);
Global_CURR=(aADCxConvertedData[0]+aADCxConvertedData[4])/(2*SET_ADC_OVERSAMPLING);
}
else { // [glow=red]analize half of buffer[/glow]
Global_16V=aADCxConvertedData[3]/SET_ADC_OVERSAMPLING;
Global_TEMP=aADCxConvertedData[2]/SET_ADC_OVERSAMPLING;
Global_AB=aADCxConvertedData[1]/SET_ADC_OVERSAMPLING;
Global_CURR=aADCxConvertedData[0]/SET_ADC_OVERSAMPLING;
}
}
Main code
Code: Select all
//Activates the ADC1 driver and the temperature sensor.
adcStart(&ADCD1, NULL);
// start ADC
adcStartConversion(&ADCD1, &adcgrpcfg2, aADCxConvertedData, ADC_GRP2_BUF_DEPTH);
Now the main problem
1) Starting ADC with value lower than treshold (2000)
All is Ok.
2) Now give at one channel ADC value higher than treshold (more than 2000)
ADC driver stop to call adccallback to update value. All value now is zero.
But main problem - ADC driver never call adcerrorcallback
if ADC set low then treshold then all rollback to normal state.