From 379f5aa71bfd617ef9a779abe3a41dd3cddb400c Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Fri, 13 Aug 2021 21:51:22 +0200 Subject: [PATCH] Refactoring of GDx ADC1 driver: added function allowing to retrieve the raw conversion value, changed return value of 'adc1_getMeasurement' from float to uint16_t --- platform/drivers/ADC/ADC0_GDx.c | 21 +++++++++++++++++---- platform/drivers/ADC/ADC0_GDx.h | 9 ++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/platform/drivers/ADC/ADC0_GDx.c b/platform/drivers/ADC/ADC0_GDx.c index 496db9a1..af37fdf1 100644 --- a/platform/drivers/ADC/ADC0_GDx.c +++ b/platform/drivers/ADC/ADC0_GDx.c @@ -49,15 +49,28 @@ void adc0_terminate() SIM->SCGC6 &= ~SIM_SCGC6_ADC0(1); } -float adc0_getMeasurement(uint8_t ch) +uint16_t adc0_getRawSample(uint8_t ch) { - if(ch > 32) return 0.0f; + if(ch > 32) return 0; /* Conversion is automatically initiated by writing to this register */ ADC0->SC1[0] = ADC_SC1_ADCH(ch); while(((ADC0->SC1[0]) & ADC_SC1_COCO_MASK) == 0) ; - uint16_t sample = ADC0->R[0]; - return ((float) sample) * 3300.0f/65536.0f; + return ADC0->R[0]; +} + +uint16_t adc0_getMeasurement(uint8_t ch) +{ + /* + * To avoid using floats, we convert the raw ADC sample to mV using 16.16 + * fixed point math. The equation for conversion is (sample * 3300)/4096 but, + * since converting the raw ADC sample to 16.16 notation requires a left + * shift by 16 and dividing by 4096 is equivalent to shifting right by 12, + * we just shift left by four and then multiply by 3300. + * With respect to using floats, maximum error is -1mV. + */ + uint32_t sample = (adc0_getRawSample(ch) << 4) * 3300; + return ((uint16_t) (sample >> 16)); } diff --git a/platform/drivers/ADC/ADC0_GDx.h b/platform/drivers/ADC/ADC0_GDx.h index ccd59e6a..004c7a60 100644 --- a/platform/drivers/ADC/ADC0_GDx.h +++ b/platform/drivers/ADC/ADC0_GDx.h @@ -30,11 +30,18 @@ void adc0_init(); */ void adc0_terminate(); +/** + * Get current measurement of a given channel returning the raw ADC value. + * @param ch: channel number. + * @return current value of the specified channel, in ADC counts. + */ +uint16_t adc0_getRawSample(uint8_t ch); + /** * Get current measurement of a given channel. * @param ch: channel number. * @return current value of the specified channel in mV. */ -float adc0_getMeasurement(uint8_t ch); +uint16_t adc0_getMeasurement(uint8_t ch); #endif /* ADC0_H */