From f38ce61dc9f28a3ea3007ad8357bc1eb9355520b Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Tue, 22 Dec 2020 15:29:32 +0100 Subject: [PATCH] ADC driver for GDx targets --- meson.build | 2 + platform/drivers/ADC/ADC0_GDx.c | 63 +++++++++++++++++++++++++++++ platform/drivers/ADC/ADC0_GDx.h | 40 ++++++++++++++++++ platform/targets/DM-1801/platform.c | 30 ++++++++++++-- platform/targets/GD77/platform.c | 30 ++++++++++++-- 5 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 platform/drivers/ADC/ADC0_GDx.c create mode 100644 platform/drivers/ADC/ADC0_GDx.h diff --git a/meson.build b/meson.build index 9e376526..96a388d9 100644 --- a/meson.build +++ b/meson.build @@ -224,6 +224,7 @@ mduv380_def = def + stm32f405_def + {'PLATFORM_MDUV380': ''} gd77_src = src + mk22fn512_src + ['platform/targets/GD77/platform.c', 'platform/drivers/display/UC1701_GD77.c', 'platform/drivers/keyboard/keyboard_GD77.c', + 'platform/drivers/ADC/ADC0_GDx.c', 'platform/drivers/baseband/rtx_GDx.c'] gd77_inc = inc + mk22fn512_inc + ['platform/targets/GD77'] @@ -234,6 +235,7 @@ gd77_def = def + mk22fn512_def + {'PLATFORM_GD77': ''} dm1801_src = src + mk22fn512_src + ['platform/targets/DM-1801/platform.c', 'platform/drivers/display/UC1701_GD77.c', 'platform/drivers/keyboard/keyboard_GD77.c', + 'platform/drivers/ADC/ADC0_GDx.c', 'platform/drivers/baseband/rtx_GDx.c'] dm1801_inc = inc + mk22fn512_inc + ['platform/targets/DM-1801'] diff --git a/platform/drivers/ADC/ADC0_GDx.c b/platform/drivers/ADC/ADC0_GDx.c new file mode 100644 index 00000000..496db9a1 --- /dev/null +++ b/platform/drivers/ADC/ADC0_GDx.c @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include "ADC0_GDx.h" + +void adc0_init() +{ + SIM->SCGC6 |= SIM_SCGC6_ADC0(1); + + ADC0->CFG1 |= ADC_CFG1_ADIV(3) /* Divide clock by 8 */ + | ADC_CFG1_ADLSMP(1) /* Long sample time */ + | ADC_CFG1_MODE(3); /* 16 bit result */ + + ADC0->SC3 |= ADC_SC3_AVGE(1) /* Enable hardware average */ + | ADC_SC3_AVGS(3); /* Average over 32 samples */ + + /* Calibrate ADC */ + ADC0->SC3 |= ADC_SC3_CAL(1); + + while((ADC0->SC3) & ADC_SC3_CAL_MASK) ; + + uint32_t cal = ADC0->CLP0 + + ADC0->CLP1 + + ADC0->CLP2 + + ADC0->CLP3 + + ADC0->CLP4 + + ADC0->CLPS; + + ADC0->PG = 0x8000 | (cal >> 1); +} + +void adc0_terminate() +{ + SIM->SCGC6 &= ~SIM_SCGC6_ADC0(1); +} + +float adc0_getMeasurement(uint8_t ch) +{ + if(ch > 32) return 0.0f; + + /* 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; +} diff --git a/platform/drivers/ADC/ADC0_GDx.h b/platform/drivers/ADC/ADC0_GDx.h new file mode 100644 index 00000000..ccd59e6a --- /dev/null +++ b/platform/drivers/ADC/ADC0_GDx.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#ifndef ADC0_H +#define ADC0_H + +#include + +/** + * Initialise and start ADC0. + */ +void adc0_init(); + +/** + * Turn off ADC0. + */ +void adc0_terminate(); + +/** + * 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); + +#endif /* ADC0_H */ diff --git a/platform/targets/DM-1801/platform.c b/platform/targets/DM-1801/platform.c index 83168f1d..4af913f8 100644 --- a/platform/targets/DM-1801/platform.c +++ b/platform/targets/DM-1801/platform.c @@ -19,9 +19,15 @@ ***************************************************************************/ #include +#include #include +#include #include "hwconfig.h" +/* Mutex for concurrent access to ADC0 */ +OS_MUTEX adc_mutex; +OS_ERR e; + void platform_init() { /* Configure GPIOs */ @@ -48,6 +54,12 @@ void platform_init() gpio_setMode(LCD_BKLIGHT, OUTPUT); gpio_setAlternateFunction(LCD_BKLIGHT, 2); + + /* + * Initialise ADC + */ + adc0_init(); + OSMutexCreate(&adc_mutex, "", &e); } void platform_terminate() @@ -55,18 +67,28 @@ void platform_terminate() gpio_clearPin(LCD_BKLIGHT); gpio_clearPin(RED_LED); gpio_clearPin(GREEN_LED); + + adc0_terminate(); } float platform_getVbat() { - /* TODO */ - return 0.0f; + float value = 0.0f; + OSMutexPend(&adc_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &e); + value = adc0_getMeasurement(1); + OSMutexPost(&adc_mutex, OS_OPT_POST_NONE, &e); + + return (value * 3.0f)/1000.0f; } float platform_getMicLevel() { - /* TODO */ - return 0.0f; + float value = 0.0f; + OSMutexPend(&adc_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &e); + value = adc0_getMeasurement(3); + OSMutexPost(&adc_mutex, OS_OPT_POST_NONE, &e); + + return value; } float platform_getVolumeLevel() diff --git a/platform/targets/GD77/platform.c b/platform/targets/GD77/platform.c index 83168f1d..4af913f8 100644 --- a/platform/targets/GD77/platform.c +++ b/platform/targets/GD77/platform.c @@ -19,9 +19,15 @@ ***************************************************************************/ #include +#include #include +#include #include "hwconfig.h" +/* Mutex for concurrent access to ADC0 */ +OS_MUTEX adc_mutex; +OS_ERR e; + void platform_init() { /* Configure GPIOs */ @@ -48,6 +54,12 @@ void platform_init() gpio_setMode(LCD_BKLIGHT, OUTPUT); gpio_setAlternateFunction(LCD_BKLIGHT, 2); + + /* + * Initialise ADC + */ + adc0_init(); + OSMutexCreate(&adc_mutex, "", &e); } void platform_terminate() @@ -55,18 +67,28 @@ void platform_terminate() gpio_clearPin(LCD_BKLIGHT); gpio_clearPin(RED_LED); gpio_clearPin(GREEN_LED); + + adc0_terminate(); } float platform_getVbat() { - /* TODO */ - return 0.0f; + float value = 0.0f; + OSMutexPend(&adc_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &e); + value = adc0_getMeasurement(1); + OSMutexPost(&adc_mutex, OS_OPT_POST_NONE, &e); + + return (value * 3.0f)/1000.0f; } float platform_getMicLevel() { - /* TODO */ - return 0.0f; + float value = 0.0f; + OSMutexPend(&adc_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &e); + value = adc0_getMeasurement(3); + OSMutexPost(&adc_mutex, OS_OPT_POST_NONE, &e); + + return value; } float platform_getVolumeLevel()