From cf480b03a398a1d0b3d62d828c6472427be24cf7 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 23 Jul 2021 21:50:18 +0200 Subject: [PATCH 01/13] [adc] Use StdPeriph lib instead of direct reg access --- radio/src/hal/adc_driver.h | 37 ++ .../targets/common/arm/stm32/adc_driver.cpp | 321 +++++++++++++----- .../common/arm/stm32/f2/CMakeLists.txt | 1 + .../common/arm/stm32/f4/CMakeLists.txt | 1 + radio/src/targets/horus/hal.h | 1 + 5 files changed, 271 insertions(+), 90 deletions(-) create mode 100644 radio/src/hal/adc_driver.h diff --git a/radio/src/hal/adc_driver.h b/radio/src/hal/adc_driver.h new file mode 100644 index 000000000..718351ded --- /dev/null +++ b/radio/src/hal/adc_driver.h @@ -0,0 +1,37 @@ +/* + * 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 etx_hal_adc_channel { + const uint8_t adc_channel; + const uint8_t rank; + const uint8_t sample_time; +}; + +typedef const etx_hal_adc_channel* (*etx_hal_adc_get_channels)(); +typedef uint8_t (*etx_hal_adc_get_nconv)(); + +struct etx_hal_adc { + ADC_TypeDef* adc; + const etx_hal_adc_get_nconv get_nconv; + const etx_hal_adc_get_channels get_channels; +}; diff --git a/radio/src/targets/common/arm/stm32/adc_driver.cpp b/radio/src/targets/common/arm/stm32/adc_driver.cpp index 6a1214207..b17ce3a9a 100644 --- a/radio/src/targets/common/arm/stm32/adc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/adc_driver.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "hal/adc_driver.h" #if defined(SIMU) // not needed @@ -72,7 +73,7 @@ uint16_t adcValues[NUM_ANALOGS] __DMA; uint16_t rtcBatteryVoltage; #endif -void adcInit() +static void adc_init_pins() { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; @@ -98,82 +99,184 @@ void adcInit() #if defined(ADC_GPIOF_PINS) GPIO_InitStructure.GPIO_Pin = ADC_GPIOF_PINS; GPIO_Init(GPIOF, &GPIO_InitStructure); -#endif +#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 +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; + ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; + ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; + ADC_InitStructure.ADC_NbrOfConversion = nconv; + + 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 +} + +etx_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) - 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); + { 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}, + {ADC_CHANNEL_BATT, ADC_SAMPTIME}, + {ADC_Channel_Vbat, ADC_SAMPTIME} #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); + {ADC_CHANNEL_POT1, ADC_SAMPTIME}, + {ADC_CHANNEL_BATT, ADC_SAMPTIME}, + {ADC_Channel_Vbat, 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_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); + {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}, #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); + {ADC_CHANNEL_BATT, ADC_SAMPTIME}, + {ADC_Channel_Vbat, ADC_SAMPTIME} #endif +}; +static const etx_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; +} + +static uint8_t ADC_MAIN_get_nconv() +{ + return NUM_ANALOGS_ADC; // based on STICKS_PWM_ENABLED() +} + +#if defined(ADC_EXT) #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; +static const etx_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 etx_hal_adc_channel ADC_EXT_channels[] = { + { ADC_Channel_Vbat, 1, ADC_SAMPTIME } +}; + +static uint8_t ADC_EXT_get_nconv() { return 1; } + +#endif +#endif + +etx_hal_adc ADC_hal_def[] = { + { ADC_MAIN, ADC_MAIN_get_nconv, ADC_MAIN_get_channels }, +#if defined(ADC_EXT) + { ADC_EXT, ADC_EXT_get_nconv, ADC_EXT_get_channels }, +#endif + { nullptr, nullptr, nullptr }, +}; + + +static void adc_init_channels(const etx_hal_adc* adc_def) +{ + while (adc_def->adc) { + uint8_t nconv = 0; + if (adc_def->get_nconv) nconv = adc_def->get_nconv(); + + const etx_hal_adc_channel* chan = nullptr; + if ((nconv > 0) && adc_def->get_channels) + chan = adc_def->get_channels(); + + if (chan) { + uint8_t rank = 1; + while (nconv > 0) { + ADC_RegularChannelConfig(adc_def->adc, chan->adc_channel, rank, + chan->sample_time); + nconv--; rank++; + chan++; + } + } + adc_def++; + } +} + +static void adc_init_dma_channel(ADC_TypeDef* ADCx, DMA_Stream_TypeDef * dma_stream, + uint16_t* dest, uint8_t nconv) +{ + // setup DMA request + dma_stream->CR = DMA_SxCR_PL | ADC_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; + dma_stream->PAR = CONVERT_PTR_UINT(&ADCx->DR); + dma_stream->M0AR = CONVERT_PTR_UINT(dest); + dma_stream->NDTR = nconv; + dma_stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; +} + + +void adcInit() +{ + 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); + + + adc_setup_scan_mode(ADC_MAIN, NUM_ANALOGS_ADC); +#if defined(PCBX10) // X10 uses ADC3 for "normal" things + adc_setup_scan_mode(ADC_EXT, 1); +#endif +#if defined(PCBX9E) + adc_setup_scan_mode(ADC_EXT, NUM_ANALOGS_ADC_EXT); +#endif + + // configure each channel + adc_init_channels(ADC_hal_def); + + // Enable vbat sensor + ADC_VBATCmd(ENABLE); + + adc_init_dma_channel(ADC_MAIN, ADC_DMA_Stream, &adcValues[FIRST_ANALOG_ADC], NUM_ANALOGS_ADC); +#if defined(PCBX9E) + adc_init_dma_channel(ADC_EXT, ADC_EXT_DMA_Stream, adcValues + NUM_ANALOGS_ADC, NUM_ANALOGS_ADC_EXT); #endif #if NUM_PWMSTICKS > 0 @@ -183,49 +286,87 @@ void adcInit() #endif } +#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 void adc_start_dma_conversion(ADC_TypeDef* ADCx, + DMA_Stream_TypeDef * dma_stream) +{ + dma_stream->CR &= ~DMA_SxCR_EN; // Disable DMA + ADCx->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); + adc_dma_clear_flags(dma_stream); + + dma_stream->CR |= DMA_SxCR_EN; // Enable DMA + ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; +} + +static void adc_disable_dma(DMA_Stream_TypeDef * dma_stream) +{ + dma_stream->CR &= ~DMA_SxCR_EN; // Disable DMA stream +} + +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; +} + 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; + adc_start_dma_conversion(ADC_MAIN, ADC_DMA_Stream); -#if defined(PCBX10) - ADC1->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); - ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART; +#if defined(ADC_EXT) +#if defined(ADC_EXT_DMA_Stream) + adc_start_dma_conversion(ADC_EXT, ADC_EXT_DMA_Stream); +#else + // start a single conversion on ADC1 (VBat only) + adc_start_single_conversion(ADC_EXT); +#endif #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) + //TODO: replace with IRQ trigger (both) +#if defined(ADC_EXT) && defined(ADC_EXT_DMA_Stream) + // Wait for all ADCs to complete 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 + 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 (ADC_TRANSFER_COMPLETE()) { break; } } - ADC_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA -#endif + adc_disable_dma(ADC_DMA_Stream); -#if defined(PCBX10) +#if defined(ADC_EXT) if (isVBatBridgeEnabled()) { - rtcBatteryVoltage = ADC1->DR; + rtcBatteryVoltage = ADC_EXT->DR; } #endif +#endif } void adcRead() 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/horus/hal.h b/radio/src/targets/horus/hal.h index 5e009f041..560977a39 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -318,6 +318,7 @@ #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 From 0e4201f25dd8fc3162f21d27220410039e329a9b Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 24 Jul 2021 10:04:54 +0200 Subject: [PATCH 02/13] WiP --- radio/src/gui/128x64/radio_calibration.cpp | 1 + radio/src/gui/colorlcd/radio_calibration.cpp | 1 + radio/src/gui/colorlcd/radio_hardware.cpp | 1 + .../src/gui/common/stdlcd/radio_hardware.cpp | 1 + radio/src/hal/adc_driver.cpp | 145 +++++++++ radio/src/hal/adc_driver.h | 38 ++- radio/src/main.cpp | 1 + radio/src/opentx.cpp | 3 +- .../targets/common/arm/stm32/board_common.h | 7 +- .../{adc_driver.cpp => stm32_hal_adc.cpp} | 285 +++++++----------- .../targets/common/arm/stm32/stm32_hal_adc.h | 45 +++ radio/src/targets/horus/CMakeLists.txt | 3 +- radio/src/targets/horus/board.cpp | 5 +- radio/src/targets/taranis/CMakeLists.txt | 3 +- radio/src/targets/taranis/board.cpp | 5 +- 15 files changed, 350 insertions(+), 194 deletions(-) create mode 100644 radio/src/hal/adc_driver.cpp rename radio/src/targets/common/arm/stm32/{adc_driver.cpp => stm32_hal_adc.cpp} (57%) create mode 100644 radio/src/targets/common/arm/stm32/stm32_hal_adc.h 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/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/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..4b36440a3 --- /dev/null +++ b/radio/src/hal/adc_driver.cpp @@ -0,0 +1,145 @@ +/* + * 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) +#if defined(HORUS_STICKS) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,-1,-1,1, -1,1,1, -1,-1,-1}; +#else + const int8_t adcDirection[NUM_ANALOGS] = {1,1,-1,-1, -1,-1,-1,1, -1,1,1, -1,-1,-1}; +#endif + 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}; +#endif + +uint16_t adcValues[NUM_ANALOGS] __DMA; + +#if defined(PCBX10) +uint16_t rtcBatteryVoltage; +#endif + +void adcInit(const etx_hal_adc_driver_t* driver) +{ + etx_hal_adc_driver = driver; + if (etx_hal_adc_driver && etx_hal_adc_driver->init) + etx_hal_adc_driver->init(); +} + +static void adcSingleRead() +{ + if (!etx_hal_adc_driver) return; + + if (etx_hal_adc_driver->start_conversion) + etx_hal_adc_driver->start_conversion(); + + if (etx_hal_adc_driver->wait_completion) + etx_hal_adc_driver->wait_completion(); +} + +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/hal/adc_driver.h b/radio/src/hal/adc_driver.h index 718351ded..50d1bd168 100644 --- a/radio/src/hal/adc_driver.h +++ b/radio/src/hal/adc_driver.h @@ -21,17 +21,33 @@ #pragma once -struct etx_hal_adc_channel { - const uint8_t adc_channel; - const uint8_t rank; - const uint8_t sample_time; +#include + +#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) +#else + #define FIRST_ANALOG_ADC 0 + #define NUM_ANALOGS_ADC NUM_ANALOGS +#endif + +#if defined(PCBX10) +extern uint16_t rtcBatteryVoltage; +#endif + +struct etx_hal_adc_driver_t { + void (*init)(); + void (*start_conversion)(); + void (*wait_completion)(); }; -typedef const etx_hal_adc_channel* (*etx_hal_adc_get_channels)(); -typedef uint8_t (*etx_hal_adc_get_nconv)(); +void adcInit(const etx_hal_adc_driver_t* driver); +//void adcDeInit(); -struct etx_hal_adc { - ADC_TypeDef* adc; - const etx_hal_adc_get_nconv get_nconv; - const etx_hal_adc_get_channels get_channels; -}; +void 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..0c0975aff 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" 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/adc_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp similarity index 57% rename from radio/src/targets/common/arm/stm32/adc_driver.cpp rename to radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp index b17ce3a9a..28190dd66 100644 --- a/radio/src/targets/common/arm/stm32/adc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp @@ -20,58 +20,7 @@ #include "opentx.h" #include "hal/adc_driver.h" - -#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) -#if defined(HORUS_STICKS) - const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,-1,-1,1, -1,1,1, -1,-1,-1}; -#else - const int8_t adcDirection[NUM_ANALOGS] = {1,1,-1,-1, -1,-1,-1,1, -1,1,1, -1,-1,-1}; -#endif - 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}; -#endif - -#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) -#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 +#include "stm32_hal_adc.h" static void adc_init_pins() { @@ -122,7 +71,7 @@ static void adc_setup_scan_mode(ADC_TypeDef* ADCx, uint8_t nconv) ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE); // ADC_CR2_DDS } -etx_hal_adc_channel ADC_MAIN_channels[] = { +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}, @@ -168,7 +117,7 @@ etx_hal_adc_channel ADC_MAIN_channels[] = { #endif }; -static const etx_hal_adc_channel* ADC_MAIN_get_channels() +static const stm32_hal_adc_channel* ADC_MAIN_get_channels() { #if NUM_PWMSTICKS > 0 if (STICKS_PWM_ENABLED()) @@ -185,7 +134,7 @@ static uint8_t ADC_MAIN_get_nconv() #if defined(ADC_EXT) #if defined(PCBX9E) -static const etx_hal_adc_channel ADC_EXT_channels[] = { +static const stm32_hal_adc_channel ADC_EXT_channels[] = { {ADC_CHANNEL_POT1, ADC_SAMPTIME}, {ADC_CHANNEL_SLIDER1, ADC_SAMPTIME}, {ADC_CHANNEL_SLIDER2, ADC_SAMPTIME} @@ -195,60 +144,82 @@ static uint8_t ADC_EXT_get_nconv() { return NUM_ANALOGS_ADC_EXT; } #elif defined(PCBX10) -static const etx_hal_adc_channel ADC_EXT_channels[] = { +static const stm32_hal_adc_channel ADC_EXT_channels[] = { { ADC_Channel_Vbat, 1, ADC_SAMPTIME } }; static uint8_t ADC_EXT_get_nconv() { return 1; } #endif + +static const stm32_hal_adc_channel* ADC_EXT_get_channels() +{ + return ADC_EXT_channels; +} + #endif -etx_hal_adc ADC_hal_def[] = { - { ADC_MAIN, ADC_MAIN_get_nconv, ADC_MAIN_get_channels }, -#if defined(ADC_EXT) - { ADC_EXT, ADC_EXT_get_nconv, ADC_EXT_get_channels }, +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; +} #endif - { nullptr, nullptr, nullptr }, + +stm32_hal_adc ADC_hal_def[] = { + { + ADC_MAIN, + ADC_DMA_Stream, ADC_MAIN_get_dma_buffer, + ADC_MAIN_get_nconv, ADC_MAIN_get_channels + }, +#if defined(ADC_EXT) +#if defined(ADC_EXT_DMA_Stream) + { + ADC_EXT, + ADC_EXT_DMA_Stream, ADC_EXT_get_dma_buffer, + ADC_EXT_get_nconv, ADC_EXT_get_channels + }, +#else + { + ADC_EXT, + nullptr, nullptr, + ADC_EXT_get_nconv, ADC_EXT_get_channels + }, +#endif +#endif + { nullptr, nullptr, nullptr, nullptr, nullptr }, }; - -static void adc_init_channels(const etx_hal_adc* adc_def) +static void adc_init_channels(ADC_TypeDef* adc, const stm32_hal_adc_channel* chan, + uint8_t nconv) { - while (adc_def->adc) { - uint8_t nconv = 0; - if (adc_def->get_nconv) nconv = adc_def->get_nconv(); + if (!chan || !nconv) return; - const etx_hal_adc_channel* chan = nullptr; - if ((nconv > 0) && adc_def->get_channels) - chan = adc_def->get_channels(); - - if (chan) { - uint8_t rank = 1; - while (nconv > 0) { - ADC_RegularChannelConfig(adc_def->adc, chan->adc_channel, rank, - chan->sample_time); - nconv--; rank++; - chan++; - } - } - adc_def++; + uint8_t rank = 1; + while (nconv > 0) { + ADC_RegularChannelConfig(adc, chan->adc_channel, rank, chan->sample_time); + nconv--; rank++; chan++; } } -static void adc_init_dma_channel(ADC_TypeDef* ADCx, DMA_Stream_TypeDef * dma_stream, - uint16_t* dest, uint8_t nconv) +static void adc_init_dma_stream(ADC_TypeDef* adc, DMA_Stream_TypeDef * dma_stream, + uint16_t* dest, uint8_t nconv) { // setup DMA request - dma_stream->CR = DMA_SxCR_PL | ADC_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; - dma_stream->PAR = CONVERT_PTR_UINT(&ADCx->DR); + dma_stream->CR = DMA_SxCR_PL | ADC_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | + DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; + dma_stream->PAR = CONVERT_PTR_UINT(&adc->DR); dma_stream->M0AR = CONVERT_PTR_UINT(dest); dma_stream->NDTR = nconv; dma_stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; } - -void adcInit() +static void stm32_hal_adc_init() { adc_init_pins(); @@ -259,26 +230,35 @@ void adcInit() ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInit(&ADC_CommonInitStruct); - - adc_setup_scan_mode(ADC_MAIN, NUM_ANALOGS_ADC); -#if defined(PCBX10) // X10 uses ADC3 for "normal" things - adc_setup_scan_mode(ADC_EXT, 1); -#endif -#if defined(PCBX9E) - adc_setup_scan_mode(ADC_EXT, NUM_ANALOGS_ADC_EXT); -#endif + 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 - adc_init_channels(ADC_hal_def); + // 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(); + adc_init_dma_stream(adc_def->adc, adc_def->dma_stream, dma_buffer, nconv); + } + } + } + // move to next ADC definition + adc_def++; + } + + //TODO: move VBat & PWM sticks somewhere else. // Enable vbat sensor ADC_VBATCmd(ENABLE); - adc_init_dma_channel(ADC_MAIN, ADC_DMA_Stream, &adcValues[FIRST_ANALOG_ADC], NUM_ANALOGS_ADC); -#if defined(PCBX9E) - adc_init_dma_channel(ADC_EXT, ADC_EXT_DMA_Stream, adcValues + NUM_ANALOGS_ADC, NUM_ANALOGS_ADC_EXT); -#endif - #if NUM_PWMSTICKS > 0 if (STICKS_PWM_ENABLED()) { sticksPwmInit(); @@ -329,20 +309,32 @@ static void adc_start_single_conversion(ADC_TypeDef* ADCx) ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; } -void adcSingleRead() +static void stm32_hal_adc_start_read() { - adc_start_dma_conversion(ADC_MAIN, ADC_DMA_Stream); + 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) { + adc_start_dma_conversion(adc_def->adc, adc_def->dma_stream); + } else if (nconv == 1){ + adc_start_single_conversion(adc_def->adc); + } + } + } + // move to next ADC definition + adc_def++; + } +} -#if defined(ADC_EXT) -#if defined(ADC_EXT_DMA_Stream) - adc_start_dma_conversion(ADC_EXT, ADC_EXT_DMA_Stream); -#else - // start a single conversion on ADC1 (VBat only) - adc_start_single_conversion(ADC_EXT); -#endif -#endif - - //TODO: replace with IRQ trigger (both) +static void stm32_hal_adc_wait_completion() +{ + //TODO: + // - 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++) { @@ -350,6 +342,7 @@ void adcSingleRead() break; } } + //TODO: move into completion IRQ trigger adc_disable_dma(ADC_DMA_Stream); adc_disable_dma(ADC_EXT_DMA_Stream); #else @@ -359,9 +352,10 @@ void adcSingleRead() break; } } + //TODO: move into completion IRQ trigger adc_disable_dma(ADC_DMA_Stream); -#if defined(ADC_EXT) +#if defined(ADC_EXT) && !defined(ADC_EXT_DMA_Stream) if (isVBatBridgeEnabled()) { rtcBatteryVoltage = ADC_EXT->DR; } @@ -369,61 +363,8 @@ void adcSingleRead() #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) +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..3df85ae66 --- /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 rank; + 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; + 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..1ff3ea877 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) diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index f24f8f1bf..b192cdda8 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -20,6 +20,9 @@ #include "opentx.h" +#include "hal/adc_driver.h" +#include "../common/arm/stm32/stm32_hal_adc.h" + #if defined(__cplusplus) extern "C" { #endif @@ -197,7 +200,7 @@ void boardInit() } #endif - adcInit(); + adcInit(&stm32_hal_adc_driver); lcdInit(); backlightInit(); 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..c85907b2e 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,7 @@ void boardInit() } #endif - adcInit(); + adcInit(&stm32_hal_adc_driver); lcdInit(); // delaysInit() must be called before audioInit(); init2MhzTimer(); From e70b77962d06dd358b41379acfd5658f4aa2d9ba Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 24 Jul 2021 10:29:56 +0200 Subject: [PATCH 03/13] Add missing include for 212x64 UI --- radio/src/gui/212x64/radio_calibration.cpp | 1 + 1 file changed, 1 insertion(+) 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 */ From b1be0bf57df02b48da31adea3669526adb0784f7 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 24 Jul 2021 10:36:07 +0200 Subject: [PATCH 04/13] Fix X7 / XLITE(S) / X9LITE(S) targets --- radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp index 28190dd66..1bcd47598 100644 --- a/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp @@ -93,12 +93,8 @@ stm32_hal_adc_channel ADC_MAIN_channels[] = { #elif defined(PCBX7) || defined(PCBXLITE) {ADC_CHANNEL_POT1, ADC_SAMPTIME}, {ADC_CHANNEL_POT2, ADC_SAMPTIME}, - {ADC_CHANNEL_BATT, ADC_SAMPTIME}, - {ADC_Channel_Vbat, ADC_SAMPTIME} #elif defined(PCBX9LITE) {ADC_CHANNEL_POT1, ADC_SAMPTIME}, - {ADC_CHANNEL_BATT, ADC_SAMPTIME}, - {ADC_Channel_Vbat, ADC_SAMPTIME}, #elif defined(PCBX9E) {ADC_CHANNEL_POT2, ADC_SAMPTIME}, {ADC_CHANNEL_POT3, ADC_SAMPTIME}, From ec630671adcfdabf0a346e4e9d2e7af7ee848d9b Mon Sep 17 00:00:00 2001 From: rotorman Date: Fri, 30 Jul 2021 20:40:41 +0200 Subject: [PATCH 05/13] Small bugfix and added some comments. --- radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp | 12 ++++++------ radio/src/targets/common/arm/stm32/stm32_hal_adc.h | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp index 1bcd47598..fa3e12af0 100644 --- a/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp @@ -56,11 +56,11 @@ 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; - ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; - ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; + 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; + ADC_InitStructure.ADC_NbrOfConversion = nconv; // Channel count ADC_Init(ADCx, &ADC_InitStructure); @@ -141,7 +141,7 @@ 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, 1, ADC_SAMPTIME } + { ADC_Channel_Vbat, ADC_SAMPTIME } }; static uint8_t ADC_EXT_get_nconv() { return 1; } @@ -188,7 +188,7 @@ stm32_hal_adc ADC_hal_def[] = { }, #endif #endif - { nullptr, nullptr, nullptr, nullptr, nullptr }, + { nullptr, nullptr, nullptr, nullptr, nullptr }, // required to detect end of ADC definitions }; static void adc_init_channels(ADC_TypeDef* adc, const stm32_hal_adc_channel* chan, diff --git a/radio/src/targets/common/arm/stm32/stm32_hal_adc.h b/radio/src/targets/common/arm/stm32/stm32_hal_adc.h index 3df85ae66..f0d4572cb 100644 --- a/radio/src/targets/common/arm/stm32/stm32_hal_adc.h +++ b/radio/src/targets/common/arm/stm32/stm32_hal_adc.h @@ -23,7 +23,6 @@ struct stm32_hal_adc_channel { const uint8_t adc_channel; - const uint8_t rank; const uint8_t sample_time; }; From 897d2f30256a3de1b49b52cfc4453e4ad70838ac Mon Sep 17 00:00:00 2001 From: rotorman Date: Fri, 30 Jul 2021 22:11:43 +0200 Subject: [PATCH 06/13] Adheres to the STM32F429 reference manual (RM0090) Section 10.3.17 DMA stream configuration procedure. Before write access is permitted to numerous DMA registers, need to make sure that DMA is disabled for the stream. Disabling the stream is not instantaneous, and needs to be waited for (previous transmissions need to be finished first). Added return values to numerous functions to signal a failure. --- radio/src/hal/adc_driver.cpp | 34 +++++++++--- radio/src/hal/adc_driver.h | 8 +-- radio/src/opentx.cpp | 3 +- .../common/arm/stm32/stm32_hal_adc.cpp | 55 ++++++++++++++----- radio/src/targets/horus/board.cpp | 4 +- radio/src/targets/taranis/board.cpp | 3 +- 6 files changed, 80 insertions(+), 27 deletions(-) diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp index 4b36440a3..fdeb1595b 100644 --- a/radio/src/hal/adc_driver.cpp +++ b/radio/src/hal/adc_driver.cpp @@ -67,30 +67,49 @@ uint16_t adcValues[NUM_ANALOGS] __DMA; uint16_t rtcBatteryVoltage; #endif -void adcInit(const etx_hal_adc_driver_t* driver) +bool adcInit(const etx_hal_adc_driver_t* driver) { etx_hal_adc_driver = driver; if (etx_hal_adc_driver && etx_hal_adc_driver->init) - etx_hal_adc_driver->init(); + { + if(!etx_hal_adc_driver->init()) + return false; + + return true; + } + return false; } -static void adcSingleRead() +static bool adcSingleRead() { - if (!etx_hal_adc_driver) return; + if (!etx_hal_adc_driver) + return false; if (etx_hal_adc_driver->start_conversion) - etx_hal_adc_driver->start_conversion(); + { + if (!etx_hal_adc_driver->start_conversion()) + return false; + } + else + return false; if (etx_hal_adc_driver->wait_completion) + { etx_hal_adc_driver->wait_completion(); + } + else + return false; + + return true; } -void adcRead() +bool adcRead() { uint16_t temp[NUM_ANALOGS] = { 0 }; for (int i=0; i<4; i++) { - adcSingleRead(); + if (!adcSingleRead()) + return false; for (uint8_t x=FIRST_ANALOG_ADC; xCR = DMA_SxCR_PL | ADC_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | - DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC; 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 | ADC_DMA_SxCR_CHSEL | 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 void stm32_hal_adc_init() +static bool stm32_hal_adc_init() { adc_init_pins(); @@ -242,7 +255,8 @@ static void stm32_hal_adc_init() if (adc_def->dma_stream && adc_def->get_dma_buffer) { uint16_t* dma_buffer = adc_def->get_dma_buffer(); - adc_init_dma_stream(adc_def->adc, adc_def->dma_stream, dma_buffer, nconv); + if (!adc_init_dma_stream(adc_def->adc, adc_def->dma_stream, dma_buffer, nconv)) + return false; } } } @@ -260,6 +274,7 @@ static void stm32_hal_adc_init() sticksPwmInit(); } #endif + return true; } #define DMA_Stream0_IT_MASK (uint32_t)(DMA_LISR_FEIF0 | DMA_LISR_DMEIF0 | \ @@ -283,20 +298,32 @@ static void adc_dma_clear_flags(DMA_Stream_TypeDef * dma_stream) } } -static void adc_start_dma_conversion(ADC_TypeDef* ADCx, +static bool adc_start_dma_conversion(ADC_TypeDef* ADCx, DMA_Stream_TypeDef * dma_stream) { - dma_stream->CR &= ~DMA_SxCR_EN; // Disable DMA - ADCx->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); + // 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); + ADCx->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); + dma_stream->CR |= DMA_SxCR_EN; // Enable DMA ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; + return true; } -static void adc_disable_dma(DMA_Stream_TypeDef * dma_stream) +static bool adc_disable_dma(DMA_Stream_TypeDef * dma_stream) { - dma_stream->CR &= ~DMA_SxCR_EN; // Disable DMA stream + dma_stream->CR &= ~(uint32_t)DMA_SxCR_EN; + uint16_t uiTimeout = 1000; + do + { + if (--uiTimeout == 0) return false; // Timeout. Failed to disable DMA + } while (dma_stream->CR & (uint32_t)DMA_SxCR_EN); // wait until DMA enable bit gets cleared by hardware + return true; } static void adc_start_single_conversion(ADC_TypeDef* ADCx) @@ -305,7 +332,7 @@ static void adc_start_single_conversion(ADC_TypeDef* ADCx) ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; } -static void stm32_hal_adc_start_read() +static bool stm32_hal_adc_start_read() { const stm32_hal_adc* adc_def = ADC_hal_def; while (adc_def->adc) { @@ -314,8 +341,9 @@ static void stm32_hal_adc_start_read() nconv = adc_def->get_nconv(); if (nconv > 0) { if (adc_def->dma_stream && adc_def->get_dma_buffer) { - adc_start_dma_conversion(adc_def->adc, adc_def->dma_stream); - } else if (nconv == 1){ + 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); } } @@ -323,6 +351,7 @@ static void stm32_hal_adc_start_read() // move to next ADC definition adc_def++; } + return true; } static void stm32_hal_adc_wait_completion() diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index b192cdda8..f3d10e507 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -200,7 +200,9 @@ void boardInit() } #endif - adcInit(&stm32_hal_adc_driver); + if (!adcInit(&stm32_hal_adc_driver)) + TRACE("adcInit failed"); + lcdInit(); backlightInit(); diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index c85907b2e..db8d4cebb 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -162,7 +162,8 @@ void boardInit() } #endif - adcInit(&stm32_hal_adc_driver); + if (!adcInit(&stm32_hal_adc_driver)) + TRACE("adcInit failed"); lcdInit(); // delaysInit() must be called before audioInit(); init2MhzTimer(); From f1fd6dde0254fb31a0937a256fd6234df7e532f1 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 31 Jul 2021 12:26:05 +0200 Subject: [PATCH 07/13] Integrate NV14 ADC driver into generic stm32_hal_driver --- .../src/gui/colorlcd/view_main_decoration.cpp | 19 +- radio/src/hal/adc_driver.cpp | 60 ++-- radio/src/hal/adc_driver.h | 6 + .../common/arm/stm32/stm32_hal_adc.cpp | 78 +++-- .../targets/common/arm/stm32/stm32_hal_adc.h | 1 + radio/src/targets/horus/hal.h | 8 +- radio/src/targets/nv14/CMakeLists.txt | 9 +- radio/src/targets/nv14/adc_driver.cpp | 325 ------------------ radio/src/targets/nv14/board.cpp | 6 +- radio/src/targets/nv14/board.h | 7 +- radio/src/targets/nv14/hal.h | 52 ++- radio/src/targets/nv14/keys_driver.cpp | 1 + 12 files changed, 147 insertions(+), 425 deletions(-) delete mode 100644 radio/src/targets/nv14/adc_driver.cpp 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/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp index fdeb1595b..ace78d64c 100644 --- a/radio/src/hal/adc_driver.cpp +++ b/radio/src/hal/adc_driver.cpp @@ -38,11 +38,15 @@ const etx_hal_adc_driver_t* etx_hal_adc_driver = nullptr; #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) - const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,-1,-1,1, -1,1,1, -1,-1,-1}; + 1,-1,1,-1, #else - const int8_t adcDirection[NUM_ANALOGS] = {1,1,-1,-1, -1,-1,-1,1, -1,1,1, -1,-1,-1}; -#endif + 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*/, @@ -59,6 +63,21 @@ const etx_hal_adc_driver_t* etx_hal_adc_driver = nullptr; 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*/}; + +#else + #error "ADC driver does not suppport this target" #endif uint16_t adcValues[NUM_ANALOGS] __DMA; @@ -85,21 +104,14 @@ static bool adcSingleRead() if (!etx_hal_adc_driver) return false; - if (etx_hal_adc_driver->start_conversion) - { - if (!etx_hal_adc_driver->start_conversion()) - return false; - } - else - 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(); - } - else - return false; + if (!etx_hal_adc_driver->wait_completion) + return false; + etx_hal_adc_driver->wait_completion(); return true; } @@ -133,17 +145,17 @@ bool adcRead() return true; } -#if defined(PCBX10) -uint16_t getRTCBatteryVoltage() -{ - return (rtcBatteryVoltage * 2 * ADC_VREF_PREC2) / 2048; -} -#else uint16_t getRTCBatteryVoltage() { +#if defined(TX_RTC_VOLTAGE) return (getAnalogValue(TX_RTC_VOLTAGE) * ADC_VREF_PREC2) / 2048; -} +#elif defined(PCBX10) + return (rtcBatteryVoltage * 2 * ADC_VREF_PREC2) / 2048; +#elif defined(PCBNV14) + #warning "TODO RTC voltage" + return 330; #endif +} #if !defined(SIMU) uint16_t getAnalogValue(uint8_t index) @@ -154,7 +166,7 @@ uint16_t getAnalogValue(uint8_t index) // which produces ghost readings on these inputs. return 0; } -#if defined(PCBX9E) +#if defined(PCBX9E) || defined(PCBNV14) index = adcMapping[index]; #endif if (adcDirection[index] < 0) diff --git a/radio/src/hal/adc_driver.h b/radio/src/hal/adc_driver.h index e09824f6f..c240b6e8f 100644 --- a/radio/src/hal/adc_driver.h +++ b/radio/src/hal/adc_driver.h @@ -23,6 +23,7 @@ #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) @@ -30,11 +31,16 @@ #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) extern uint16_t rtcBatteryVoltage; #endif diff --git a/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp index cc36ba56e..f7482e2ba 100644 --- a/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_hal_adc.cpp @@ -110,6 +110,15 @@ stm32_hal_adc_channel ADC_MAIN_channels[] = { {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} @@ -118,11 +127,11 @@ stm32_hal_adc_channel ADC_MAIN_channels[] = { static const stm32_hal_adc_channel* ADC_MAIN_get_channels() { -#if NUM_PWMSTICKS > 0 +#if (NUM_PWMSTICKS > 0) if (STICKS_PWM_ENABLED()) return ADC_MAIN_channels + 4; #endif - return ADC_MAIN_channels; + return ADC_MAIN_channels + FIRST_ANALOG_ADC; } static uint8_t ADC_MAIN_get_nconv() @@ -149,6 +158,15 @@ static const stm32_hal_adc_channel ADC_EXT_channels[] = { 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() @@ -166,32 +184,29 @@ static uint16_t* ADC_MAIN_get_dma_buffer() #if defined(ADC_EXT) && defined(ADC_EXT_DMA_Stream) static uint16_t* ADC_EXT_get_dma_buffer() { - return adcValues + NUM_ANALOGS_ADC; + return adcValues + NUM_ANALOGS_ADC + FIRST_ANALOG_ADC; } #endif stm32_hal_adc ADC_hal_def[] = { { ADC_MAIN, - ADC_DMA_Stream, ADC_MAIN_get_dma_buffer, + 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, - ADC_EXT_DMA_Stream, ADC_EXT_get_dma_buffer, - ADC_EXT_get_nconv, ADC_EXT_get_channels - }, + ADC_EXT_DMA_Stream, ADC_EXT_DMA_Channel, ADC_EXT_get_dma_buffer, #else - { - ADC_EXT, - nullptr, nullptr, + nullptr, 0, nullptr, +#endif ADC_EXT_get_nconv, ADC_EXT_get_channels }, #endif -#endif - { nullptr, nullptr, nullptr, nullptr, nullptr }, // required to detect end of ADC definitions + // 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, @@ -207,7 +222,7 @@ static void adc_init_channels(ADC_TypeDef* adc, const stm32_hal_adc_channel* cha } static bool adc_init_dma_stream(ADC_TypeDef* adc, DMA_Stream_TypeDef * dma_stream, - uint16_t* dest, uint8_t nconv) + 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)) @@ -221,7 +236,7 @@ static bool adc_init_dma_stream(ADC_TypeDef* adc, DMA_Stream_TypeDef * dma_strea 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 | ADC_DMA_SxCR_CHSEL | DMA_SxCR_MSIZE_0 | + 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; @@ -255,7 +270,8 @@ static bool stm32_hal_adc_init() 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, dma_buffer, nconv)) + if (!adc_init_dma_stream(adc_def->adc, adc_def->dma_stream, + adc_def->dma_channel, dma_buffer, nconv)) return false; } } @@ -308,21 +324,29 @@ static bool adc_start_dma_conversion(ADC_TypeDef* ADCx, // 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); - dma_stream->CR |= DMA_SxCR_EN; // Enable DMA + // 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) +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; - do - { - if (--uiTimeout == 0) return false; // Timeout. Failed to disable DMA - } while (dma_stream->CR & (uint32_t)DMA_SxCR_EN); // wait until DMA enable bit gets cleared by hardware + while (dma_stream->CR & (uint32_t)DMA_SxCR_EN) { + if (--uiTimeout == 0) { + // Timeout. Failed to disable DMA + return false; + } + } return true; } @@ -342,7 +366,7 @@ static bool stm32_hal_adc_start_read() 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; + return false; } else if (nconv == 1) { adc_start_single_conversion(adc_def->adc); } @@ -357,13 +381,15 @@ static bool stm32_hal_adc_start_read() 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 (ADC_TRANSFER_COMPLETE() && ADC_EXT_TRANSFER_COMPLETE()) { + if (DMA_GetFlagStatus(ADC_DMA_Stream, ADC_DMA_TC_Flag) != RESET && + DMA_GetFlagStatus(ADC_EXT_DMA_Stream, ADC_EXT_DMA_TC_Flag) != RESET) { break; } } @@ -373,7 +399,7 @@ static void stm32_hal_adc_wait_completion() #else // Wait only for the main ADC, and hope others are done as well for (unsigned int i = 0; i < 10000; i++) { - if (ADC_TRANSFER_COMPLETE()) { + if (DMA_GetFlagStatus(ADC_DMA_Stream, ADC_DMA_TC_Flag) != RESET) { break; } } diff --git a/radio/src/targets/common/arm/stm32/stm32_hal_adc.h b/radio/src/targets/common/arm/stm32/stm32_hal_adc.h index f0d4572cb..3a98f6113 100644 --- a/radio/src/targets/common/arm/stm32/stm32_hal_adc.h +++ b/radio/src/targets/common/arm/stm32/stm32_hal_adc.h @@ -34,6 +34,7 @@ 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; diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 560977a39..eebb201c3 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -321,10 +321,11 @@ #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) @@ -334,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/nv14/CMakeLists.txt b/radio/src/targets/nv14/CMakeLists.txt index ad5dda406..4f5aa592b 100644 --- a/radio/src/targets/nv14/CMakeLists.txt +++ b/radio/src/targets/nv14/CMakeLists.txt @@ -48,17 +48,12 @@ add_definitions(-DINTERNAL_MODULE_AFHDS2A) set(TARGET_SRC ${TARGET_SRC} audio_spi_driver.cpp - adc_driver.cpp -# ../common/arm/stm32/adc_driver.cpp + ../../hal/adc_driver.cpp + ../common/arm/stm32/stm32_hal_adc.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 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 63dd52b07..bf378c4bb 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 d4bc4e37c..1d628d163 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -306,6 +306,7 @@ enum Analogs { SUB_ANALOG_POS = SWH, SWITCH_END = SWH, TX_VOLTAGE, + TX_VBAT, NUM_ANALOGS }; @@ -318,8 +319,6 @@ enum CalibratedAnalogs { CALIBRATED_STICK4, CALIBRATED_POT1, CALIBRATED_POT2, - CALIBRATED_SLIDER_REAR_LEFT, - CALIBRATED_SLIDER_REAR_RIGHT, CALIBRATED_SWA, CALIBRATED_SWB, CALIBRATED_SWC, @@ -336,10 +335,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..b5520a835 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) -// 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_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_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 3e4f530b3..f70e474e9 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() { From f77d2369781aef7134ce0134a924d525b833201c Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 31 Jul 2021 15:09:40 +0200 Subject: [PATCH 08/13] fixed DMA channels / flags for taranis targets --- radio/src/hal/adc_driver.cpp | 5 ++++- radio/src/targets/taranis/board.h | 2 ++ radio/src/targets/taranis/hal.h | 17 +++++------------ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp index ace78d64c..01814b4da 100644 --- a/radio/src/hal/adc_driver.cpp +++ b/radio/src/hal/adc_driver.cpp @@ -147,13 +147,16 @@ bool adcRead() uint16_t getRTCBatteryVoltage() { -#if defined(TX_RTC_VOLTAGE) +#if defined(HAS_TX_RTC_VOLTAGE) return (getAnalogValue(TX_RTC_VOLTAGE) * ADC_VREF_PREC2) / 2048; #elif defined(PCBX10) 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 } 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) From 5ba5cb299ee3b1c21d1f8a51d7d48062eb2a761c Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 31 Jul 2021 16:16:46 +0200 Subject: [PATCH 09/13] Hotfix for X12S ADC driver --- radio/src/hal/adc_driver.cpp | 2 +- radio/src/hal/adc_driver.h | 6 +++-- radio/src/targets/horus/board.cpp | 11 +++++++-- radio/src/targets/horus/x12s_adc_driver.cpp | 15 +++++++++++- radio/src/targets/horus/x12s_adc_driver.h | 26 +++++++++++++++++++++ 5 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 radio/src/targets/horus/x12s_adc_driver.h diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp index 01814b4da..6569f19ce 100644 --- a/radio/src/hal/adc_driver.cpp +++ b/radio/src/hal/adc_driver.cpp @@ -115,7 +115,7 @@ static bool adcSingleRead() return true; } -bool adcRead() +bool adcRead() __attribute__((weak)) { uint16_t temp[NUM_ANALOGS] = { 0 }; diff --git a/radio/src/hal/adc_driver.h b/radio/src/hal/adc_driver.h index c240b6e8f..3f7f02642 100644 --- a/radio/src/hal/adc_driver.h +++ b/radio/src/hal/adc_driver.h @@ -52,8 +52,10 @@ struct etx_hal_adc_driver_t { }; bool adcInit(const etx_hal_adc_driver_t* driver); -//void adcDeInit(); +// void adcDeInit(); + +// Declare adcRead() weak so it can be re-declared +bool adcRead() __attribute__((weak)); -bool adcRead(); uint16_t getRTCBatteryVoltage(); uint16_t getAnalogValue(uint8_t index); diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index f3d10e507..b215f753d 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -21,7 +21,14 @@ #include "opentx.h" #include "hal/adc_driver.h" -#include "../common/arm/stm32/stm32_hal_adc.h" + +#if !defined(PCBX12S) + #include "../common/arm/stm32/stm32_hal_adc.h" + #define ADC_DRIVER stm32_hal_adc_driver +#else + #include "x12_adc_driver.h" + #define ADC_DRIVER x12s_adc_driver +#endif #if defined(__cplusplus) extern "C" { @@ -200,7 +207,7 @@ void boardInit() } #endif - if (!adcInit(&stm32_hal_adc_driver)) + if (!adcInit(&ADC_DRIVER)) TRACE("adcInit failed"); lcdInit(); diff --git a/radio/src/targets/horus/x12s_adc_driver.cpp b/radio/src/targets/horus/x12s_adc_driver.cpp index b8127bddc..e4628cd96 100644 --- a/radio/src/targets/horus/x12s_adc_driver.cpp +++ b/radio/src/targets/horus/x12s_adc_driver.cpp @@ -100,7 +100,7 @@ static void ADS7952_Init() ADC_CS_HIGH(); } -void adcInit() +static bool x12s_adc_init() { ADS7952_Init(); @@ -227,6 +227,8 @@ bool adcOnChipReadFinished() return (ADC_DMA->LISR & DMA_LISR_TCIF0); } +// Re-declare adcRead() +// (takes precedence over hal/adc_driver.cpp) void adcRead() { uint16_t temp[NUM_ANALOGS-MOUSE1] = { 0 }; @@ -279,3 +281,14 @@ uint16_t getAnalogValue(uint8_t index) return adcValues[index]; } #endif // #if !defined(SIMU) + +//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(); + +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; From 4ea1820366107ad57eab3f8b9b1232897ea15d54 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 31 Jul 2021 16:18:04 +0200 Subject: [PATCH 10/13] Allow NULL driver methods --- radio/src/hal/adc_driver.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp index 6569f19ce..19a14c18f 100644 --- a/radio/src/hal/adc_driver.cpp +++ b/radio/src/hal/adc_driver.cpp @@ -89,14 +89,17 @@ uint16_t rtcBatteryVoltage; bool adcInit(const etx_hal_adc_driver_t* driver) { etx_hal_adc_driver = driver; - if (etx_hal_adc_driver && etx_hal_adc_driver->init) - { - if(!etx_hal_adc_driver->init()) - return false; + if (!etx_hal_adc_driver) + return false; - return true; + // If there is an init function + // it should succeed + if (etx_hal_adc_driver->init && + !etx_hal_adc_driver->init()) { + return false; } - return false; + + return true; } static bool adcSingleRead() @@ -104,14 +107,13 @@ static bool adcSingleRead() if (!etx_hal_adc_driver) return false; - if (!etx_hal_adc_driver->start_conversion || + if (etx_hal_adc_driver->start_conversion && !etx_hal_adc_driver->start_conversion()) return false; - if (!etx_hal_adc_driver->wait_completion) - return false; + if (etx_hal_adc_driver->wait_completion) + etx_hal_adc_driver->wait_completion(); - etx_hal_adc_driver->wait_completion(); return true; } From 56b30ffa9ea936f679585490c087e015309acf0f Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 31 Jul 2021 16:48:21 +0200 Subject: [PATCH 11/13] X12S fixes (not tested) --- radio/src/hal/adc_driver.cpp | 10 +++++++--- radio/src/hal/adc_driver.h | 6 ++---- radio/src/targets/horus/CMakeLists.txt | 1 + radio/src/targets/horus/board.cpp | 2 +- radio/src/targets/horus/x12s_adc_driver.cpp | 22 ++++----------------- 5 files changed, 15 insertions(+), 26 deletions(-) diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp index 19a14c18f..b68c04bef 100644 --- a/radio/src/hal/adc_driver.cpp +++ b/radio/src/hal/adc_driver.cpp @@ -76,13 +76,15 @@ const etx_hal_adc_driver_t* etx_hal_adc_driver = nullptr; 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) +#if defined(PCBX10) || defined(PCBX12S) uint16_t rtcBatteryVoltage; #endif @@ -117,7 +119,9 @@ static bool adcSingleRead() return true; } -bool adcRead() __attribute__((weak)) +// Declare adcRead() weak so it can be re-declared +#pragma weak adcRead +bool adcRead() { uint16_t temp[NUM_ANALOGS] = { 0 }; @@ -151,7 +155,7 @@ uint16_t getRTCBatteryVoltage() { #if defined(HAS_TX_RTC_VOLTAGE) return (getAnalogValue(TX_RTC_VOLTAGE) * ADC_VREF_PREC2) / 2048; -#elif defined(PCBX10) +#elif defined(PCBX10) || defined(PCBX12S) return (rtcBatteryVoltage * 2 * ADC_VREF_PREC2) / 2048; #elif defined(PCBNV14) #warning "TODO RTC voltage" diff --git a/radio/src/hal/adc_driver.h b/radio/src/hal/adc_driver.h index 3f7f02642..d9256ef62 100644 --- a/radio/src/hal/adc_driver.h +++ b/radio/src/hal/adc_driver.h @@ -41,7 +41,7 @@ #endif // TODO: get rid of this special case -#if defined(PCBX10) +#if defined(PCBX10) || defined(PCBX12S) extern uint16_t rtcBatteryVoltage; #endif @@ -54,8 +54,6 @@ struct etx_hal_adc_driver_t { bool adcInit(const etx_hal_adc_driver_t* driver); // void adcDeInit(); -// Declare adcRead() weak so it can be re-declared -bool adcRead() __attribute__((weak)); - +bool adcRead(); uint16_t getRTCBatteryVoltage(); uint16_t getAnalogValue(uint8_t index); diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 1ff3ea877..2c71792a1 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -138,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 b215f753d..4faa08b93 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -26,7 +26,7 @@ #include "../common/arm/stm32/stm32_hal_adc.h" #define ADC_DRIVER stm32_hal_adc_driver #else - #include "x12_adc_driver.h" + #include "x12s_adc_driver.h" #define ADC_DRIVER x12s_adc_driver #endif diff --git a/radio/src/targets/horus/x12s_adc_driver.cpp b/radio/src/targets/horus/x12s_adc_driver.cpp index e4628cd96..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) @@ -137,11 +136,8 @@ static bool x12s_adc_init() 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] = @@ -229,7 +225,7 @@ bool adcOnChipReadFinished() // Re-declare adcRead() // (takes precedence over hal/adc_driver.cpp) -void adcRead() +bool adcRead() { uint16_t temp[NUM_ANALOGS-MOUSE1] = { 0 }; uint8_t noInternalReads = 0; @@ -268,19 +264,9 @@ void adcRead() if (isVBatBridgeEnabled()) { rtcBatteryVoltage = ADC1->DR; } -} -#if !defined(SIMU) -const int8_t ana_direction[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, -1,-1, -1,1, 0,0,0}; - -uint16_t getAnalogValue(uint8_t index) -{ - if (ana_direction[index] < 0) - return 4095 - adcValues[index]; - else - return adcValues[index]; + return true; } -#endif // #if !defined(SIMU) //TODO: implement these based on stm32_hal_adc.cpp //static bool x12s_adc_init(); From 2e5dd73f5151c4400ac8a33af5de517d8f2e792c Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 31 Jul 2021 16:59:36 +0200 Subject: [PATCH 12/13] Fixed NV14 TC flags --- radio/src/targets/nv14/hal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radio/src/targets/nv14/hal.h b/radio/src/targets/nv14/hal.h index b5520a835..5dfbfaeca 100644 --- a/radio/src/targets/nv14/hal.h +++ b/radio/src/targets/nv14/hal.h @@ -158,11 +158,11 @@ #define ADC_DMA DMA2 #define ADC_DMA_Channel DMA_Channel_0 #define ADC_DMA_Stream DMA2_Stream4 -#define ADC_TRANSFER_COMPLETE() (ADC_DMA->HISR & DMA_HISR_TCIF4) +#define ADC_DMA_TC_Flag DMA_FLAG_TCIF4 #define ADC_EXT_DMA_Channel DMA_Channel_2 #define ADC_EXT_DMA_Stream DMA2_Stream0 -#define ADC_EXT_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) +#define ADC_EXT_DMA_TC_Flag DMA_FLAG_TCIF0 // Power #define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOI From a8e2e3de741d5c3af8ffef293ebce5571a5270f0 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 31 Jul 2021 17:14:06 +0200 Subject: [PATCH 13/13] Fixed NV14 simu linking --- radio/src/hal/adc_driver.cpp | 2 +- radio/src/targets/nv14/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp index b68c04bef..831f8037b 100644 --- a/radio/src/hal/adc_driver.cpp +++ b/radio/src/hal/adc_driver.cpp @@ -151,6 +151,7 @@ bool adcRead() return true; } +#if !defined(SIMU) uint16_t getRTCBatteryVoltage() { #if defined(HAS_TX_RTC_VOLTAGE) @@ -166,7 +167,6 @@ uint16_t getRTCBatteryVoltage() #endif } -#if !defined(SIMU) uint16_t getAnalogValue(uint8_t index) { if (IS_POT(index) && !IS_POT_SLIDER_AVAILABLE(index)) { diff --git a/radio/src/targets/nv14/CMakeLists.txt b/radio/src/targets/nv14/CMakeLists.txt index 4f5aa592b..5cc1d030b 100644 --- a/radio/src/targets/nv14/CMakeLists.txt +++ b/radio/src/targets/nv14/CMakeLists.txt @@ -48,8 +48,6 @@ add_definitions(-DINTERNAL_MODULE_AFHDS2A) set(TARGET_SRC ${TARGET_SRC} audio_spi_driver.cpp - ../../hal/adc_driver.cpp - ../common/arm/stm32/stm32_hal_adc.cpp ../common/arm/stm32/mixer_scheduler_driver.cpp ../common/arm/stm32/timers_driver.cpp ) @@ -58,6 +56,8 @@ 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)