/* * 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 // 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++](); } }