diff --git a/radio/src/gui/128x64/radio_calibration.cpp b/radio/src/gui/128x64/radio_calibration.cpp index 3e1a30d20..2ee780ea8 100644 --- a/radio/src/gui/128x64/radio_calibration.cpp +++ b/radio/src/gui/128x64/radio_calibration.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "hal/adc_driver.h" #define XPOT_DELTA 10 #define XPOT_DELAY 10 /* cycles */ diff --git a/radio/src/gui/212x64/radio_calibration.cpp b/radio/src/gui/212x64/radio_calibration.cpp index 3dcb9c27f..f6f6515c5 100644 --- a/radio/src/gui/212x64/radio_calibration.cpp +++ b/radio/src/gui/212x64/radio_calibration.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "hal/adc_driver.h" #define XPOT_DELTA 10 #define XPOT_DELAY 10 /* cycles */ diff --git a/radio/src/gui/colorlcd/radio_calibration.cpp b/radio/src/gui/colorlcd/radio_calibration.cpp index fcf41f723..6947fe522 100644 --- a/radio/src/gui/colorlcd/radio_calibration.cpp +++ b/radio/src/gui/colorlcd/radio_calibration.cpp @@ -22,6 +22,7 @@ #include "radio_calibration.h" #include "sliders.h" #include "view_main_decoration.h" +#include "hal/adc_driver.h" #define XPOT_DELTA 10 #define XPOT_DELAY 5 /* cycles */ diff --git a/radio/src/gui/colorlcd/radio_hardware.cpp b/radio/src/gui/colorlcd/radio_hardware.cpp index 60f1fbe94..6b04ccf95 100644 --- a/radio/src/gui/colorlcd/radio_hardware.cpp +++ b/radio/src/gui/colorlcd/radio_hardware.cpp @@ -24,6 +24,7 @@ #include "radio_diaganas.h" #include "opentx.h" #include "libopenui.h" +#include "hal/adc_driver.h" #define SET_DIRTY() storageDirty(EE_GENERAL) diff --git a/radio/src/gui/colorlcd/view_main_decoration.cpp b/radio/src/gui/colorlcd/view_main_decoration.cpp index b10c771d1..ca875ff62 100644 --- a/radio/src/gui/colorlcd/view_main_decoration.cpp +++ b/radio/src/gui/colorlcd/view_main_decoration.cpp @@ -48,6 +48,7 @@ void ViewMainDecoration::setSlidersVisible(bool visible) sliders[SLIDERS_POT3]->setHeight(visible ? TRIM_SQUARE_SIZE : 0); #endif +#if NUM_SLIDERS > 0 // // Vertical sliders // @@ -65,6 +66,8 @@ void ViewMainDecoration::setSlidersVisible(bool visible) if (IS_POT_SLIDER_AVAILABLE(EXT2)) { sliders[SLIDERS_EXT2]->setWidth(visible ? TRIM_SQUARE_SIZE : 0); } +#endif + #endif if (visible) { @@ -135,13 +138,14 @@ void ViewMainDecoration::adjustDecoration() // Vertical trims/slider are on top of horizontal sliders with a small margin auto vertTop = pos - HMARGIN - VERTICAL_SLIDERS_HEIGHT; - + +#if NUM_SLIDERS > 0 // Left side (vertical) pos = left(); sliders[SLIDERS_REAR_LEFT]->setLeft(pos); sliders[SLIDERS_REAR_LEFT]->setTop(vertTop); -#if defined(HARDWARE_EXT1) || defined(PCBX12S) +#if defined(HARDWARE_EXT1) || defined(PCBX12S) // TODO: define HARDWARE_EXT1 for X12S sliders[SLIDERS_EXT1]->setLeft(pos); if (IS_POT_SLIDER_AVAILABLE(EXT1)) { auto rl = sliders[SLIDERS_REAR_LEFT]; @@ -195,7 +199,14 @@ void ViewMainDecoration::adjustDecoration() trims[TRIMS_LV]->setTop(vertTop); trims[TRIMS_RV]->setLeft(sliders[SLIDERS_REAR_RIGHT]->left() - trims[TRIMS_RV]->width()); trims[TRIMS_RV]->setTop(vertTop); - +#else + // No sliders: place the vertical trims on the edge + trims[TRIMS_LV]->setLeft(left()); + trims[TRIMS_LV]->setTop(vertTop); + trims[TRIMS_RV]->setLeft(right() - trims[TRIMS_RV]->width()); + trims[TRIMS_RV]->setTop(vertTop); +#endif + // Place the flight-mode text box // -> between horiz trims (if existing) // else on top of horiz sliders @@ -265,6 +276,7 @@ void ViewMainDecoration::createSliders() sliders[SLIDERS_POT3] = new MainViewHorizontalSlider(this, r, CALIBRATED_POT3); #endif +#if NUM_SLIDERS > 0 r = rect_t { 0, 0, 0, 0 }; sliders[SLIDERS_REAR_LEFT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_LEFT); sliders[SLIDERS_REAR_RIGHT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_RIGHT); @@ -276,6 +288,7 @@ void ViewMainDecoration::createSliders() #if defined(HARDWARE_EXT2) || defined(PCBX12S) sliders[SLIDERS_EXT2] = new MainViewVerticalSlider(this, r, CALIBRATED_POT_EXT2); #endif +#endif // NUM_SLIDERS > 0 } void ViewMainDecoration::createTrims() diff --git a/radio/src/gui/common/stdlcd/radio_hardware.cpp b/radio/src/gui/common/stdlcd/radio_hardware.cpp index 69004bf75..0ff93f0b4 100644 --- a/radio/src/gui/common/stdlcd/radio_hardware.cpp +++ b/radio/src/gui/common/stdlcd/radio_hardware.cpp @@ -19,6 +19,7 @@ */ #include +#include "hal/adc_driver.h" #if defined(PCBSKY9X) #define HW_SETTINGS_COLUMN (2+(15*FW)) diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp new file mode 100644 index 000000000..831f8037b --- /dev/null +++ b/radio/src/hal/adc_driver.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (C) EdgeTx + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#include "adc_driver.h" +#include "board.h" + +// IS_POT_SLIDER_AVAILABLE() +#include "opentx.h" + +const etx_hal_adc_driver_t* etx_hal_adc_driver = nullptr; + +#if defined(SIMU) + // not needed +#elif defined(RADIO_T16) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,1, -1,1, -1,1}; +#elif defined(RADIO_T18) + const int8_t adcDirection[NUM_ANALOGS] = { 1,-1,1,-1, -1,1,-1, -1,1, -1,1 }; +#elif defined(RADIO_TX16S) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,1, -1,1, -1,1}; +#elif defined(PCBX10) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, 1,1, 1, -1}; +#elif defined(PCBX9E) + const int8_t adcDirection[NUM_ANALOGS] = { +#if defined(HORUS_STICKS) + 1,-1,1,-1, +#else + 1,1,-1,-1, +#endif // HORUS_STICKS + // other analogs are the same + -1,-1,-1,1, -1,1,1,-1, -1,-1 }; + + const uint8_t adcMapping[NUM_ANALOGS] = { 0 /*STICK1*/, 1 /*STICK2*/, 2 /*STICK3*/, 3 /*STICK4*/, + 11 /*POT1*/, 4 /*POT2*/, 5 /*POT3*/, 6 /*POT4*/, + 12 /*SLIDER1*/, 13 /*SLIDER2*/, 7 /*SLIDER3*/, 8 /*SLIDER4*/, + 9 /*TX_VOLTAGE*/, 10 /*TX_VBAT*/ }; +#elif defined(PCBX9DP) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,-1, 1,1, 1, 1}; +#elif defined(PCBX9D) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,0, 1,1, 1, 1}; +#elif defined(RADIO_TX12) + const int8_t adcDirection[NUM_ANALOGS] = {-1,1,-1,1, -1,-1, 1, 1}; +#elif defined(PCBX7) + const int8_t adcDirection[NUM_ANALOGS] = {-1,1,-1,1, 1,1, 1, 1}; +#elif defined(PCBX9LITE) + const int8_t adcDirection[NUM_ANALOGS] = {-1,1,-1,1, 1,1, 1}; +#elif defined(PCBXLITE) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,-1,1, -1,1, 1, 1}; +#elif defined(PCBNV14) + const uint8_t adcMapping[NUM_ANALOGS] = { 0 /*STICK1*/, 1 /*STICK2*/, 2 /*STICK3*/, 3 /*STICK4*/, + 4 /*POT1*/, 5 /*POT2*/, 6 /*SWA*/, 14 /*SWB*/, + 7 /*SWC*/, 15 /*SWD*/, 8 /*SWE*/, 9 /*SWF*/, + 10/*SWG*/, 11/*SWH*/, + 12 /*TX_VOLTAGE*/, 13 /* TX_VBAT */ }; + + const int8_t adcDirection[NUM_ANALOGS] = { 0 /*STICK1*/, 0 /*STICK2*/, 0 /*STICK3*/, 0 /*STICK4*/, + -1 /*POT1*/, 0 /*POT2*/, 0 /*SWA*/, 0 /*SWC*/, + 0 /*SWE*/, -1 /*SWF*/, 0 /*SWG*/, -1 /*SWH*/, + 0 /*TX_VOLTAGE*/, 0 /*TX_VBAT*/, + 0 /*SWB*/, 0 /*SWD*/}; + +#elif defined(PCBX12S) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, -1,-1, -1,1, 0,0,0}; +#else + #error "ADC driver does not suppport this target" +#endif + +uint16_t adcValues[NUM_ANALOGS] __DMA; + +#if defined(PCBX10) || defined(PCBX12S) +uint16_t rtcBatteryVoltage; +#endif + +bool adcInit(const etx_hal_adc_driver_t* driver) +{ + etx_hal_adc_driver = driver; + if (!etx_hal_adc_driver) + return false; + + // If there is an init function + // it should succeed + if (etx_hal_adc_driver->init && + !etx_hal_adc_driver->init()) { + return false; + } + + return true; +} + +static bool adcSingleRead() +{ + if (!etx_hal_adc_driver) + return false; + + if (etx_hal_adc_driver->start_conversion && + !etx_hal_adc_driver->start_conversion()) + return false; + + if (etx_hal_adc_driver->wait_completion) + etx_hal_adc_driver->wait_completion(); + + return true; +} + +// Declare adcRead() weak so it can be re-declared +#pragma weak adcRead +bool adcRead() +{ + uint16_t temp[NUM_ANALOGS] = { 0 }; + + for (int i=0; i<4; i++) { + if (!adcSingleRead()) + return false; + for (uint8_t x=FIRST_ANALOG_ADC; x> 2; + } + +#if NUM_PWMSTICKS > 0 + if (STICKS_PWM_ENABLED()) { + sticksPwmRead(adcValues); + } +#endif + return true; +} + +#if !defined(SIMU) +uint16_t getRTCBatteryVoltage() +{ +#if defined(HAS_TX_RTC_VOLTAGE) + return (getAnalogValue(TX_RTC_VOLTAGE) * ADC_VREF_PREC2) / 2048; +#elif defined(PCBX10) || defined(PCBX12S) + return (rtcBatteryVoltage * 2 * ADC_VREF_PREC2) / 2048; +#elif defined(PCBNV14) + #warning "TODO RTC voltage" + return 330; +#else + #warning "RTC battery not supported on this target" + return 0; +#endif +} + +uint16_t getAnalogValue(uint8_t index) +{ + if (IS_POT(index) && !IS_POT_SLIDER_AVAILABLE(index)) { + // Use fixed analog value for non-existing and/or non-connected pots. + // Non-connected analog inputs will slightly follow the adjacent connected analog inputs, + // which produces ghost readings on these inputs. + return 0; + } +#if defined(PCBX9E) || defined(PCBNV14) + index = adcMapping[index]; +#endif + if (adcDirection[index] < 0) + return 4095 - adcValues[index]; + else + return adcValues[index]; +} +#endif // #if !defined(SIMU) diff --git a/radio/src/hal/adc_driver.h b/radio/src/hal/adc_driver.h new file mode 100644 index 000000000..d9256ef62 --- /dev/null +++ b/radio/src/hal/adc_driver.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) EdgeTx + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#pragma once + +#include + +// TODO: move this to the targets +#if NUM_PWMSTICKS > 0 + #define FIRST_ANALOG_ADC (STICKS_PWM_ENABLED() ? NUM_PWMSTICKS : 0) + #define NUM_ANALOGS_ADC (STICKS_PWM_ENABLED() ? (NUM_ANALOGS - NUM_PWMSTICKS) : NUM_ANALOGS) +#elif defined(PCBX9E) + #define FIRST_ANALOG_ADC 0 + #define NUM_ANALOGS_ADC 11 + #define NUM_ANALOGS_ADC_EXT (NUM_ANALOGS - NUM_ANALOGS_ADC) +#elif defined(PCBNV14) && defined(FLYSKY_HALL_STICKS) + #define FIRST_ANALOG_ADC 4 + #define NUM_ANALOGS_ADC 10 + #define NUM_ANALOGS_ADC_EXT 2 +#else + #define FIRST_ANALOG_ADC 0 + #define NUM_ANALOGS_ADC NUM_ANALOGS +#endif + +// TODO: get rid of this special case +#if defined(PCBX10) || defined(PCBX12S) +extern uint16_t rtcBatteryVoltage; +#endif + +struct etx_hal_adc_driver_t { + bool (*init)(); + bool (*start_conversion)(); + void (*wait_completion)(); +}; + +bool adcInit(const etx_hal_adc_driver_t* driver); +// void adcDeInit(); + +bool adcRead(); +uint16_t getRTCBatteryVoltage(); +uint16_t getAnalogValue(uint8_t index); diff --git a/radio/src/main.cpp b/radio/src/main.cpp index 5c927db79..6c7fa7d55 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "hal/adc_driver.h" #if defined(LIBOPENUI) #include "libopenui.h" diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index ca46b174e..6c677d36f 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -19,7 +19,8 @@ */ #include "opentx.h" -#include +#include "io/frsky_firmware_update.h" +#include "hal/adc_driver.h" #if defined(LIBOPENUI) #include "libopenui.h" @@ -1058,7 +1059,8 @@ void getADC() #endif DEBUG_TIMER_START(debugTimerAdcRead); - adcRead(); + if (!adcRead()) + TRACE("adcRead failed"); DEBUG_TIMER_STOP(debugTimerAdcRead); for (uint8_t x=0; x 0 - #define FIRST_ANALOG_ADC (STICKS_PWM_ENABLED() ? NUM_PWMSTICKS : 0) - #define NUM_ANALOGS_ADC (STICKS_PWM_ENABLED() ? (NUM_ANALOGS - NUM_PWMSTICKS) : NUM_ANALOGS) -#elif defined(PCBX9E) - #define FIRST_ANALOG_ADC 0 - #define NUM_ANALOGS_ADC 11 - #define NUM_ANALOGS_ADC_EXT (NUM_ANALOGS - NUM_ANALOGS_ADC) -#else - #define FIRST_ANALOG_ADC 0 - #define NUM_ANALOGS_ADC NUM_ANALOGS -#endif - -uint16_t adcValues[NUM_ANALOGS] __DMA; - -#if defined(PCBX10) -uint16_t rtcBatteryVoltage; -#endif - -void adcInit() -{ - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - -#if defined(ADC_GPIOA_PINS) - GPIO_InitStructure.GPIO_Pin = ADC_GPIOA_PINS; - GPIO_Init(GPIOA, &GPIO_InitStructure); -#endif - -#if defined(ADC_GPIOB_PINS) - GPIO_InitStructure.GPIO_Pin = ADC_GPIOB_PINS; - GPIO_Init(GPIOB, &GPIO_InitStructure); -#endif - -#if defined(ADC_GPIOC_PINS) - GPIO_InitStructure.GPIO_Pin = ADC_GPIOC_PINS; - GPIO_Init(GPIOC, &GPIO_InitStructure); -#endif - -#if defined(ADC_GPIOF_PINS) - GPIO_InitStructure.GPIO_Pin = ADC_GPIOF_PINS; - GPIO_Init(GPIOF, &GPIO_InitStructure); -#endif - - ADC_MAIN->CR1 = ADC_CR1_SCAN; - ADC_MAIN->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; - ADC_MAIN->SQR1 = (NUM_ANALOGS_ADC - 1) << 20; // bits 23:20 = number of conversions - -#if defined(PCBX10) - if (STICKS_PWM_ENABLED()) { - ADC_MAIN->SQR2 = (ADC_CHANNEL_SLIDER2 << 0) + (ADC_CHANNEL_BATT << 5); - ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1 << 0) + (ADC_CHANNEL_POT2 << 5) + (ADC_CHANNEL_POT3 << 10) + (ADC_CHANNEL_EXT1 << 15) + (ADC_CHANNEL_EXT2 << 20) + (ADC_CHANNEL_SLIDER1 << 25); - } - else { - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3 << 0) + (ADC_CHANNEL_EXT1 << 5) + (ADC_CHANNEL_EXT2 << 10) + (ADC_CHANNEL_SLIDER1 << 15) + (ADC_CHANNEL_SLIDER2 << 20) + (ADC_CHANNEL_BATT << 25); - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT1 << 20) + (ADC_CHANNEL_POT2 << 25); - } -#elif defined(PCBX9E) - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT4 << 0) + (ADC_CHANNEL_SLIDER3 << 5) + (ADC_CHANNEL_SLIDER4 << 10) + (ADC_CHANNEL_BATT << 15) + (ADC_Channel_Vbat << 20); - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT2 << 20) + (ADC_CHANNEL_POT3 << 25); -#elif defined(PCBXLITE) - if (STICKS_PWM_ENABLED()) { - ADC_MAIN->SQR2 = 0; - ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1 << 0) + (ADC_CHANNEL_POT2 << 5) + (ADC_CHANNEL_BATT << 10) + (ADC_Channel_Vbat << 15); - } - else { - ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT << 0) + (ADC_Channel_Vbat << 5); - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT1 << 20) + (ADC_CHANNEL_POT2 << 25); - } -#elif defined(RADIO_T8) || defined(RADIO_TLITE) - ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT << 0) + (ADC_Channel_Vbat << 5); - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15); -#elif defined(PCBX7) - ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT << 0) + (ADC_Channel_Vbat << 5); - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT1 << 20) + (ADC_CHANNEL_POT2 << 25); -#elif defined(PCBX9LITE) - ADC_MAIN->SQR2 = (ADC_Channel_Vbat << 0); - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT1 << 20) + (ADC_CHANNEL_BATT << 25); -#elif defined(PCBX9D) || defined(PCBX9DP) - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3 << 0) + (ADC_CHANNEL_SLIDER1 << 5) + (ADC_CHANNEL_SLIDER2 << 10) + (ADC_CHANNEL_BATT << 15) + (ADC_Channel_Vbat << 20); - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT1 << 20) + (ADC_CHANNEL_POT2 << 25); -#endif - - ADC_MAIN->SMPR1 = ADC_MAIN_SMPR1; - ADC_MAIN->SMPR2 = ADC_MAIN_SMPR2; - - ADC->CCR = ADC_CCR_VBATE; // Enable vbat sensor - - ADC_DMA_Stream->CR = DMA_SxCR_PL | ADC_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; - ADC_DMA_Stream->PAR = CONVERT_PTR_UINT(&ADC_MAIN->DR); - ADC_DMA_Stream->M0AR = CONVERT_PTR_UINT(&adcValues[FIRST_ANALOG_ADC]); - ADC_DMA_Stream->NDTR = NUM_ANALOGS_ADC; - ADC_DMA_Stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; - -#if defined(PCBX10) - ADC1->CR1 = ADC_CR1_SCAN; - ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; - ADC1->SQR1 = (1 - 1) << 20; - ADC1->SQR2 = 0; - ADC1->SQR3 = (ADC_Channel_Vbat << 0); - ADC1->SMPR1 = (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24); - ADC1->SMPR2 = (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24) + (ADC_SAMPTIME << 27); -#endif - -#if defined(PCBX9E) - ADC_EXT->CR1 = ADC_CR1_SCAN; - ADC_EXT->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; - ADC_EXT->SQR1 = (NUM_ANALOGS_ADC_EXT - 1) << 20; - ADC_EXT->SQR2 = 0; - ADC_EXT->SQR3 = (ADC_CHANNEL_POT1 << 0) + (ADC_CHANNEL_SLIDER1 << 5) + (ADC_CHANNEL_SLIDER2 << 10); // conversions 1 to 3 - ADC_EXT->SMPR1 = (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24); - ADC_EXT->SMPR2 = (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24) + (ADC_SAMPTIME << 27); - - ADC_EXT_DMA_Stream->CR = DMA_SxCR_PL | DMA_SxCR_CHSEL_1 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; - ADC_EXT_DMA_Stream->PAR = CONVERT_PTR_UINT(&ADC_EXT->DR); - ADC_EXT_DMA_Stream->M0AR = CONVERT_PTR_UINT(adcValues + NUM_ANALOGS_ADC); - ADC_EXT_DMA_Stream->NDTR = NUM_ANALOGS_ADC_EXT; - ADC_EXT_DMA_Stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; -#endif - -#if NUM_PWMSTICKS > 0 - if (STICKS_PWM_ENABLED()) { - sticksPwmInit(); - } -#endif -} - -void adcSingleRead() -{ - ADC_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA - ADC_MAIN->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); - ADC_SET_DMA_FLAGS(); - ADC_DMA_Stream->CR |= DMA_SxCR_EN; // Enable DMA - ADC_MAIN->CR2 |= (uint32_t)ADC_CR2_SWSTART; - -#if defined(PCBX10) - ADC1->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); - ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART; -#endif - -#if defined(PCBX9E) - ADC_EXT_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA - ADC_EXT->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); - ADC_EXT_SET_DMA_FLAGS(); - ADC_EXT_DMA_Stream->CR |= DMA_SxCR_EN; // Enable DMA - ADC_EXT->CR2 |= (uint32_t)ADC_CR2_SWSTART; -#endif - -#if defined(PCBX9E) - for (unsigned int i=0; i<10000; i++) { - if (ADC_TRANSFER_COMPLETE() && ADC_EXT_TRANSFER_COMPLETE()) { - break; - } - } - ADC_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA - ADC_EXT_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA -#else - for (unsigned int i = 0; i < 10000; i++) { - if (ADC_TRANSFER_COMPLETE()) { - break; - } - } - ADC_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA -#endif - -#if defined(PCBX10) - if (isVBatBridgeEnabled()) { - rtcBatteryVoltage = ADC1->DR; - } -#endif -} - -void adcRead() -{ - uint16_t temp[NUM_ANALOGS] = { 0 }; - - for (int i=0; i<4; i++) { - adcSingleRead(); - for (uint8_t x=FIRST_ANALOG_ADC; x> 2; - } - -#if NUM_PWMSTICKS > 0 - if (STICKS_PWM_ENABLED()) { - sticksPwmRead(adcValues); - } -#endif -} - -#if defined(PCBX10) -uint16_t getRTCBatteryVoltage() -{ - return (rtcBatteryVoltage * 2 * ADC_VREF_PREC2) / 2048; -} -#else -uint16_t getRTCBatteryVoltage() -{ - return (getAnalogValue(TX_RTC_VOLTAGE) * ADC_VREF_PREC2) / 2048; -} -#endif - -#if !defined(SIMU) -uint16_t getAnalogValue(uint8_t index) -{ - if (IS_POT(index) && !IS_POT_SLIDER_AVAILABLE(index)) { - // Use fixed analog value for non-existing and/or non-connected pots. - // Non-connected analog inputs will slightly follow the adjacent connected analog inputs, - // which produces ghost readings on these inputs. - return 0; - } -#if defined(PCBX9E) - index = adcMapping[index]; -#endif - if (adcDirection[index] < 0) - return 4095 - adcValues[index]; - else - return adcValues[index]; -} -#endif // #if !defined(SIMU) diff --git a/radio/src/targets/common/arm/stm32/board_common.h b/radio/src/targets/common/arm/stm32/board_common.h index 43a83ac91..e55424a40 100644 --- a/radio/src/targets/common/arm/stm32/board_common.h +++ b/radio/src/targets/common/arm/stm32/board_common.h @@ -103,12 +103,7 @@ extern "C" { #include "../simu/simpgmspace.h" #endif -// ADC driver -void adcInit(); -void adcRead(); -uint16_t getAnalogValue(uint8_t index); -uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps -uint16_t getRTCBatteryVoltage(); +uint16_t getBatteryVoltage(); // STM32 uses a 25K+25K voltage divider bridge to measure the battery voltage // Measuring VBAT puts considerable drain (22 µA) on the battery instead of normal drain (~10 nA) diff --git a/radio/src/targets/common/arm/stm32/f2/CMakeLists.txt b/radio/src/targets/common/arm/stm32/f2/CMakeLists.txt index 3aca8a114..3db373f42 100644 --- a/radio/src/targets/common/arm/stm32/f2/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/f2/CMakeLists.txt @@ -24,6 +24,7 @@ set(STM32LIB_SRC STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rtc.c STM32F2xx_StdPeriph_Driver/src/stm32f2xx_pwr.c STM32F2xx_StdPeriph_Driver/src/stm32f2xx_usart.c + STM32F2xx_StdPeriph_Driver/src/stm32f2xx_adc.c ) # diff --git a/radio/src/targets/common/arm/stm32/f4/CMakeLists.txt b/radio/src/targets/common/arm/stm32/f4/CMakeLists.txt index 0bd50e34a..8db9dfd6f 100644 --- a/radio/src/targets/common/arm/stm32/f4/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/f4/CMakeLists.txt @@ -23,6 +23,7 @@ set(STM32LIB_SRC STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c + STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c ) # diff --git a/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp new file mode 100644 index 000000000..f7482e2ba --- /dev/null +++ b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp @@ -0,0 +1,421 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#include "opentx.h" +#include "hal/adc_driver.h" +#include "stm32_hal_adc.h" + +static bool adc_disable_dma(DMA_Stream_TypeDef * dma_stream); +static void adc_dma_clear_flags(DMA_Stream_TypeDef * dma_stream); + +static void adc_init_pins() +{ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + +#if defined(ADC_GPIOA_PINS) + GPIO_InitStructure.GPIO_Pin = ADC_GPIOA_PINS; + GPIO_Init(GPIOA, &GPIO_InitStructure); +#endif + +#if defined(ADC_GPIOB_PINS) + GPIO_InitStructure.GPIO_Pin = ADC_GPIOB_PINS; + GPIO_Init(GPIOB, &GPIO_InitStructure); +#endif + +#if defined(ADC_GPIOC_PINS) + GPIO_InitStructure.GPIO_Pin = ADC_GPIOC_PINS; + GPIO_Init(GPIOC, &GPIO_InitStructure); +#endif + +#if defined(ADC_GPIOF_PINS) + GPIO_InitStructure.GPIO_Pin = ADC_GPIOF_PINS; + GPIO_Init(GPIOF, &GPIO_InitStructure); +#endif +} + +static void adc_setup_scan_mode(ADC_TypeDef* ADCx, uint8_t nconv) +{ + ADC_InitTypeDef ADC_InitStructure; + ADC_StructInit(&ADC_InitStructure); + + ADC_InitStructure.ADC_ScanConvMode = ENABLE; // Sets ADC_CR1_SCAN + ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Clears ADC_CR2_CONT + ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // Software trigger + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; + ADC_InitStructure.ADC_NbrOfConversion = nconv; // Channel count + + ADC_Init(ADCx, &ADC_InitStructure); + + // enable ADC_MAIN + ADC_Cmd(ADCx, ENABLE); // ADC_CR2_ADON + // enable DMA for ADC + ADC_DMACmd(ADCx, ENABLE); // ADC_CR2_DMA + ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE); // ADC_CR2_DDS +} + +stm32_hal_adc_channel ADC_MAIN_channels[] = { + {ADC_CHANNEL_STICK_LH, ADC_SAMPTIME}, + {ADC_CHANNEL_STICK_LV, ADC_SAMPTIME}, + {ADC_CHANNEL_STICK_RV, ADC_SAMPTIME}, + {ADC_CHANNEL_STICK_RH, ADC_SAMPTIME}, +#if defined(PCBX10) + { ADC_CHANNEL_POT1, ADC_SAMPTIME }, + { ADC_CHANNEL_POT2, ADC_SAMPTIME }, + { ADC_CHANNEL_POT3, ADC_SAMPTIME }, + { ADC_CHANNEL_EXT1, ADC_SAMPTIME }, + { ADC_CHANNEL_EXT2, ADC_SAMPTIME }, + { ADC_CHANNEL_SLIDER1, ADC_SAMPTIME }, + { ADC_CHANNEL_SLIDER2, ADC_SAMPTIME }, + { ADC_CHANNEL_BATT, ADC_SAMPTIME } +#else +#if defined(RADIO_T8) || defined(RADIO_TLITE) + // fake channels to fill unsused POT1/POT2 + {0, 0}, + {0, 0}, +#elif defined(PCBX7) || defined(PCBXLITE) + {ADC_CHANNEL_POT1, ADC_SAMPTIME}, + {ADC_CHANNEL_POT2, ADC_SAMPTIME}, +#elif defined(PCBX9LITE) + {ADC_CHANNEL_POT1, ADC_SAMPTIME}, +#elif defined(PCBX9E) + {ADC_CHANNEL_POT2, ADC_SAMPTIME}, + {ADC_CHANNEL_POT3, ADC_SAMPTIME}, + {ADC_CHANNEL_POT4, ADC_SAMPTIME}, + {ADC_CHANNEL_SLIDER3, ADC_SAMPTIME}, + {ADC_CHANNEL_SLIDER4, ADC_SAMPTIME}, +#elif defined(PCBX9D) || defined(PCBX9DP) + {ADC_CHANNEL_POT1, ADC_SAMPTIME}, + {ADC_CHANNEL_POT2, ADC_SAMPTIME}, + {ADC_CHANNEL_POT3, ADC_SAMPTIME}, + {ADC_CHANNEL_SLIDER1, ADC_SAMPTIME}, + {ADC_CHANNEL_SLIDER2, ADC_SAMPTIME}, +#elif defined(PCBNV14) + {ADC_CHANNEL_POT1, ADC_SAMPTIME}, + {ADC_CHANNEL_POT2, ADC_SAMPTIME}, + {ADC_CHANNEL_SWA, ADC_SAMPTIME}, + {ADC_CHANNEL_SWC, ADC_SAMPTIME}, + {ADC_CHANNEL_SWE, ADC_SAMPTIME}, + {ADC_CHANNEL_SWF, ADC_SAMPTIME}, + {ADC_CHANNEL_SWG, ADC_SAMPTIME}, + {ADC_CHANNEL_SWH, ADC_SAMPTIME}, +#endif + {ADC_CHANNEL_BATT, ADC_SAMPTIME}, + {ADC_Channel_Vbat, ADC_SAMPTIME} +#endif +}; + +static const stm32_hal_adc_channel* ADC_MAIN_get_channels() +{ +#if (NUM_PWMSTICKS > 0) + if (STICKS_PWM_ENABLED()) + return ADC_MAIN_channels + 4; +#endif + return ADC_MAIN_channels + FIRST_ANALOG_ADC; +} + +static uint8_t ADC_MAIN_get_nconv() +{ + return NUM_ANALOGS_ADC; // based on STICKS_PWM_ENABLED() +} + +#if defined(ADC_EXT) +#if defined(PCBX9E) + +static const stm32_hal_adc_channel ADC_EXT_channels[] = { + {ADC_CHANNEL_POT1, ADC_SAMPTIME}, + {ADC_CHANNEL_SLIDER1, ADC_SAMPTIME}, + {ADC_CHANNEL_SLIDER2, ADC_SAMPTIME} +}; + +static uint8_t ADC_EXT_get_nconv() { return NUM_ANALOGS_ADC_EXT; } + +#elif defined(PCBX10) + +static const stm32_hal_adc_channel ADC_EXT_channels[] = { + { ADC_Channel_Vbat, ADC_SAMPTIME } +}; + +static uint8_t ADC_EXT_get_nconv() { return 1; } + +#elif defined(PCBNV14) + +static const stm32_hal_adc_channel ADC_EXT_channels[] = { + {ADC_CHANNEL_SWB, ADC_SAMPTIME}, + {ADC_CHANNEL_SWD, ADC_SAMPTIME}, +}; + +static uint8_t ADC_EXT_get_nconv() { return NUM_ANALOGS_ADC_EXT; } + +#endif + +static const stm32_hal_adc_channel* ADC_EXT_get_channels() +{ + return ADC_EXT_channels; +} + +#endif + +static uint16_t* ADC_MAIN_get_dma_buffer() +{ + return &adcValues[FIRST_ANALOG_ADC]; +} + +#if defined(ADC_EXT) && defined(ADC_EXT_DMA_Stream) +static uint16_t* ADC_EXT_get_dma_buffer() +{ + return adcValues + NUM_ANALOGS_ADC + FIRST_ANALOG_ADC; +} +#endif + +stm32_hal_adc ADC_hal_def[] = { + { + ADC_MAIN, + ADC_DMA_Stream, ADC_DMA_Channel, ADC_MAIN_get_dma_buffer, + ADC_MAIN_get_nconv, ADC_MAIN_get_channels + }, +#if defined(ADC_EXT) + { + ADC_EXT, +#if defined(ADC_EXT_DMA_Stream) + ADC_EXT_DMA_Stream, ADC_EXT_DMA_Channel, ADC_EXT_get_dma_buffer, +#else + nullptr, 0, nullptr, +#endif + ADC_EXT_get_nconv, ADC_EXT_get_channels + }, +#endif + // required to detect end of ADC definitions + { nullptr, nullptr, 0, nullptr, nullptr, nullptr }, +}; + +static void adc_init_channels(ADC_TypeDef* adc, const stm32_hal_adc_channel* chan, + uint8_t nconv) +{ + if (!chan || !nconv) return; + + uint8_t rank = 1; + while (nconv > 0) { + ADC_RegularChannelConfig(adc, chan->adc_channel, rank, chan->sample_time); + nconv--; rank++; chan++; + } +} + +static bool adc_init_dma_stream(ADC_TypeDef* adc, DMA_Stream_TypeDef * dma_stream, + uint32_t dma_channel, uint16_t* dest, uint8_t nconv) +{ + // Disable DMA before continuing (see ref. manual "Stream configuration procedure") + if (!adc_disable_dma(dma_stream)) + return false; + + // Clear Interrupt flags + adc_dma_clear_flags(dma_stream); + + // setup DMA request + dma_stream->PAR = CONVERT_PTR_UINT(&adc->DR); + dma_stream->M0AR = CONVERT_PTR_UINT(dest); + dma_stream->NDTR = nconv; + // Very high priority, 1 byte transfers, increment memory + dma_stream->CR = DMA_SxCR_PL | dma_channel | DMA_SxCR_MSIZE_0 | + DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; + // disable direct mode, half full FIFO + dma_stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; + return true; +} + +static bool stm32_hal_adc_init() +{ + adc_init_pins(); + + // Init common to all ADCs + ADC_CommonInitTypeDef ADC_CommonInitStruct; + ADC_CommonStructInit(&ADC_CommonInitStruct); + ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent; + ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2; + ADC_CommonInit(&ADC_CommonInitStruct); + + const stm32_hal_adc* adc_def = ADC_hal_def; + while (adc_def->adc) { + uint8_t nconv = 0; + if (adc_def->get_nconv) { + nconv = adc_def->get_nconv(); + if (nconv > 0) { + adc_setup_scan_mode(adc_def->adc, nconv); + + // configure each channel + if (adc_def->get_channels) { + const stm32_hal_adc_channel* chan = adc_def->get_channels(); + adc_init_channels(adc_def->adc, chan, nconv); + } + + if (adc_def->dma_stream && adc_def->get_dma_buffer) { + uint16_t* dma_buffer = adc_def->get_dma_buffer(); + if (!adc_init_dma_stream(adc_def->adc, adc_def->dma_stream, + adc_def->dma_channel, dma_buffer, nconv)) + return false; + } + } + } + // move to next ADC definition + adc_def++; + } + + //TODO: move VBat & PWM sticks somewhere else. + + // Enable vbat sensor + ADC_VBATCmd(ENABLE); + +#if NUM_PWMSTICKS > 0 + if (STICKS_PWM_ENABLED()) { + sticksPwmInit(); + } +#endif + return true; +} + +#define DMA_Stream0_IT_MASK (uint32_t)(DMA_LISR_FEIF0 | DMA_LISR_DMEIF0 | \ + DMA_LISR_TEIF0 | DMA_LISR_HTIF0 | \ + DMA_LISR_TCIF0) + +#define DMA_Stream4_IT_MASK (uint32_t)(DMA_HISR_FEIF4 | DMA_HISR_DMEIF4 | \ + DMA_HISR_TEIF4 | DMA_HISR_HTIF4 | \ + DMA_HISR_TCIF4) + +static void adc_dma_clear_flags(DMA_Stream_TypeDef * dma_stream) +{ + // no other choice, sorry for that... + if (dma_stream == DMA2_Stream4) { + /* Reset interrupt pending bits for DMA2 Stream4 */ + DMA2->HIFCR = DMA_Stream4_IT_MASK; + + } else if (dma_stream == DMA2_Stream0) { + /* Reset interrupt pending bits for DMA2 Stream0 */ + DMA2->LIFCR = DMA_Stream0_IT_MASK; + } +} + +static bool adc_start_dma_conversion(ADC_TypeDef* ADCx, + DMA_Stream_TypeDef * dma_stream) +{ + // Disable DMA before continuing (see ref. manual "Stream configuration procedure") + if (!adc_disable_dma(dma_stream)) + return false; + + // Clear Interrupt flags + adc_dma_clear_flags(dma_stream); + + // Clear ADC status register + ADCx->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); + + // Enable DMA + dma_stream->CR |= DMA_SxCR_EN; + + // Trigger ADC start + ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; + return true; +} + +static bool adc_disable_dma(DMA_Stream_TypeDef* dma_stream) +{ + dma_stream->CR &= ~(uint32_t)DMA_SxCR_EN; + + // wait until DMA EN bit gets cleared by hardware + uint16_t uiTimeout = 1000; + while (dma_stream->CR & (uint32_t)DMA_SxCR_EN) { + if (--uiTimeout == 0) { + // Timeout. Failed to disable DMA + return false; + } + } + return true; +} + +static void adc_start_single_conversion(ADC_TypeDef* ADCx) +{ + ADCx->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); + ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; +} + +static bool stm32_hal_adc_start_read() +{ + const stm32_hal_adc* adc_def = ADC_hal_def; + while (adc_def->adc) { + uint8_t nconv = 0; + if (adc_def->get_nconv) { + nconv = adc_def->get_nconv(); + if (nconv > 0) { + if (adc_def->dma_stream && adc_def->get_dma_buffer) { + if (!adc_start_dma_conversion(adc_def->adc, adc_def->dma_stream)) + return false; + } else if (nconv == 1) { + adc_start_single_conversion(adc_def->adc); + } + } + } + // move to next ADC definition + adc_def++; + } + return true; +} + +static void stm32_hal_adc_wait_completion() +{ + //TODO: + // - iterate through ADCs + // - replace with IRQ trigger (both) + // - move RTC batt reading somewhere else + +#if defined(ADC_EXT) && defined(ADC_EXT_DMA_Stream) + // Wait for all ADCs to complete + for (unsigned int i=0; i<10000; i++) { + if (DMA_GetFlagStatus(ADC_DMA_Stream, ADC_DMA_TC_Flag) != RESET && + DMA_GetFlagStatus(ADC_EXT_DMA_Stream, ADC_EXT_DMA_TC_Flag) != RESET) { + break; + } + } + //TODO: move into completion IRQ trigger + adc_disable_dma(ADC_DMA_Stream); + adc_disable_dma(ADC_EXT_DMA_Stream); +#else + // Wait only for the main ADC, and hope others are done as well + for (unsigned int i = 0; i < 10000; i++) { + if (DMA_GetFlagStatus(ADC_DMA_Stream, ADC_DMA_TC_Flag) != RESET) { + break; + } + } + //TODO: move into completion IRQ trigger + adc_disable_dma(ADC_DMA_Stream); + +#if defined(ADC_EXT) && !defined(ADC_EXT_DMA_Stream) + if (isVBatBridgeEnabled()) { + rtcBatteryVoltage = ADC_EXT->DR; + } +#endif +#endif +} + +const etx_hal_adc_driver_t stm32_hal_adc_driver = { + stm32_hal_adc_init, + stm32_hal_adc_start_read, + stm32_hal_adc_wait_completion +}; diff --git a/radio/src/targets/common/arm/stm32/stm32_hal_adc.h b/radio/src/targets/common/arm/stm32/stm32_hal_adc.h new file mode 100644 index 000000000..3a98f6113 --- /dev/null +++ b/radio/src/targets/common/arm/stm32/stm32_hal_adc.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) EdgeTx + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#pragma once + +struct stm32_hal_adc_channel { + const uint8_t adc_channel; + const uint8_t sample_time; +}; + +typedef const stm32_hal_adc_channel* (*stm32_hal_adc_get_channels)(); +typedef uint8_t (*stm32_hal_adc_get_nconv)(); +typedef uint16_t* (*stm32_hal_adc_get_dma_buffer)(); + +struct stm32_hal_adc { + ADC_TypeDef* adc; + + DMA_Stream_TypeDef* dma_stream; + uint32_t dma_channel; + const stm32_hal_adc_get_dma_buffer get_dma_buffer; + + const stm32_hal_adc_get_nconv get_nconv; + const stm32_hal_adc_get_channels get_channels; +}; + +// Driver to be passed to adcInit() +extern const etx_hal_adc_driver_t stm32_hal_adc_driver; diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 70e1a2f82..2c71792a1 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -58,7 +58,8 @@ if (PCB STREQUAL X10) ) set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} - ../common/arm/stm32/adc_driver.cpp + ../common/arm/stm32/stm32_hal_adc.cpp + ../../hal/adc_driver.cpp ) set(BITMAPS_TARGET x10_bitmaps) set(FONTS_TARGET x10_fonts) @@ -137,6 +138,7 @@ elseif (PCB STREQUAL X12S) ) set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} + ../../hal/adc_driver.cpp x12s_adc_driver.cpp ) set(BITMAPS_TARGET x12s_bitmaps) diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index f24f8f1bf..4faa08b93 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -20,6 +20,16 @@ #include "opentx.h" +#include "hal/adc_driver.h" + +#if !defined(PCBX12S) + #include "../common/arm/stm32/stm32_hal_adc.h" + #define ADC_DRIVER stm32_hal_adc_driver +#else + #include "x12s_adc_driver.h" + #define ADC_DRIVER x12s_adc_driver +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -197,7 +207,9 @@ void boardInit() } #endif - adcInit(); + if (!adcInit(&ADC_DRIVER)) + TRACE("adcInit failed"); + lcdInit(); backlightInit(); diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 5e009f041..eebb201c3 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -318,12 +318,14 @@ #define ADC_CHANNEL_EXT1 ADC_Channel_6 // ADC3_IN6 #define ADC_CHANNEL_EXT2 ADC_Channel_7 // ADC3_IN7 #define ADC_MAIN ADC3 + #define ADC_EXT ADC1 #define ADC_SAMPTIME 3 #define ADC_DMA DMA2 - #define ADC_DMA_SxCR_CHSEL DMA_SxCR_CHSEL_1 + #define ADC_DMA_Channel DMA_Channel_2 #define ADC_DMA_Stream DMA2_Stream0 - #define ADC_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) #define ADC_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) + #define ADC_DMA_TC_Flag DMA_FLAG_TCIF0 + #if defined(RADIO_TX16S) #define ADC_VREF_PREC2 330 #elif defined(RADIO_T16) || defined(RADIO_T18) @@ -333,9 +335,6 @@ #endif #endif -#define ADC_MAIN_SMPR1 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24); -#define ADC_MAIN_SMPR2 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24) + (ADC_SAMPTIME << 27); - // Power #if defined(RADIO_T18) #define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOJ | RCC_AHB1Periph_GPIOB diff --git a/radio/src/targets/horus/x12s_adc_driver.cpp b/radio/src/targets/horus/x12s_adc_driver.cpp index b8127bddc..737cc52d7 100644 --- a/radio/src/targets/horus/x12s_adc_driver.cpp +++ b/radio/src/targets/horus/x12s_adc_driver.cpp @@ -19,9 +19,8 @@ */ #include "opentx.h" +#include "x12s_adc_driver.h" -uint16_t adcValues[NUM_ANALOGS] __DMA; -uint16_t rtcBatteryVoltage; #define ADC_CS_HIGH() (ADC_SPI_GPIO->BSRRL = ADC_SPI_PIN_CS) #define ADC_CS_LOW() (ADC_SPI_GPIO->BSRRH = ADC_SPI_PIN_CS) @@ -100,7 +99,7 @@ static void ADS7952_Init() ADC_CS_HIGH(); } -void adcInit() +static bool x12s_adc_init() { ADS7952_Init(); @@ -137,11 +136,8 @@ void adcInit() ADC1->SQR3 = (ADC_Channel_Vbat << 0); ADC1->SMPR1 = (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24); ADC1->SMPR2 = (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24) + (ADC_SAMPTIME << 27); -} -uint16_t getRTCBatteryVoltage() -{ - return (rtcBatteryVoltage * 2 * ADC_VREF_PREC2) / 2048; + return true; } const uint16_t adcCommands[MOUSE1+2] = @@ -227,7 +223,9 @@ bool adcOnChipReadFinished() return (ADC_DMA->LISR & DMA_LISR_TCIF0); } -void adcRead() +// Re-declare adcRead() +// (takes precedence over hal/adc_driver.cpp) +bool adcRead() { uint16_t temp[NUM_ANALOGS-MOUSE1] = { 0 }; uint8_t noInternalReads = 0; @@ -266,16 +264,17 @@ void adcRead() if (isVBatBridgeEnabled()) { rtcBatteryVoltage = ADC1->DR; } + + return true; } -#if !defined(SIMU) -const int8_t ana_direction[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, -1,-1, -1,1, 0,0,0}; +//TODO: implement these based on stm32_hal_adc.cpp +//static bool x12s_adc_init(); +//static bool x12s_adc_start_read(); +//static void x12s_adc_wait_completion(); -uint16_t getAnalogValue(uint8_t index) -{ - if (ana_direction[index] < 0) - return 4095 - adcValues[index]; - else - return adcValues[index]; -} -#endif // #if !defined(SIMU) +const etx_hal_adc_driver_t x12s_adc_driver = { + x12s_adc_init, + nullptr,//x12s_adc_start_read, + nullptr,//x12s_adc_wait_completion +}; diff --git a/radio/src/targets/horus/x12s_adc_driver.h b/radio/src/targets/horus/x12s_adc_driver.h new file mode 100644 index 000000000..7e8fc8c2c --- /dev/null +++ b/radio/src/targets/horus/x12s_adc_driver.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) EdgeTx + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#pragma once + +#include "hal/adc_driver.h" + +extern const etx_hal_adc_driver_t x12s_adc_driver; diff --git a/radio/src/targets/nv14/CMakeLists.txt b/radio/src/targets/nv14/CMakeLists.txt index 242b0bd09..303995b96 100644 --- a/radio/src/targets/nv14/CMakeLists.txt +++ b/radio/src/targets/nv14/CMakeLists.txt @@ -48,21 +48,16 @@ add_definitions(-DINTERNAL_MODULE_AFHDS2A) set(TARGET_SRC ${TARGET_SRC} audio_spi_driver.cpp - adc_driver.cpp -# ../common/arm/stm32/adc_driver.cpp ../common/arm/stm32/mixer_scheduler_driver.cpp ../common/arm/stm32/timers_driver.cpp ) -#set(FIRMWARE_TARGET_SRC -# ${FIRMWARE_TARGET_SRC} -# x12s_adc_driver.cpp -# ) - set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} battery_driver.cpp ../horus/flyskyHallStick_driver.cpp + ../common/arm/stm32/stm32_hal_adc.cpp + ../../hal/adc_driver.cpp ) set(BITMAPS_TARGET nv14_bitmaps) diff --git a/radio/src/targets/nv14/adc_driver.cpp b/radio/src/targets/nv14/adc_driver.cpp deleted file mode 100644 index 203ee1f34..000000000 --- a/radio/src/targets/nv14/adc_driver.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Based on code named - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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. - */ - -#include "opentx.h" - -#if defined(SIMU) - // not needed -#elif defined(PCBNV14) - const int8_t ana_direction[NUM_ANALOGS] = { 0 /*STICK1*/, 0 /*STICK2*/, 0 /*STICK3*/, 0 /*STICK4*/, - 0 /*POT1*/, 0 /*POT2*/, 0 /*SWA*/, 0 /*SWB*/, - 0 /*SWC*/, -1 /*SWD*/, 0 /*SWE*/, -1 /*SWF*/, - 0 /*SWH*/, 0 /*SWG*/, - 0 /*TX_VOLTAGE*/ }; - const uint8_t anas_mapping[NUM_ANALOGS] = { 0 /*STICK1*/, 1 /*STICK2*/, 2 /*STICK3*/, 3 /*STICK4*/, - 4 /*POT1*/, 5 /*POT2*/, 6 /*SWA*/, 13 /*SWB*/, - 7 /*SWC*/, 14 /*SWD*/, 8 /*SWE*/, 9 /*SWF*/, - 11/*SWH*/, 10/*SWG*/, - 12 /*TX_VOLTAGE*/ }; - #define ANAS_MAPPING anas_mapping // TODO => hal.h -#elif defined(PCBX10) - const int8_t ana_direction[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, 1,-1, 1, 1,1}; -#elif defined(PCBX9E) -#if defined(HORUS_STICKS) - const int8_t ana_direction[NUM_ANALOGS] = {1,-1,1,-1, -1,-1,-1,1, -1,1,-1,-1, -1}; -#else - const int8_t ana_direction[NUM_ANALOGS] = {1,1,-1,-1, -1,-1,-1,1, -1,1,-1,-1, -1}; -#endif - const uint8_t anas_mapping[NUM_ANALOGS] = { 0 /*STICK1*/, 1 /*STICK2*/, 2 /*STICK3*/, 3 /*STICK4*/, - 10 /*POT1*/, 4 /*POT2*/, 5 /*POT3*/, 6 /*POT4*/, - 11 /*SLIDER1*/, 12 /*SLIDER2*/, 7 /*SLIDER3*/, 8 /*SLIDER4*/, - 9 /*TX_VOLTAGE*/ }; - #define ANAS_MAPPING anas_mapping -#elif defined(PCBX9DP) - const int8_t ana_direction[NUM_ANALOGS] = {1,-1,1,-1, 1,1,-1, 1,1, 1}; -#elif defined(PCBX7) - const int8_t ana_direction[NUM_ANALOGS] = {-1,1,-1,1, 1,1, 1}; -#elif defined(PCBI8) - const int8_t ana_direction[NUM_ANALOGS] = {/*sticks*/1,1,1,1, /*pots*/1,1, /*switches*/1,1,1,1,1,1, /*batt*/1,1}; -#elif defined(PCBXLITE) - const int8_t ana_direction[NUM_ANALOGS] = {1,-1,-1,1, -1,1, 1}; -#elif defined(REV4a) - const int8_t ana_direction[NUM_ANALOGS] = {1,-1,1,-1, 1,-1,0, 1,1, 1}; -#else - const int8_t ana_direction[NUM_ANALOGS] = {1,-1,1,-1, 1,1,0, 1,1, 1}; -#endif - -#if NUM_PWMSTICKS > 0 - #define FIRST_ANALOG_ADC (STICKS_PWM_ENABLED() ? NUM_PWMSTICKS : 0) - #define NUM_MAIN_ANALOGS_ADC (STICKS_PWM_ENABLED() ? (NUM_MAIN_ANALOGS - NUM_PWMSTICKS) : NUM_MAIN_ANALOGS) -#elif defined(PCBX9E) - #define FIRST_ANALOG_ADC 0 - #define NUM_MAIN_ANALOGS_ADC 10 - #define NUM_MAIN_ANALOGS_ADC_EXT (NUM_MAIN_ANALOGS - 10) -#elif defined(PCBNV14) && defined(FLYSKY_HALL_STICKS) - #define FIRST_ANALOG_ADC 4 - #define NUM_MAIN_ANALOGS_ADC 9 - #define NUM_SUB_ANALOGS_ADC 2 -#else - #define FIRST_ANALOG_ADC 0 - #define FIRST_SUB_ANALOG_ADC 0 - #define NUM_MAIN_ANALOGS_ADC (SUB_ANALOG_POS) - #define NUM_SUB_ANALOGS_ADC (NUM_ANALOGS - SUB_ANALOG_POS) -#endif -#ifndef NUM_SUB_ANALOGS_ADC -#define NUM_SUB_ANALOGS_ADC 0 -#endif -uint16_t adcValues[NUM_ANALOGS] __DMA; - -void adcInit() -{ - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - -#if defined(ADC_GPIOA_PINS) - GPIO_InitStructure.GPIO_Pin = ADC_GPIOA_PINS; - GPIO_Init(GPIOA, &GPIO_InitStructure); -#endif - -#if defined(ADC_GPIOB_PINS) - GPIO_InitStructure.GPIO_Pin = ADC_GPIOB_PINS; - GPIO_Init(GPIOB, &GPIO_InitStructure); -#endif - -#if defined(ADC_GPIOC_PINS) - GPIO_InitStructure.GPIO_Pin = ADC_GPIOC_PINS; - GPIO_Init(GPIOC, &GPIO_InitStructure); -#endif - -#if defined(ADC_GPIOF_PINS) - GPIO_InitStructure.GPIO_Pin = ADC_GPIOF_PINS; - GPIO_Init(GPIOF, &GPIO_InitStructure); -#endif - - ADC_MAIN->CR1 = ADC_CR1_SCAN; - ADC_MAIN->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; - ADC_MAIN->SQR1 = (NUM_MAIN_ANALOGS_ADC-1) << 20; // bits 23:20 = number of conversions -#if NUM_SUB_ANALOGS_ADC > 0 - ADC_SUB->CR1 = ADC_CR1_SCAN; - ADC_SUB->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; - ADC_SUB->SQR1 = (NUM_SUB_ANALOGS_ADC-1) << 20; // bits 23:20 = number of conversions -#endif -#if defined(PCBX10) - if (STICKS_PWM_ENABLED()) { - ADC_MAIN->SQR2 = (ADC_CHANNEL_EXT1<<0) + (ADC_CHANNEL_EXT2<<5); // conversions 7 and more - ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_POT3<<10) + (ADC_CHANNEL_SLIDER1<<15) + (ADC_CHANNEL_SLIDER2<<20) + (ADC_CHANNEL_BATT<<25); // conversions 1 to 6 - } - else { - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10) + (ADC_CHANNEL_BATT<<15) + (ADC_CHANNEL_EXT1<<20) + (ADC_CHANNEL_EXT2<<25); // conversions 7 and more - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 - } -#elif defined(PCBX9E) - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT4<<0) + (ADC_CHANNEL_SLIDER3<<5) + (ADC_CHANNEL_SLIDER4<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT2<<20) + (ADC_CHANNEL_POT3<<25); // conversions 1 to 6 -#elif defined(PCBXLITE) - if (STICKS_PWM_ENABLED()) { - ADC_MAIN->SQR2 = 0; - ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_BATT<<10); - } - else { - ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT<<0); - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 - } -#elif defined(PCBX7) - // TODO why do we invert POT1 and POT2 here? - ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT<<0); // conversions 7 and more - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<25) + (ADC_CHANNEL_POT2<<20); // conversions 1 to 6 -#elif defined(PCBI8) - ADC_MAIN->SQR2 = (ADC_CHANNEL_SWE<<0) + (ADC_CHANNEL_SWF<<5) + (ADC_CHANNEL_LIBATT<<10) + (ADC_CHANNEL_DRYBATT<<15); // conversions 7 and more - ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_SWA<<10) + (ADC_CHANNEL_SWB<<15) + (ADC_CHANNEL_SWC<<20) + (ADC_CHANNEL_SWD<<25); // conversions 1 to 6 -#elif defined(PCBNV14) - #if !defined(FLYSKY_HALL_STICKS) - ADC_MAIN->SQR1 |= (ADC_CHANNEL_BATT <<0 ); - ADC_MAIN->SQR2 = (ADC_CHANNEL_SWA << 0) + (ADC_CHANNEL_SWC << 5) + (ADC_CHANNEL_SWE << 10) + (ADC_CHANNEL_SWF << 15) + (ADC_CHANNEL_SWG << 20) + (ADC_CHANNEL_SWH << 25); // conversions 7 and more - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 - ADC_SUB->SQR3 = (ADC_CHANNEL_SWB<<0) + (ADC_CHANNEL_SWD<<5); // conversions 1 to 2 - #else - ADC_MAIN->SQR2 = (ADC_CHANNEL_SWG << 0) + (ADC_CHANNEL_SWH << 5) + (ADC_CHANNEL_BATT << 10); // conversions 7 and more - ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_SWA<<10) + (ADC_CHANNEL_SWC<<15) + (ADC_CHANNEL_SWE<<20) + (ADC_CHANNEL_SWF<<25); // conversions 1 to 6 - ADC_SUB->SQR3 = (ADC_CHANNEL_SWB<<0) + (ADC_CHANNEL_SWD<<5); // conversions 1 to 2 - #endif -#else - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more - ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 -#endif - - ADC_MAIN->SMPR1 = ADC_SAMPTIME + (ADC_SAMPTIME<<3) + (ADC_SAMPTIME<<6) + (ADC_SAMPTIME<<9) + (ADC_SAMPTIME<<12) + (ADC_SAMPTIME<<15) + (ADC_SAMPTIME<<18) + (ADC_SAMPTIME<<21) + (ADC_SAMPTIME<<24); - ADC_MAIN->SMPR2 = ADC_SAMPTIME + (ADC_SAMPTIME<<3) + (ADC_SAMPTIME<<6) + (ADC_SAMPTIME<<9) + (ADC_SAMPTIME<<12) + (ADC_SAMPTIME<<15) + (ADC_SAMPTIME<<18) + (ADC_SAMPTIME<<21) + (ADC_SAMPTIME<<24) + (ADC_SAMPTIME<<27); - - ADC->CCR = 0; - - ADC_MAIN_DMA_Stream->CR = DMA_SxCR_PL | ADC_MAIN_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; - ADC_MAIN_DMA_Stream->PAR = CONVERT_PTR_UINT(&ADC_MAIN->DR); - ADC_MAIN_DMA_Stream->M0AR = CONVERT_PTR_UINT(&adcValues[FIRST_ANALOG_ADC]); - ADC_MAIN_DMA_Stream->NDTR = NUM_MAIN_ANALOGS_ADC; - ADC_MAIN_DMA_Stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; - -#if NUM_SUB_ANALOGS_ADC > 0 - ADC_SUB->SMPR1 = ADC_SAMPTIME + (ADC_SAMPTIME<<3) + (ADC_SAMPTIME<<6) + (ADC_SAMPTIME<<9) + (ADC_SAMPTIME<<12) + (ADC_SAMPTIME<<15) + (ADC_SAMPTIME<<18) + (ADC_SAMPTIME<<21) + (ADC_SAMPTIME<<24); - ADC_SUB->SMPR2 = ADC_SAMPTIME + (ADC_SAMPTIME<<3) + (ADC_SAMPTIME<<6) + (ADC_SAMPTIME<<9) + (ADC_SAMPTIME<<12) + (ADC_SAMPTIME<<15) + (ADC_SAMPTIME<<18) + (ADC_SAMPTIME<<21) + (ADC_SAMPTIME<<24) + (ADC_SAMPTIME<<27); - - ADC->CCR = 0; - - ADC_SUB_DMA_Stream->CR = DMA_SxCR_PL | ADC_SUB_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; - ADC_SUB_DMA_Stream->PAR = CONVERT_PTR_UINT(&ADC_SUB->DR); - ADC_SUB_DMA_Stream->M0AR = CONVERT_PTR_UINT(&adcValues[SUB_ANALOG_POS]); - ADC_SUB_DMA_Stream->NDTR = NUM_SUB_ANALOGS_ADC; - ADC_SUB_DMA_Stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; -#endif -#if defined(PCBX9E) - ADC_EXT->CR1 = ADC_CR1_SCAN; - ADC_EXT->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; - ADC_EXT->SQR1 = (NUM_MAIN_ANALOGS_ADC_EXT-1) << 20; - ADC_EXT->SQR2 = 0; - ADC_EXT->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10); // conversions 1 to 3 - ADC_EXT->SMPR1 = 0; - ADC_EXT->SMPR2 = (ADC_EXT_SAMPTIME<<(3*ADC_CHANNEL_POT1)) + (ADC_EXT_SAMPTIME<<(3*ADC_CHANNEL_SLIDER1)) + (ADC_EXT_SAMPTIME<<(3*ADC_CHANNEL_SLIDER2)); - - ADC_EXT_DMA_Stream->CR = DMA_SxCR_PL | DMA_SxCR_CHSEL_1 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; - ADC_EXT_DMA_Stream->PAR = CONVERT_PTR_UINT(&ADC_EXT->DR); - ADC_EXT_DMA_Stream->M0AR = CONVERT_PTR_UINT(adcValues + NUM_MAIN_ANALOGS_ADC); - ADC_EXT_DMA_Stream->NDTR = NUM_MAIN_ANALOGS_ADC_EXT; - ADC_EXT_DMA_Stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; -#endif - -#if NUM_PWMSTICKS > 0 - if (STICKS_PWM_ENABLED()) { - sticksPwmInit(); - } -#endif - //Avoid reading wrong values when the adcRead not be called. - adcRead(); -} - -void adcSingleRead() -{ - ADC_MAIN_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA - ADC_MAIN->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); - ADC_MAIN_SET_DMA_FLAGS(); - ADC_MAIN_DMA_Stream->CR |= DMA_SxCR_EN; // Enable DMA - ADC_MAIN->CR2 |= (uint32_t) ADC_CR2_SWSTART; -#if NUM_SUB_ANALOGS_ADC > 0 - ADC_SUB_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA - ADC_SUB->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); - ADC_SUB_SET_DMA_FLAGS(); - ADC_SUB_DMA_Stream->CR |= DMA_SxCR_EN; // Enable DMA - ADC_SUB->CR2 |= (uint32_t) ADC_CR2_SWSTART; -#endif -#if defined(PCBX9E) - ADC_EXT_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA - ADC_EXT->SR &= ~(uint32_t) ( ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR ); - ADC_EXT_SET_DMA_FLAGS(); - ADC_EXT_DMA_Stream->CR |= DMA_SxCR_EN; // Enable DMA - ADC_EXT->CR2 |= (uint32_t)ADC_CR2_SWSTART; -#endif - -#if defined(PCBX9E) - for (unsigned int i=0; i<10000; i++) { - if (ADC_TRANSFER_COMPLETE() && ADC_EXT_TRANSFER_COMPLETE()) { - break; - } - } - ADC_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA - ADC_EXT_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA -#else - for (unsigned int i = 0; i < 10000; i++) { -#if defined(PCBNV14) - if (ADC_MAIN_TRANSFER_COMPLETE() && ADC_SUB_TRANSFER_COMPLETE()) - { - break; - } -#else - if (ADC_MAIN_TRANSFER_COMPLETE()) - { - break; - } -#endif - } - - ADC_MAIN_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA -#if defined(PCBNV14) - ADC_SUB_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA -#endif -#endif -} - -void adcRead() -{ - int i, j; - - uint16_t temp[NUM_ANALOGS] = { 0 }; - - for (i = 0; i < 4; i++) - { - adcSingleRead(); - - for (j = FIRST_ANALOG_ADC; j < NUM_ANALOGS; j++) - { - uint16_t val = adcValues[j]; -#if defined(JITTER_MEASURE) - if (JITTER_MEASURE_ACTIVE()) { - rawJitter[j].measure(val); - } -#endif - temp[j] += val; - } - } - - for (uint8_t x = FIRST_ANALOG_ADC; x < NUM_ANALOGS; x++) - { - adcValues[x] = temp[x] >> 2; - } - -#if NUM_PWMSTICKS > 0 - if (STICKS_PWM_ENABLED()) { - sticksPwmRead(adcValues); - } -#endif -} - -#if !defined(SIMU) -uint16_t getRTCBatteryVoltage() -{ - #warning "TODO RTC voltage" - return 330; -} - -uint16_t getAnalogValue(uint8_t index) -{ - if (IS_POT(index) && !IS_POT_SLIDER_AVAILABLE(index)) { - // Use fixed analog value for non-existing and/or non-connected pots. - // Non-connected analog inputs will slightly follow the adjacent connected analog inputs, - // which produces ghost readings on these inputs. - return 0; - } - -#if defined(ANAS_MAPPING) - index = ANAS_MAPPING[index]; -#endif - - if (ana_direction[index] < 0) - return 4095 - adcValues[index]; - else - return adcValues[index]; -} -#endif // #if !defined(SIMU) diff --git a/radio/src/targets/nv14/board.cpp b/radio/src/targets/nv14/board.cpp index c088584a7..b5c8dc5ae 100644 --- a/radio/src/targets/nv14/board.cpp +++ b/radio/src/targets/nv14/board.cpp @@ -20,6 +20,10 @@ #include "opentx.h" #include "touch.h" + +#include "hal/adc_driver.h" +#include "../common/arm/stm32/stm32_hal_adc.h" + #if defined(__cplusplus) && !defined(SIMU) extern "C" { #endif @@ -171,7 +175,7 @@ void boardInit() // and this section is un-initialized memset(&g_FATFS_Obj, 0, sizeof(g_FATFS_Obj)); monitorInit(); - adcInit(); + adcInit(&stm32_hal_adc_driver); backlightInit(); lcdInit(); usbInit(); diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index d278506e7..c272bd0d7 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -305,6 +305,7 @@ enum Analogs { SUB_ANALOG_POS = SWH, SWITCH_END = SWH, TX_VOLTAGE, + TX_VBAT, NUM_ANALOGS }; @@ -317,8 +318,6 @@ enum CalibratedAnalogs { CALIBRATED_STICK4, CALIBRATED_POT1, CALIBRATED_POT2, - CALIBRATED_SLIDER_REAR_LEFT, - CALIBRATED_SLIDER_REAR_RIGHT, CALIBRATED_SWA, CALIBRATED_SWB, CALIBRATED_SWC, @@ -335,10 +334,6 @@ enum CalibratedAnalogs { extern uint16_t adcValues[NUM_ANALOGS]; -void adcInit(); -void adcRead(); -uint16_t getAnalogValue(uint8_t index); -uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps #define BATTERY_WARN 36 // 3.6V #define BATTERY_MIN 35 // 3.5V diff --git a/radio/src/targets/nv14/hal.h b/radio/src/targets/nv14/hal.h index 767d53682..5dfbfaeca 100644 --- a/radio/src/targets/nv14/hal.h +++ b/radio/src/targets/nv14/hal.h @@ -100,16 +100,17 @@ #define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_DMA2) #define ADC_RCC_APB2Periph (RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC3) #if !defined(FLYSKY_HALL_STICKS) -#define ADC_GPIO_PIN_STICK_LH GPIO_Pin_2 // PA.02 -#define ADC_GPIO_PIN_STICK_LV GPIO_Pin_3 // PA.03 -#define ADC_GPIO_PIN_STICK_RH GPIO_Pin_4 // PA.04 -#define ADC_GPIO_PIN_STICK_RV GPIO_Pin_5 // PA.05 + #define ADC_GPIO_PIN_STICK_LH GPIO_Pin_2 // PA.02 + #define ADC_GPIO_PIN_STICK_LV GPIO_Pin_3 // PA.03 + #define ADC_GPIO_PIN_STICK_RH GPIO_Pin_4 // PA.04 + #define ADC_GPIO_PIN_STICK_RV GPIO_Pin_5 // PA.05 #else -#define ADC_GPIO_PIN_STICK_LH 0 -#define ADC_GPIO_PIN_STICK_LV 0 -#define ADC_GPIO_PIN_STICK_RH 0 -#define ADC_GPIO_PIN_STICK_RV 0 + #define ADC_GPIO_PIN_STICK_LH 0 + #define ADC_GPIO_PIN_STICK_LV 0 + #define ADC_GPIO_PIN_STICK_RH 0 + #define ADC_GPIO_PIN_STICK_RV 0 #endif + #define ADC_GPIO_PIN_POT1 GPIO_Pin_6 // PA.06 VRA #define ADC_GPIO_PIN_POT2 GPIO_Pin_4 // PC.04 VRB #define ADC_GPIO_PIN_SWA GPIO_Pin_1 // PB.01 @@ -128,11 +129,17 @@ #define ADC_GPIOF_PINS (GPIO_Pin_8 | GPIO_Pin_10) #if !defined(FLYSKY_HALL_STICKS) -#define ADC_CHANNEL_STICK_LH ADC_Channel_2 // ADC123_IN2 -> ADC1_IN2 -#define ADC_CHANNEL_STICK_LV ADC_Channel_3 // ADC123_IN3 -> ADC1_IN3 -#define ADC_CHANNEL_STICK_RH ADC_Channel_4 // ADC12_IN4 -> ADC1_IN4 -#define ADC_CHANNEL_STICK_RV ADC_Channel_5 // ADC12_IN5 -> ADC1_IN5 + #define ADC_CHANNEL_STICK_LH ADC_Channel_2 // ADC123_IN2 -> ADC1_IN2 + #define ADC_CHANNEL_STICK_LV ADC_Channel_3 // ADC123_IN3 -> ADC1_IN3 + #define ADC_CHANNEL_STICK_RH ADC_Channel_4 // ADC12_IN4 -> ADC1_IN4 + #define ADC_CHANNEL_STICK_RV ADC_Channel_5 // ADC12_IN5 -> ADC1_IN5 +#else + #define ADC_CHANNEL_STICK_LH 0 + #define ADC_CHANNEL_STICK_LV 0 + #define ADC_CHANNEL_STICK_RH 0 + #define ADC_CHANNEL_STICK_RV 0 #endif + #define ADC_CHANNEL_POT1 ADC_Channel_6 // ADC12_IN6 -> ADC1_IN6 #define ADC_CHANNEL_POT2 ADC_Channel_14 // ADC12_IN14 -> ADC1_IN14 #define ADC_CHANNEL_SWA ADC_Channel_9 // ADC12_IN9 -> ADC1_IN9 @@ -146,27 +153,16 @@ #define ADC_CHANNEL_BATT ADC_Channel_15 // ADC12_IN15 -> ADC1_IN15 #define ADC_MAIN ADC1 -#define ADC_SUB ADC3 +#define ADC_EXT ADC3 #define ADC_SAMPTIME 2 #define ADC_DMA DMA2 -#define ADC_DMA_SxCR_CHSEL 0 //DMA_SxCR_CHSEL_1 +#define ADC_DMA_Channel DMA_Channel_0 #define ADC_DMA_Stream DMA2_Stream4 -#define ADC_SET_DMA_FLAGS() ADC_DMA->HIFCR = (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4) -#define ADC_TRANSFER_COMPLETE() (ADC_DMA->HISR & DMA_HISR_TCIF4) +#define ADC_DMA_TC_Flag DMA_FLAG_TCIF4 -// NV14 customized drivers uses this -#define ADC_MAIN_DMA_SxCR_CHSEL 0 // DMA_SxCR_CHSEL_1 -#define ADC_MAIN_DMA_Stream DMA2_Stream4 -#define ADC_MAIN_SET_DMA_FLAGS() ADC_DMA->HIFCR = (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4) -#define ADC_MAIN_TRANSFER_COMPLETE() (ADC_DMA->HISR & DMA_HISR_TCIF4) - -#define ADC_SUB_DMA_SxCR_CHSEL DMA_Channel_2 -#define ADC_SUB_DMA_Stream DMA2_Stream0 -#define ADC_SUB_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) -#define ADC_SUB_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) - -#define ADC_MAIN_SMPR1 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24); -#define ADC_MAIN_SMPR2 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24) + (ADC_SAMPTIME << 27); +#define ADC_EXT_DMA_Channel DMA_Channel_2 +#define ADC_EXT_DMA_Stream DMA2_Stream0 +#define ADC_EXT_DMA_TC_Flag DMA_FLAG_TCIF0 // Power #define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOI diff --git a/radio/src/targets/nv14/keys_driver.cpp b/radio/src/targets/nv14/keys_driver.cpp index 293728b03..853c8f3a7 100644 --- a/radio/src/targets/nv14/keys_driver.cpp +++ b/radio/src/targets/nv14/keys_driver.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "hal/adc_driver.h" uint32_t readKeys() { diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index e671993ed..64e6a45db 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -470,7 +470,8 @@ set(TARGET_SRC set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} - ../common/arm/stm32/adc_driver.cpp + ../common/arm/stm32/stm32_hal_adc.cpp + ../../hal/adc_driver.cpp ../common/arm/stm32/heartbeat_driver.cpp ../common/arm/stm32/mixer_scheduler_driver.cpp ) diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 03b6c4c84..db8d4cebb 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -20,6 +20,9 @@ #include "opentx.h" +#include "hal/adc_driver.h" +#include "stm32_hal_adc.h" + #if defined(__cplusplus) extern "C" { #endif @@ -159,7 +162,8 @@ void boardInit() } #endif - adcInit(); + if (!adcInit(&stm32_hal_adc_driver)) + TRACE("adcInit failed"); lcdInit(); // delaysInit() must be called before audioInit(); init2MhzTimer(); diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index c01c83046..8307197fd 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -553,6 +553,8 @@ enum Analogs { NUM_ANALOGS }; +#define HAS_TX_RTC_VOLTAGE + #if defined(PCBX9LITE) #define NUM_POTS 1 #define NUM_SLIDERS 0 diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index e25ed35c5..93873f5dd 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -875,18 +875,11 @@ // ADC #define ADC_MAIN ADC1 #define ADC_DMA DMA2 -#define ADC_DMA_SxCR_CHSEL 0 +#define ADC_DMA_Channel DMA_Channel_0 #define ADC_DMA_Stream DMA2_Stream4 -#define ADC_SET_DMA_FLAGS() ADC_DMA->HIFCR = (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4) -#define ADC_TRANSFER_COMPLETE() (ADC_DMA->HISR & DMA_HISR_TCIF4) +#define ADC_DMA_TC_Flag DMA_FLAG_TCIF4 #define ADC_SAMPTIME 2 // sample time = 28 cycles -#if defined(RADIO_TLITE) - #define ADC_MAIN_SMPR1 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + ((ADC_SAMPTIME + 1) << 24); // TLite needs +1 for proper RTC Bat measurement. - #define ADC_MAIN_SMPR2 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24) + (ADC_SAMPTIME << 27); -#else - #define ADC_MAIN_SMPR1 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24); - #define ADC_MAIN_SMPR2 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24) + (ADC_SAMPTIME << 27); -#endif + #if defined(PCBX9E) #define HARDWARE_POT1 #define HARDWARE_POT2 @@ -928,8 +921,8 @@ #define ADC_EXT ADC3 #define ADC_EXT_DMA DMA2 #define ADC_EXT_DMA_Stream DMA2_Stream0 - #define ADC_EXT_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) - #define ADC_EXT_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) + #define ADC_EXT_DMA_Channel DMA_Channel_2 + #define ADC_EXT_TC_Flag DMA_FLAG_TCIF0 #define ADC_EXT_SAMPTIME 3 // sample time = 56 cycles #define ADC_VREF_PREC2 300 #elif defined(PCBX9DP)