From c745983f95c42ef31c04094bd0c691a1cc2c6f48 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Tue, 23 Jun 2020 23:01:59 +0200 Subject: [PATCH] define gpios as array of Stm32Gpio objects --- Firmware/Board/v3/Inc/board.h | 14 +-- Firmware/Board/v3/board.cpp | 38 +++++++ Firmware/Drivers/STM32/stm32_gpio.cpp | 1 + Firmware/Drivers/STM32/stm32_gpio.hpp | 10 +- Firmware/MotorControl/axis.cpp | 19 ++-- Firmware/MotorControl/axis.hpp | 6 +- Firmware/MotorControl/encoder.cpp | 18 ++-- Firmware/MotorControl/encoder.hpp | 3 +- Firmware/MotorControl/endstop.cpp | 14 +-- Firmware/MotorControl/gpio_utils.hpp | 46 --------- Firmware/MotorControl/low_level.cpp | 123 ++++++++--------------- Firmware/MotorControl/low_level.h | 4 +- Firmware/MotorControl/main.cpp | 16 +-- Firmware/MotorControl/odrive_main.h | 6 +- Firmware/MotorControl/thermistor.cpp | 5 +- Firmware/communication/communication.cpp | 1 - 16 files changed, 132 insertions(+), 192 deletions(-) delete mode 100644 Firmware/MotorControl/gpio_utils.hpp diff --git a/Firmware/Board/v3/Inc/board.h b/Firmware/Board/v3/Inc/board.h index 66cf3a3f..0294b34b 100644 --- a/Firmware/Board/v3/Inc/board.h +++ b/Firmware/Board/v3/Inc/board.h @@ -29,6 +29,12 @@ #define AXIS_COUNT (2) +#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR <= 4 +#define GPIO_COUNT (5) +#elif HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 5 +#define GPIO_COUNT (8) +#endif + #ifdef __cplusplus #include @@ -44,6 +50,8 @@ using TOpAmp = Drv8301; extern Motor motors[AXIS_COUNT]; extern OnboardThermistorCurrentLimiter fet_thermistors[AXIS_COUNT]; extern Encoder encoders[AXIS_COUNT]; +extern Stm32Gpio gpios[GPIO_COUNT]; +extern uint32_t pwm_in_gpios[4]; #include extern Stm32SpiArbiter& ext_spi_arbiter; @@ -100,12 +108,6 @@ const BoardHardwareConfig_t hw_configs[AXIS_COUNT] = { { #define I2C_A2_PORT GPIO_5_GPIO_Port #define I2C_A2_PIN GPIO_5_Pin -#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR <= 4 -#define GPIO_COUNT 5 -#else -#define GPIO_COUNT 8 -#endif - // This board has no board-specific user configurations static inline bool board_pop_config() { return true; } static inline bool board_push_config() { return true; } diff --git a/Firmware/Board/v3/board.cpp b/Firmware/Board/v3/board.cpp index 1143222a..8ca73270 100644 --- a/Firmware/Board/v3/board.cpp +++ b/Firmware/Board/v3/board.cpp @@ -80,6 +80,44 @@ Encoder encoders[AXIS_COUNT] = { }; +// Note that GPIO1 as labeled on the board corresponds to gpios[0] in code. +#if (HW_VERSION_MINOR == 1) || (HW_VERSION_MINOR == 2) +Stm32Gpio gpios[] = { + {GPIOB, GPIO_PIN_2}, + {GPIOA, GPIO_PIN_5}, + {GPIOA, GPIO_PIN_4}, + {GPIOA, GPIO_PIN_3} +}; +#elif (HW_VERSION_MINOR == 3) || (HW_VERSION_MINOR == 4) +Stm32Gpio gpios[] = { + {GPIOA, GPIO_PIN_0}, + {GPIOA, GPIO_PIN_1}, + {GPIOA, GPIO_PIN_2}, + {GPIOA, GPIO_PIN_3}, + {GPIOB, GPIO_PIN_2} +}; +#elif (HW_VERSION_MINOR == 5) || (HW_VERSION_MINOR == 6) +Stm32Gpio gpios[] = { + {GPIOA, GPIO_PIN_0}, + {GPIOA, GPIO_PIN_1}, + {GPIOA, GPIO_PIN_2}, + {GPIOA, GPIO_PIN_3}, + {GPIOC, GPIO_PIN_4}, + {GPIOB, GPIO_PIN_2}, + {GPIOA, GPIO_PIN_15}, + {GPIOB, GPIO_PIN_3} +}; +#else +#error "unknown GPIOs" +#endif + +#if HW_VERSION_MINOR <= 2 +uint32_t pwm_in_gpios[4] = { 0, 0, 0, 4 }; // 0 means not in use +#else +uint32_t pwm_in_gpios[4] = { 1, 2, 3, 4 }; +#endif + + void board_init() { // Ensure that debug halting of the core doesn't leave the motor PWM running __HAL_DBGMCU_FREEZE_TIM1(); diff --git a/Firmware/Drivers/STM32/stm32_gpio.cpp b/Firmware/Drivers/STM32/stm32_gpio.cpp index 51a88228..cb4e738c 100644 --- a/Firmware/Drivers/STM32/stm32_gpio.cpp +++ b/Firmware/Drivers/STM32/stm32_gpio.cpp @@ -9,6 +9,7 @@ struct subscription_t { void* ctx = nullptr; } subscriptions[N_EXTI]; +const Stm32Gpio Stm32Gpio::none{nullptr, 0}; /** * @brief Returns the IRQ number associated with a certain pin. diff --git a/Firmware/Drivers/STM32/stm32_gpio.hpp b/Firmware/Drivers/STM32/stm32_gpio.hpp index 2df5fc5e..405f6fb2 100644 --- a/Firmware/Drivers/STM32/stm32_gpio.hpp +++ b/Firmware/Drivers/STM32/stm32_gpio.hpp @@ -5,6 +5,8 @@ class Stm32Gpio { public: + static const Stm32Gpio none; + Stm32Gpio() : port_(nullptr), pin_mask_(0) {} Stm32Gpio(GPIO_TypeDef* port, uint16_t pin) : port_(port), pin_mask_(pin) {} @@ -19,6 +21,8 @@ public: * TODO: avoid disabling interrupt if it is enabled */ bool config(uint32_t mode, uint32_t pull) { + if (!port_) + return false; HAL_GPIO_DeInit(port_, pin_mask_); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = pin_mask_; @@ -30,11 +34,13 @@ public: } void write(bool state) { - HAL_GPIO_WritePin(port_, pin_mask_, state ? GPIO_PIN_SET : GPIO_PIN_RESET); + if (port_) { + HAL_GPIO_WritePin(port_, pin_mask_, state ? GPIO_PIN_SET : GPIO_PIN_RESET); + } } bool read() { - return HAL_GPIO_ReadPin(port_, pin_mask_) != GPIO_PIN_RESET; + return port_ && (HAL_GPIO_ReadPin(port_, pin_mask_) != GPIO_PIN_RESET); } /** diff --git a/Firmware/MotorControl/axis.cpp b/Firmware/MotorControl/axis.cpp index 2718b680..ec2efea5 100644 --- a/Firmware/MotorControl/axis.cpp +++ b/Firmware/MotorControl/axis.cpp @@ -5,7 +5,6 @@ #include "odrive_main.h" #include "utils.hpp" -#include "gpio_utils.hpp" #include "communication/interface_can.hpp" Axis::Axis(int axis_num, @@ -119,8 +118,8 @@ bool Axis::wait_for_current_meas() { // step/direction interface void Axis::step_cb() { if (step_dir_active_) { - GPIO_PinState dir_pin = HAL_GPIO_ReadPin(dir_port_, dir_pin_); - float dir = (dir_pin == GPIO_PIN_SET) ? 1.0f : -1.0f; + bool dir_pin = dir_gpio_.read(); + float dir = dir_pin ? 1.0f : -1.0f; controller_.input_pos_ += dir * config_.counts_per_step; controller_.input_pos_updated(); } @@ -137,21 +136,19 @@ void Axis::load_default_can_id(const int& id, Config_t& config){ } void Axis::decode_step_dir_pins() { - step_port_ = get_gpio_port_by_pin(config_.step_gpio_pin); - step_pin_ = get_gpio_pin_by_pin(config_.step_gpio_pin); - dir_port_ = get_gpio_port_by_pin(config_.dir_gpio_pin); - dir_pin_ = get_gpio_pin_by_pin(config_.dir_gpio_pin); + step_gpio_ = get_gpio(config_.step_gpio_pin); + dir_gpio_ = get_gpio(config_.dir_gpio_pin); } // @brief (de)activates step/dir input void Axis::set_step_dir_active(bool active) { if (active) { // Set up the step/direction GPIOs as input - Stm32Gpio{dir_port_, dir_pin_}.config(GPIO_MODE_INPUT, GPIO_NOPULL); - Stm32Gpio{step_port_, step_pin_}.config(GPIO_MODE_INPUT, GPIO_PULLDOWN); + dir_gpio_.config(GPIO_MODE_INPUT, GPIO_NOPULL); + step_gpio_.config(GPIO_MODE_INPUT, GPIO_PULLDOWN); // Subscribe to rising edges of the step GPIO - Stm32Gpio{step_port_, step_pin_}.subscribe(true, false, step_cb_wrapper, this); + step_gpio_.subscribe(true, false, step_cb_wrapper, this); step_dir_active_ = true; } else { @@ -160,7 +157,7 @@ void Axis::set_step_dir_active(bool active) { // Unsubscribe from step GPIO // TODO: if we change the GPIO while the subscription is active and then // unsubscribe then the unsubscribe is for the wrong pin. - Stm32Gpio{step_port_, step_pin_}.unsubscribe(); + step_gpio_.unsubscribe(); } } diff --git a/Firmware/MotorControl/axis.hpp b/Firmware/MotorControl/axis.hpp index f35c11e2..e63cc98a 100644 --- a/Firmware/MotorControl/axis.hpp +++ b/Firmware/MotorControl/axis.hpp @@ -227,10 +227,8 @@ public: bool step_dir_active_ = false; // auto enabled after calibration, based on config.enable_step_dir // updated from config in constructor, and on protocol hook - GPIO_TypeDef* step_port_; - uint16_t step_pin_; - GPIO_TypeDef* dir_port_; - uint16_t dir_pin_; + Stm32Gpio step_gpio_; + Stm32Gpio dir_gpio_; AxisState requested_state_ = AXIS_STATE_STARTUP_SEQUENCE; std::array task_chain_ = { AXIS_STATE_UNDEFINED }; diff --git a/Firmware/MotorControl/encoder.cpp b/Firmware/MotorControl/encoder.cpp index 3151aacd..7a982197 100644 --- a/Firmware/MotorControl/encoder.cpp +++ b/Firmware/MotorControl/encoder.cpp @@ -329,8 +329,8 @@ void Encoder::sample_now() { } break; case MODE_SINCOS: { - sincos_sample_s_ = (get_adc_voltage(get_gpio_port_by_pin(config_.sincos_gpio_pin_sin), get_gpio_pin_by_pin(config_.sincos_gpio_pin_sin)) / 3.3f) - 0.5f; - sincos_sample_c_ = (get_adc_voltage(get_gpio_port_by_pin(config_.sincos_gpio_pin_cos), get_gpio_pin_by_pin(config_.sincos_gpio_pin_cos)) / 3.3f) - 0.5f; + sincos_sample_s_ = (get_adc_voltage(get_gpio(config_.sincos_gpio_pin_sin)) / 3.3f) - 0.5f; + sincos_sample_c_ = (get_adc_voltage(get_gpio(config_.sincos_gpio_pin_cos)) / 3.3f) - 0.5f; } break; case MODE_SPI_ABS_AMS: @@ -374,7 +374,7 @@ bool Encoder::abs_spi_start_transaction(){ return false; } - spi_task_.ncs_gpio = {abs_spi_cs_port_, abs_spi_cs_pin_}; + spi_task_.ncs_gpio = abs_spi_cs_gpio_; spi_task_.tx_buf = (uint8_t*)abs_spi_dma_tx_; spi_task_.rx_buf = (uint8_t*)abs_spi_dma_rx_; spi_task_.length = 1; @@ -445,20 +445,20 @@ void Encoder::abs_spi_cb() { void Encoder::abs_spi_cs_pin_init(){ // Decode cs pin - abs_spi_cs_port_ = get_gpio_port_by_pin(config_.abs_spi_cs_gpio_pin); - abs_spi_cs_pin_ = get_gpio_pin_by_pin(config_.abs_spi_cs_gpio_pin); + abs_spi_cs_gpio_ = get_gpio(config_.abs_spi_cs_gpio_pin); // Init cs pin - HAL_GPIO_DeInit(abs_spi_cs_port_, abs_spi_cs_pin_); + // TODO: absorb into Stm32Gpio class + HAL_GPIO_DeInit(abs_spi_cs_gpio_.port_, abs_spi_cs_gpio_.pin_mask_); GPIO_InitTypeDef GPIO_InitStruct; - GPIO_InitStruct.Pin = abs_spi_cs_pin_; + GPIO_InitStruct.Pin = abs_spi_cs_gpio_.pin_mask_; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(abs_spi_cs_port_, &GPIO_InitStruct); + HAL_GPIO_Init(abs_spi_cs_gpio_.port_, &GPIO_InitStruct); // Write pin high - HAL_GPIO_WritePin(abs_spi_cs_port_, abs_spi_cs_pin_, GPIO_PIN_SET); + abs_spi_cs_gpio_.write(true); } bool Encoder::update() { diff --git a/Firmware/MotorControl/encoder.hpp b/Firmware/MotorControl/encoder.hpp index 7b00aa14..793083e5 100644 --- a/Firmware/MotorControl/encoder.hpp +++ b/Firmware/MotorControl/encoder.hpp @@ -113,8 +113,7 @@ public: uint16_t abs_spi_dma_rx_[1]; bool abs_spi_pos_updated_ = false; Mode mode_ = MODE_INCREMENTAL; - GPIO_TypeDef* abs_spi_cs_port_; - uint16_t abs_spi_cs_pin_; + Stm32Gpio abs_spi_cs_gpio_; uint32_t abs_spi_cr1; uint32_t abs_spi_cr2; bool spi_busy_ = false; diff --git a/Firmware/MotorControl/endstop.cpp b/Firmware/MotorControl/endstop.cpp index 7febba16..585b4bf2 100644 --- a/Firmware/MotorControl/endstop.cpp +++ b/Firmware/MotorControl/endstop.cpp @@ -12,9 +12,7 @@ void Endstop::update() { if (config_.enabled) { bool last_pin_state = pin_state_; - uint16_t gpio_pin = get_gpio_pin_by_pin(config_.gpio_num); - GPIO_TypeDef* gpio_port = get_gpio_port_by_pin(config_.gpio_num); - pin_state_ = HAL_GPIO_ReadPin(gpio_port, gpio_pin); + pin_state_ = get_gpio(config_.gpio_num).read(); // If the pin state has changed, reset the timer if (pin_state_ != last_pin_state) @@ -39,15 +37,9 @@ void Endstop::update_config() { void Endstop::set_enabled(bool enable) { debounceTimer_.reset(); if (config_.gpio_num != 0) { - uint16_t gpio_pin = get_gpio_pin_by_pin(config_.gpio_num); - GPIO_TypeDef* gpio_port = get_gpio_port_by_pin(config_.gpio_num); if (enable) { - HAL_GPIO_DeInit(gpio_port, gpio_pin); - GPIO_InitTypeDef GPIO_InitStruct; - GPIO_InitStruct.Pin = gpio_pin; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = config_.pullup ? GPIO_PULLUP : GPIO_PULLDOWN; - HAL_GPIO_Init(gpio_port, &GPIO_InitStruct); + Stm32Gpio gpio = get_gpio(config_.gpio_num); + gpio.config(GPIO_MODE_INPUT, config_.pullup ? GPIO_PULLUP : GPIO_PULLDOWN); debounceTimer_.start(); } else debounceTimer_.stop(); diff --git a/Firmware/MotorControl/gpio_utils.hpp b/Firmware/MotorControl/gpio_utils.hpp deleted file mode 100644 index fb70f46e..00000000 --- a/Firmware/MotorControl/gpio_utils.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "gpio.h" -constexpr GPIO_TypeDef* get_gpio_port_by_pin(uint16_t GPIO_pin){ - switch(GPIO_pin){ - case 1: return GPIO_1_GPIO_Port; break; - case 2: return GPIO_2_GPIO_Port; break; - case 3: return GPIO_3_GPIO_Port; break; - case 4: return GPIO_4_GPIO_Port; break; -#ifdef GPIO_5_GPIO_Port - case 5: return GPIO_5_GPIO_Port; break; -#endif -#ifdef GPIO_6_GPIO_Port - case 6: return GPIO_6_GPIO_Port; break; -#endif -#ifdef GPIO_7_GPIO_Port - case 7: return GPIO_7_GPIO_Port; break; -#endif -#ifdef GPIO_8_GPIO_Port - case 8: return GPIO_8_GPIO_Port; break; -#endif - default: return GPIO_1_GPIO_Port; - } -} - -constexpr uint16_t get_gpio_pin_by_pin(uint16_t GPIO_pin){ - switch(GPIO_pin){ - case 1: return GPIO_1_Pin; break; - case 2: return GPIO_2_Pin; break; - case 3: return GPIO_3_Pin; break; - case 4: return GPIO_4_Pin; break; -#ifdef GPIO_5_Pin - case 5: return GPIO_5_Pin; break; -#endif -#ifdef GPIO_6_Pin - case 6: return GPIO_6_Pin; break; -#endif -#ifdef GPIO_7_Pin - case 7: return GPIO_7_Pin; break; -#endif -#ifdef GPIO_8_Pin - case 8: return GPIO_8_Pin; break; -#endif - default: return GPIO_1_Pin; - } -} diff --git a/Firmware/MotorControl/low_level.cpp b/Firmware/MotorControl/low_level.cpp index 36c4e292..891f59b4 100644 --- a/Firmware/MotorControl/low_level.cpp +++ b/Firmware/MotorControl/low_level.cpp @@ -313,50 +313,49 @@ void start_general_purpose_adc() { // 21000kHz / (15+26) / 16 = 32kHz // The true frequency is slightly lower because of the injected vbus // measurements -float get_adc_voltage(const GPIO_TypeDef* const GPIO_port, uint16_t GPIO_pin) { - const uint16_t channel = channel_from_gpio(GPIO_port, GPIO_pin); +float get_adc_voltage(Stm32Gpio gpio) { + const uint16_t channel = channel_from_gpio(gpio); return get_adc_voltage_channel(channel); } // @brief Given a GPIO_port and pin return the associated adc_channel. // returns UINT16_MAX if there is no adc_channel; -uint16_t channel_from_gpio(const GPIO_TypeDef* const GPIO_port, uint16_t GPIO_pin) -{ - uint16_t channel = UINT16_MAX; - if (GPIO_port == GPIOA) { - if (GPIO_pin == GPIO_PIN_0) +uint16_t channel_from_gpio(Stm32Gpio gpio) { + uint32_t channel = UINT32_MAX; + if (gpio.port_ == GPIOA) { + if (gpio.pin_mask_ == GPIO_PIN_0) channel = 0; - else if (GPIO_pin == GPIO_PIN_1) + else if (gpio.pin_mask_ == GPIO_PIN_1) channel = 1; - else if (GPIO_pin == GPIO_PIN_2) + else if (gpio.pin_mask_ == GPIO_PIN_2) channel = 2; - else if (GPIO_pin == GPIO_PIN_3) + else if (gpio.pin_mask_ == GPIO_PIN_3) channel = 3; - else if (GPIO_pin == GPIO_PIN_4) + else if (gpio.pin_mask_ == GPIO_PIN_4) channel = 4; - else if (GPIO_pin == GPIO_PIN_5) + else if (gpio.pin_mask_ == GPIO_PIN_5) channel = 5; - else if (GPIO_pin == GPIO_PIN_6) + else if (gpio.pin_mask_ == GPIO_PIN_6) channel = 6; - else if (GPIO_pin == GPIO_PIN_7) + else if (gpio.pin_mask_ == GPIO_PIN_7) channel = 7; - } else if (GPIO_port == GPIOB) { - if (GPIO_pin == GPIO_PIN_0) + } else if (gpio.port_ == GPIOB) { + if (gpio.pin_mask_ == GPIO_PIN_0) channel = 8; - else if (GPIO_pin == GPIO_PIN_1) + else if (gpio.pin_mask_ == GPIO_PIN_1) channel = 9; - } else if (GPIO_port == GPIOC) { - if (GPIO_pin == GPIO_PIN_0) + } else if (gpio.port_ == GPIOC) { + if (gpio.pin_mask_ == GPIO_PIN_0) channel = 10; - else if (GPIO_pin == GPIO_PIN_1) + else if (gpio.pin_mask_ == GPIO_PIN_1) channel = 11; - else if (GPIO_pin == GPIO_PIN_2) + else if (gpio.pin_mask_ == GPIO_PIN_2) channel = 12; - else if (GPIO_pin == GPIO_PIN_3) + else if (gpio.pin_mask_ == GPIO_PIN_3) channel = 13; - else if (GPIO_pin == GPIO_PIN_4) + else if (gpio.pin_mask_ == GPIO_PIN_4) channel = 14; - else if (GPIO_pin == GPIO_PIN_5) + else if (gpio.pin_mask_ == GPIO_PIN_5) channel = 15; } return channel; @@ -537,47 +536,6 @@ void update_brake_current() { /* RC PWM input --------------------------------------------------------------*/ -// @brief Returns the ODrive GPIO number for a given -// TIM2 or TIM5 input capture channel number. -int tim_2_5_channel_num_to_gpio_num(int channel) { -#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 3 - if (channel >= 1 && channel <= 4) { - // the channel numbers just happen to coincide with - // the GPIO numbers - return channel; - } else { - return -1; - } -#else - // Only ch4 is available on v3.2 - if (channel == 4) { - return 4; - } else { - return -1; - } -#endif -} -// @brief Returns the TIM2 or TIM5 channel number -// for a given GPIO number. -uint32_t gpio_num_to_tim_2_5_channel(int gpio_num) { -#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 3 - switch (gpio_num) { - case 1: return TIM_CHANNEL_1; - case 2: return TIM_CHANNEL_2; - case 3: return TIM_CHANNEL_3; - case 4: return TIM_CHANNEL_4; - default: return 0; - } -#else - // Only ch4 is available on v3.2 - if (gpio_num == 4) { - return TIM_CHANNEL_4; - } else { - return 0; - } -#endif -} - void pwm_in_init() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; @@ -591,18 +549,21 @@ void pwm_in_init() { sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 15; -#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 3 - for (int gpio_num = 1; gpio_num <= 4; ++gpio_num) { -#else - int gpio_num = 4; { -#endif - if (fibre::is_endpoint_ref_valid(odrv.config_.pwm_mappings[gpio_num - 1].endpoint)) { - GPIO_InitStruct.Pin = get_gpio_pin_by_pin(gpio_num); - HAL_GPIO_DeInit(get_gpio_port_by_pin(gpio_num), get_gpio_pin_by_pin(gpio_num)); - HAL_GPIO_Init(get_gpio_port_by_pin(gpio_num), &GPIO_InitStruct); - HAL_TIM_IC_ConfigChannel(&htim5, &sConfigIC, gpio_num_to_tim_2_5_channel(gpio_num)); - HAL_TIM_IC_Start_IT(&htim5, gpio_num_to_tim_2_5_channel(gpio_num)); - } + uint32_t channels[] = {TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4}; + + for (size_t i = 0; i < 4; ++i) { + uint32_t gpio_num = pwm_in_gpios[i]; + if (gpio_num < 1 || gpio_num > GPIO_COUNT) + continue; + if (!fibre::is_endpoint_ref_valid(odrv.config_.pwm_mappings[gpio_num - 1].endpoint)) + continue; + + Stm32Gpio gpio = gpios[gpio_num]; + GPIO_InitStruct.Pin = gpio.pin_mask_; + HAL_GPIO_DeInit(gpio.port_, gpio.pin_mask_); + HAL_GPIO_Init(gpio.port_, &GPIO_InitStruct); + HAL_TIM_IC_ConfigChannel(&htim5, &sConfigIC, channels[i]); + HAL_TIM_IC_Start_IT(&htim5, channels[i]); } } @@ -634,10 +595,12 @@ void pwm_in_cb(int channel, uint32_t timestamp) { static bool last_pin_state[GPIO_COUNT] = { false }; static bool last_sample_valid[GPIO_COUNT] = { false }; - int gpio_num = tim_2_5_channel_num_to_gpio_num(channel); + if (channel >= 4) + return; + int gpio_num = pwm_in_gpios[channel]; if (gpio_num < 1 || gpio_num > GPIO_COUNT) return; - bool current_pin_state = HAL_GPIO_ReadPin(get_gpio_port_by_pin(gpio_num), get_gpio_pin_by_pin(gpio_num)) != GPIO_PIN_RESET; + bool current_pin_state = get_gpio(gpio_num).read(); if (last_sample_valid[gpio_num - 1] && (last_pin_state[gpio_num - 1] != PWM_INVERT_INPUT) @@ -655,7 +618,7 @@ void pwm_in_cb(int channel, uint32_t timestamp) { static void update_analog_endpoint(const struct PWMMapping_t *map, int gpio) { - float fraction = get_adc_voltage(get_gpio_port_by_pin(gpio), get_gpio_pin_by_pin(gpio)) / 3.3f; + float fraction = get_adc_voltage(get_gpio(gpio)) / 3.3f; float value = map->min + (fraction * (map->max - map->min)); fibre::set_endpoint_from_float(map->endpoint, value); } diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 6e972856..9e35808c 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -47,8 +47,8 @@ void sync_timers(TIM_HandleTypeDef* htim_a, TIM_HandleTypeDef* htim_b, uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset, TIM_HandleTypeDef* htim_refbase = nullptr); void start_general_purpose_adc(); -float get_adc_voltage(const GPIO_TypeDef* const GPIO_port, uint16_t GPIO_pin); -uint16_t channel_from_gpio(const GPIO_TypeDef* const GPIO_port, uint16_t GPIO_pin); +float get_adc_voltage(Stm32Gpio gpio); +uint16_t channel_from_gpio(Stm32Gpio gpio); float get_adc_voltage_channel(uint16_t channel); void pwm_in_init(); void start_analog_thread(); diff --git a/Firmware/MotorControl/main.cpp b/Firmware/MotorControl/main.cpp index edfb46a7..19eee8a4 100644 --- a/Firmware/MotorControl/main.cpp +++ b/Firmware/MotorControl/main.cpp @@ -185,18 +185,10 @@ extern "C" int construct_objects(){ GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Pin = GPIO_1_Pin; - HAL_GPIO_Init(GPIO_1_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = GPIO_2_Pin; - HAL_GPIO_Init(GPIO_2_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = GPIO_3_Pin; - HAL_GPIO_Init(GPIO_3_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = GPIO_4_Pin; - HAL_GPIO_Init(GPIO_4_GPIO_Port, &GPIO_InitStruct); -#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 5 - GPIO_InitStruct.Pin = GPIO_5_Pin; - HAL_GPIO_Init(GPIO_5_GPIO_Port, &GPIO_InitStruct); -#endif + for (Stm32Gpio& gpio: gpios) { + GPIO_InitStruct.Pin = gpio.pin_mask_; + HAL_GPIO_Init(gpio.port_, &GPIO_InitStruct); + } // Construct all objects. odCAN = new ODriveCAN(can_config, &hcan1); diff --git a/Firmware/MotorControl/odrive_main.h b/Firmware/MotorControl/odrive_main.h index ff194bea..dfc2f4ea 100644 --- a/Firmware/MotorControl/odrive_main.h +++ b/Firmware/MotorControl/odrive_main.h @@ -156,7 +156,6 @@ inline ENUMTYPE operator ~ (ENUMTYPE a) { return static_cast(~static_c // ODrive specific includes #include -#include #include #include #include @@ -176,6 +175,9 @@ extern const unsigned char fw_version_revision_; extern const unsigned char fw_version_unreleased_; } +static Stm32Gpio get_gpio(size_t gpio_num) { + return (gpio_num >= 1 && gpio_num <= GPIO_COUNT) ? gpios[gpio_num - 1] : GPIO_COUNT ? gpios[0] : Stm32Gpio::none; +} // general system functions defined in main.cpp class ODrive : public ODriveIntf { @@ -190,7 +192,7 @@ public: } float get_adc_voltage(uint32_t gpio) override { - return ::get_adc_voltage(get_gpio_port_by_pin(gpio), get_gpio_pin_by_pin(gpio)); + return ::get_adc_voltage(get_gpio(gpio)); } int32_t test_function(int32_t delta) override { diff --git a/Firmware/MotorControl/thermistor.cpp b/Firmware/MotorControl/thermistor.cpp index 5b1e425a..eb182420 100644 --- a/Firmware/MotorControl/thermistor.cpp +++ b/Firmware/MotorControl/thermistor.cpp @@ -72,8 +72,5 @@ OffboardThermistorCurrentLimiter::OffboardThermistorCurrentLimiter(Config_t& con } void OffboardThermistorCurrentLimiter::decode_pin() { - const GPIO_TypeDef* const port = get_gpio_port_by_pin(config_.gpio_pin); - const uint16_t pin = get_gpio_pin_by_pin(config_.gpio_pin); - - adc_channel_ = channel_from_gpio(port, pin); + adc_channel_ = channel_from_gpio(get_gpio(config_.gpio_pin)); } diff --git a/Firmware/communication/communication.cpp b/Firmware/communication/communication.cpp index c9eaa589..153d750c 100644 --- a/Firmware/communication/communication.cpp +++ b/Firmware/communication/communication.cpp @@ -11,7 +11,6 @@ #include "odrive_main.h" #include "freertos_vars.h" #include "utils.hpp" -#include "gpio_utils.hpp" #include #include