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()