diff --git a/meson.build b/meson.build index 25498bce..c18ab269 100644 --- a/meson.build +++ b/meson.build @@ -17,7 +17,8 @@ openrtx_src = ['openrtx/src/main.c', 'openrtx/src/ui.c'] openrtx_inc = ['openrtx/include/interfaces', - 'openrtx/include/fonts'] + 'openrtx/include/fonts', + 'platform/drivers/ADC'] ## RTOS rtos_src = ['rtos/uC-OS3/Source/__dbg_uCOS-III.c', @@ -130,8 +131,8 @@ endif ## TYT MD380 md380_src = src + stm32f405_src + ['platform/drivers/display/HX83XX_MDxx380.c', 'platform/drivers/keyboard/keyboard_MDxx380.c', + 'platform/drivers/ADC/ADC1_MDxx380.c', 'platform/targets/MD380/platform.c', - 'platform/targets/MD380/adc1.c', 'openrtx/src/graphics/graphics_rgb565.c'] md380_def = def + stm32f405_def @@ -142,8 +143,8 @@ md380_inc = inc + stm32f405_inc + ['platform/targets/MD380'] ## TYT MD-UV380 mduv380_src = src + stm32f405_src + ['platform/drivers/display/HX83XX_MDxx380.c', 'platform/drivers/keyboard/keyboard_MDxx380.c', + 'platform/drivers/ADC/ADC1_MDxx380.c', 'platform/targets/MD-UV380/platform.c', - 'platform/targets/MD-UV380/adc1.c', 'openrtx/src/graphics/graphics_rgb565.c'] mduv380_def = def + stm32f405_def diff --git a/platform/targets/MD380/adc1.c b/platform/drivers/ADC/ADC1_MDxx380.c similarity index 93% rename from platform/targets/MD380/adc1.c rename to platform/drivers/ADC/ADC1_MDxx380.c index 6a5f2a02..2d079a76 100644 --- a/platform/targets/MD380/adc1.c +++ b/platform/drivers/ADC/ADC1_MDxx380.c @@ -17,7 +17,7 @@ #include #include "hwconfig.h" -#include "adc1.h" +#include "ADC1_MDxx380.h" uint16_t measurements[4]; @@ -33,10 +33,12 @@ void adc1_init() * - PA3: vox level * - PB0: RSSI level */ - gpio_setMode(AIN_VOLUME, INPUT_ANALOG); gpio_setMode(AIN_VBAT, INPUT_ANALOG); + #ifdef PLATFORM_MD380 + gpio_setMode(AIN_VOLUME, INPUT_ANALOG); gpio_setMode(AIN_MIC, INPUT_ANALOG); gpio_setMode(AIN_RSSI, INPUT_ANALOG); + #endif /* * ADC clock is APB2 frequency divided by 8, giving 10.5MHz. @@ -62,11 +64,16 @@ void adc1_init() | ADC_CR2_ADON; /* Scan sequence config. */ + #ifdef PLATFORM_MD380 ADC1->SQR1 = 3 << 20; /* Four channels to be converted */ ADC1->SQR3 |= (1 << 0) /* CH1, battery voltage on PA1 */ | (8 << 5) /* CH8, RSSI value on PB0 */ | (3 << 10) /* CH3, vox level on PA3 */ | (0 << 15); /* CH0, volume potentiometer level on PA0 */ + #else + ADC1->SQR1 = 0; /* Convert one channel */ + ADC1->SQR3 |= (1 << 0); /* CH1, battery voltage on PA1 */ + #endif /* DMA2 Stream 0 configuration: * - channel 0: ADC1 diff --git a/platform/targets/MD-UV380/adc1.h b/platform/drivers/ADC/ADC1_MDxx380.h similarity index 100% rename from platform/targets/MD-UV380/adc1.h rename to platform/drivers/ADC/ADC1_MDxx380.h diff --git a/platform/targets/MD-UV380/adc1.c b/platform/targets/MD-UV380/adc1.c deleted file mode 100644 index 350dcf87..00000000 --- a/platform/targets/MD-UV380/adc1.c +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************** - * 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 "hwconfig.h" -#include "adc1.h" - -uint16_t measurements[4]; - -void adc1_init() -{ - RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; - RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; - - /* - * Configure GPIOs to analog input mode: - * - PA0: volume potentiometer level - * - PA1: battery voltage - * - PA3: vox level - * - PB0: RSSI level - * Volume, Mic and RSSI temporarily disabled until the right pinout is found - */ - //gpio_setMode(AIN_VOLUME, INPUT_ANALOG); - gpio_setMode(AIN_VBAT, INPUT_ANALOG); - //gpio_setMode(AIN_MIC, INPUT_ANALOG); - //gpio_setMode(AIN_RSSI, INPUT_ANALOG); - - /* - * ADC clock is APB2 frequency divided by 8, giving 10.5MHz. - * We set the sample time of each channel to 480 ADC cycles and we have to - * scan four channels: given that a conversion takes 12 cycles, we have a - * total conversion time of ~187us. - */ - ADC->CCR |= ADC_CCR_ADCPRE; - ADC1->SMPR2 = ADC_SMPR2_SMP0 - | ADC_SMPR2_SMP1 - | ADC_SMPR2_SMP3 - | ADC_SMPR2_SMP8; - - /* - * No overrun interrupt, 12-bit resolution, no analog watchdog, no - * discontinuous mode, enable scan mode, no end of conversion interrupts, - * enable continuous conversion (free-running). - */ - ADC1->CR1 |= ADC_CR1_SCAN; - ADC1->CR2 |= ADC_CR2_DMA - | ADC_CR2_DDS - | ADC_CR2_CONT - | ADC_CR2_ADON; - - /* Scan sequence config. */ - ADC1->SQR1 = 3 << 20; /* Four channels to be converted */ - ADC1->SQR3 |= (1 << 0) /* CH1, battery voltage on PA1 */ - | (8 << 5) /* CH8, RSSI value on PB0 */ - | (3 << 10) /* CH3, vox level on PA3 */ - | (0 << 15); /* CH0, volume potentiometer level on PA0 */ - - /* DMA2 Stream 0 configuration: - * - channel 0: ADC1 - * - low priority - * - half-word transfer, both memory and peripheral - * - increment memory - * - circular mode - * - peripheral-to-memory transfer - * - no interrupts - */ - DMA2_Stream0->PAR = ((uint32_t) &(ADC1->DR)); - DMA2_Stream0->M0AR = ((uint32_t) &measurements); - DMA2_Stream0->NDTR = 4; - DMA2_Stream0->CR = DMA_SxCR_MSIZE_0 - | DMA_SxCR_PSIZE_0 - | DMA_SxCR_MINC - | DMA_SxCR_CIRC - | DMA_SxCR_EN; - - /* Finally, start conversion */ - ADC1->CR2 |= ADC_CR2_SWSTART; -} - -void adc1_terminate() -{ - DMA2_Stream0->CR &= ~DMA_SxCR_EN; - ADC1->CR2 &= ADC_CR2_ADON; - RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; -} - -float adc1_getMeasurement(uint8_t ch) -{ - if(ch > 3) return 0.0f; - float value = ((float) measurements[ch]); - return (value * 3300.0f)/4096.0f; -} diff --git a/platform/targets/MD-UV380/platform.c b/platform/targets/MD-UV380/platform.c index 7887054a..0f21249e 100644 --- a/platform/targets/MD-UV380/platform.c +++ b/platform/targets/MD-UV380/platform.c @@ -21,7 +21,7 @@ #include #include #include "hwconfig.h" -#include "adc1.h" +#include "ADC1_MDxx380.h" #ifdef ENABLE_BKLIGHT_DIMMING void TIM1_TRG_COM_TIM11_IRQHandler() diff --git a/platform/targets/MD380/adc1.h b/platform/targets/MD380/adc1.h deleted file mode 100644 index 017d2182..00000000 --- a/platform/targets/MD380/adc1.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************** - * 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 ADC1_H -#define ADC1_H - -#include - -/** - * Driver for ADC1, used to continuously sample the following channels: - * - ADC1_CH0 (PA0): output value of the volume potentiometer; - * - ADC1_CH1 (PA1): battery voltage through 1:3 resistor divider; - * - ADC1_CH3 (PA3): vox level; - * - ADC1_CH8 (PB0): RSSI level; - */ - -/** - * Initialise and start ADC1 and DMA2 Stream 0. - * - * ADC is configured in free-running mode with 1:8 prescaler and a sample time - * for each channel of 480 cycles. This gives a sampling frequency, for each - * channel, of ~5.3kHz. - * - * DMA2 Stream 0 is used to transfer data from ADC1 data register to an internal - * buffer, from which is fetched by application code using adc1_getMeasurement(). - */ -void adc1_init(); - -/** - * Turn off ADC1 (also gating off its clock) and disable DMA2 Stream 0. - * DMA2 clock is kept active. - */ -void adc1_terminate(); - -/** - * Get current measurement of a given channel, mapped as below: - * - channel 0: battery voltage - * - channel 1: RSSI level - * - channel 2: vox level - * - channel 3: volume level - * - * NOTE: the mapping above DOES NOT correspond to the physical ADC channel - * mapping! - * - * @param ch: channel number, between 0 and 3. - * @return current value of the specified channel in mV. - */ -float adc1_getMeasurement(uint8_t ch); - -#endif /* ADC1_H */ diff --git a/platform/targets/MD380/platform.c b/platform/targets/MD380/platform.c index 9ccb0626..aecc9bd7 100644 --- a/platform/targets/MD380/platform.c +++ b/platform/targets/MD380/platform.c @@ -20,7 +20,7 @@ #include #include #include "hwconfig.h" -#include "adc1.h" +#include "ADC1_MDxx380.h" void platform_init() {