144 lines
3.5 KiB
C++
144 lines
3.5 KiB
C++
/*
|
|
* 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 "analog_inputs.h"
|
|
#include "stm32_adc.h"
|
|
#include "stm32_spi_adc.h"
|
|
#include "sticks_pwm_driver.h"
|
|
#include "flysky_gimbal_driver.h"
|
|
|
|
#include "hal.h"
|
|
|
|
#if defined(ADC_SPI)
|
|
#include "ads79xx.h"
|
|
#endif
|
|
|
|
#include "definitions.h"
|
|
|
|
#include "myeeprom.h"
|
|
#include "translations.h"
|
|
|
|
#include <string.h>
|
|
|
|
// generated files
|
|
#include "stm32_adc_inputs.inc"
|
|
#include "stm32_pwm_inputs.inc"
|
|
#include "hal_adc_inputs.inc"
|
|
|
|
constexpr uint8_t n_ADC = DIM(_ADC_adc);
|
|
constexpr uint8_t n_ADC_spi = DIM(_ADC_spi);
|
|
constexpr uint8_t n_GPIO = DIM(_ADC_GPIOs);
|
|
constexpr uint8_t n_inputs = DIM(_ADC_inputs);
|
|
|
|
static_assert(n_inputs <= MAX_ADC_INPUTS, "Too many ADC inputs");
|
|
static_assert(n_inputs <= MAX_ANALOG_INPUTS, "Too many analog inputs");
|
|
|
|
static bool adc_init()
|
|
{
|
|
bool success = stm32_hal_adc_init(_ADC_adc, n_ADC, _ADC_inputs, _ADC_GPIOs, n_GPIO);
|
|
#if defined(ADC_SPI)
|
|
if (n_ADC_spi > 0) ads79xx_init(&_ADC_spi[0]);
|
|
#endif
|
|
return success;
|
|
}
|
|
|
|
static bool adc_start_read()
|
|
{
|
|
bool success = stm32_hal_adc_start_read(_ADC_adc, n_ADC, _ADC_inputs, n_inputs);
|
|
#if defined(ADC_SPI)
|
|
if (n_ADC_spi > 0) {
|
|
success = success && ads79xx_adc_start_read(&_ADC_spi[0], _ADC_inputs);
|
|
}
|
|
#endif
|
|
return success;
|
|
}
|
|
|
|
static void adc_wait_completion()
|
|
{
|
|
#if defined(ADC_SPI)
|
|
// ADS79xx does all the work in the completion function
|
|
// so it's probably better to poll it first
|
|
if (n_ADC_spi > 0) ads79xx_adc_wait_completion(&_ADC_spi[0], _ADC_inputs);
|
|
#endif
|
|
stm32_hal_adc_wait_completion(_ADC_adc, n_ADC, _ADC_inputs, n_inputs);
|
|
}
|
|
|
|
const etx_hal_adc_driver_t _adc_driver = {
|
|
.inputs = _hal_inputs,
|
|
.default_pots_cfg = _pot_default_config,
|
|
.init = adc_init,
|
|
.start_conversion = adc_start_read,
|
|
.wait_completion = adc_wait_completion,
|
|
.set_input_mask = stm32_hal_set_inputs_mask,
|
|
.get_input_mask = stm32_hal_get_inputs_mask,
|
|
};
|
|
|
|
#if defined(PWM_STICKS)
|
|
#include "stm32_gpio.h"
|
|
|
|
static const stick_pwm_timer_t _sticks_timer = {
|
|
.GPIOx = PWM_GPIO,
|
|
.GPIO_Pin = PWM_GPIOA_PINS,
|
|
.GPIO_Alternate = PWM_GPIO_AF,
|
|
.TIMx = PWM_TIMER,
|
|
.TIM_IRQn = PWM_IRQn,
|
|
.TIM_Freq = PWM_TIMER_FREQ,
|
|
};
|
|
|
|
#if !defined(PWM_IRQHandler)
|
|
#error "Missing PWM_IRQHandler"
|
|
#endif
|
|
|
|
static_assert(DIM(_PWM_inputs) <= MAX_STICKS, "too many PWM inputs");
|
|
|
|
extern "C" void PWM_IRQHandler(void)
|
|
{
|
|
sticks_pwm_isr(&_sticks_timer, _PWM_inputs, DIM(_PWM_inputs));
|
|
}
|
|
|
|
static bool pwm_gimbal_init()
|
|
{
|
|
return sticks_pwm_detect(&_sticks_timer, _PWM_inputs, DIM(_PWM_inputs));
|
|
}
|
|
|
|
#endif
|
|
|
|
typedef bool (*gimbal_driver_t)();
|
|
|
|
const gimbal_driver_t gimbal_drivers[] = {
|
|
#if defined(PWM_STICKS)
|
|
pwm_gimbal_init,
|
|
#endif
|
|
#if defined(FLYSKY_GIMBAL)
|
|
flysky_gimbal_init,
|
|
#endif
|
|
};
|
|
|
|
void gimbalsDetect()
|
|
{
|
|
unsigned idx = 0;
|
|
bool detected = false;
|
|
|
|
while (idx < DIM(gimbal_drivers) && !detected) {
|
|
detected = gimbal_drivers[idx++]();
|
|
}
|
|
}
|