WiP
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#define XPOT_DELTA 10
|
||||
#define XPOT_DELAY 10 /* cycles */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <opentx.h>
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#if defined(PCBSKY9X)
|
||||
#define HW_SETTINGS_COLUMN (2+(15*FW))
|
||||
|
||||
@@ -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<NUM_ANALOGS; x++) {
|
||||
uint16_t val = adcValues[x];
|
||||
#if defined(JITTER_MEASURE)
|
||||
if (JITTER_MEASURE_ACTIVE()) {
|
||||
rawJitter[x].measure(val);
|
||||
}
|
||||
#endif
|
||||
temp[x] += 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(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)
|
||||
+27
-11
@@ -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 <stdint.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#if defined(LIBOPENUI)
|
||||
#include "libopenui.h"
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include <io/frsky_firmware_update.h>
|
||||
#include "io/frsky_firmware_update.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#if defined(LIBOPENUI)
|
||||
#include "libopenui.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)
|
||||
|
||||
+113
-172
@@ -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<NUM_ANALOGS; x++) {
|
||||
uint16_t val = adcValues[x];
|
||||
#if defined(JITTER_MEASURE)
|
||||
if (JITTER_MEASURE_ACTIVE()) {
|
||||
rawJitter[x].measure(val);
|
||||
}
|
||||
#endif
|
||||
temp[x] += 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(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
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user