From 7d80e564f0ac9a664bcb0afc6dabe809605306ef Mon Sep 17 00:00:00 2001 From: EmanuelFeru Date: Sat, 21 Mar 2020 19:24:29 +0100 Subject: [PATCH] First commit pwm - buttons not yet support --- Inc/config.h | 29 +++++++++- Inc/defines.h | 7 ++- Src/control.c | 139 +++++++++++++++++++++++++++++++++++++++++++++ Src/main.c | 8 +++ Src/stm32f1xx_it.c | 24 ++++++++ Src/util.c | 19 +++++++ platformio.ini | 20 +++++++ 7 files changed, 243 insertions(+), 3 deletions(-) diff --git a/Inc/config.h b/Inc/config.h index 8687389..c45c561 100644 --- a/Inc/config.h +++ b/Inc/config.h @@ -14,6 +14,7 @@ //#define VARIANT_USART // Variant for Serial control via USART3 input //#define VARIANT_NUNCHUK // Variant for Nunchuk controlled vehicle build //#define VARIANT_PPM // Variant for RC-Remote with PPM-Sum Signal + //#define VARIANT_PWM // Variant for RC-Remote with PWM Signal //#define VARIANT_IBUS // Variant for RC-Remotes with FLYSKY IBUS //#define VARIANT_HOVERCAR // Variant for HOVERCAR build //#define VARIANT_HOVERBOARD // Variant for HOVERBOARD build @@ -276,6 +277,30 @@ // ############################# END OF VARIANT_PPM SETTINGS ############################ +// ################################# VARIANT_PWM SETTINGS ############################## +#ifdef VARIANT_PWM +/* ###### CONTROL VIA RC REMOTE ###### + * left sensor board cable. Connect PA2 to channel 1 and PA3 to channel 2 on receiver. + * Channel 1: steering, Channel 2: speed. +*/ + #define CONTROL_PWM // use RC PWM as input. disable DEBUG_SERIAL_USART2! + #define PWM_DEADBAND 100 // How much of the center position is considered 'center' (100 = values -100 to 100 are considered 0) + // Min / Max values of each channel (use DEBUG to determine these values) + #define PWM_CH1_MAX 1000 // (0 - 1000) + #define PWM_CH1_MIN -1000 // (-1000 - 0) + #define PWM_CH2_MAX 500 // (0 - 1000) + #define PWM_CH2_MIN -800 // (-1000 - 0) + // right sensor board cable. Only read once during startup + #define BUTTONS_RIGHT // use right sensor board cable for button inputs. Disable DEBUG_SERIAL_USART3! + #define FILTER 6553 // 0.1f [-] fixdt(0,16,16) lower value == softer filter [0, 65535] = [0.0 - 1.0]. + #define SPEED_COEFFICIENT 16384 // 1.0f [-] fixdt(1,16,14) higher value == stronger. [0, 65535] = [-2.0 - 2.0]. In this case 16384 = 1.0 * 2^14 + #define STEER_COEFFICIENT 0 // 0.0f [-] fixdt(1,16,14) higher value == stronger. [0, 65535] = [-2.0 - 2.0]. In this case 0 = 0.0 * 2^14. If you do not want any steering, set it to 0. + // #define INVERT_R_DIRECTION + // #define INVERT_L_DIRECTION +#endif +// ############################# END OF VARIANT_PPM SETTINGS ############################ + + // ################################# VARIANT_IBUS SETTINGS ############################## #ifdef VARIANT_IBUS @@ -402,8 +427,8 @@ // ############################### VALIDATE SETTINGS ############################### -#if !defined(VARIANT_ADC) && !defined(VARIANT_USART) && !defined(VARIANT_NUNCHUK) && !defined(VARIANT_PPM) && !defined(VARIANT_IBUS) && \ - !defined(VARIANT_HOVERCAR) && !defined(VARIANT_HOVERBOARD) && !defined(VARIANT_TRANSPOTTER) +#if !defined(VARIANT_ADC) && !defined(VARIANT_USART) && !defined(VARIANT_NUNCHUK) && !defined(VARIANT_PPM) && !defined(VARIANT_PWM) && \ + !defined(VARIANT_IBUS) && !defined(VARIANT_HOVERCAR) && !defined(VARIANT_HOVERBOARD) && !defined(VARIANT_TRANSPOTTER) #error Variant not defined! Please check platformio.ini or Inc/config.h for available variants. #endif diff --git a/Inc/defines.h b/Inc/defines.h index fd3e0b8..b8bbcd6 100644 --- a/Inc/defines.h +++ b/Inc/defines.h @@ -160,13 +160,18 @@ typedef struct { uint16_t l_rx2; } adc_buf_t; -// Define I2C, Nunchuk, PPM functions +// Define I2C, Nunchuk, PPM, PWM functions void I2C_Init(void); void Nunchuk_Init(void); void Nunchuk_Read(void); uint8_t Nunchuk_Ping(void); void PPM_Init(void); void PPM_ISR_Callback(void); +void PWM_Init(void); +//void PWM_ISR_CH1_Callback(void); +void PWM_ISR_CH2_Callback(void); +void PWM_SysTick_Callback(void); +int PWM_Signal_Correct(int16_t x, int16_t max, int16_t min); // Sideboard definitions #define LED1_SET (0x01) diff --git a/Src/control.c b/Src/control.c index 7a40aa3..d80ba35 100644 --- a/Src/control.c +++ b/Src/control.c @@ -7,7 +7,9 @@ #include "config.h" TIM_HandleTypeDef TimHandle; +TIM_HandleTypeDef TimHandle2; uint8_t ppm_count = 0; +uint8_t pwm_count = 0; uint32_t timeout = 100; uint8_t nunchuk_data[6] = {0}; @@ -84,6 +86,143 @@ void PPM_Init(void) { } #endif + +#ifdef BUTTONS_RIGHT + +uint8_t btn1 = 0; +uint8_t btn2 = 0; + +void BUTTONS_RIGHT_Init() { + GPIO_InitTypeDef GPIO_InitStruct; + /*Configure GPIO pin : PB10 */ + GPIO_InitStruct.Pin = GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + btn1 = !HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10); + + GPIO_InitTypeDef GPIO_InitStruct2; + /*Configure GPIO pin : PB11 */ + GPIO_InitStruct2.Pin = GPIO_PIN_11; + GPIO_InitStruct2.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct2.Speed = GPIO_SPEED_FREQ_MEDIUM; + GPIO_InitStruct2.Pull = GPIO_PULLUP; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct2); + + btn2 = !HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11); +} + +#endif + +#ifdef CONTROL_PWM +//uint16_t pwm_captured_ch1_value = 500; +uint16_t pwm_captured_ch2_value = 500; +uint32_t pwm_timeout = 0; + +#define IN_RANGE(x, low, up) (((x) >= (low)) && ((x) <= (up))) + +int PWM_Signal_Correct(int16_t x, int16_t max, int16_t min) { + int outVal = 0; + if(x > -PWM_DEADBAND && x < PWM_DEADBAND) { + outVal = 0; + } else if(x > 0) { + outVal = (float)CLAMP(x-PWM_DEADBAND, 0, max - PWM_DEADBAND) / (max - PWM_DEADBAND) * 1000; + } else { + outVal = 0 - ((float)CLAMP(x+PWM_DEADBAND, min + PWM_DEADBAND, 0) / (min + PWM_DEADBAND) * 1000); + } + return outVal; +} + +/* +void PWM_ISR_CH1_Callback(void) { + // Dummy loop with 16 bit count wrap around + uint16_t rc_signal = TIM3->CNT; + TIM3->CNT = 0; + + if (IN_RANGE(rc_signal, 900, 2100)){ + timeout = 0; + pwm_timeout = 0; + pwm_captured_ch1_value = CLAMP(rc_signal, 1000, 2000) - 1000; + } +} +*/ + +void PWM_ISR_CH2_Callback(void) { + // Dummy loop with 16 bit count wrap around + uint16_t rc_signal = TIM2->CNT; + TIM2->CNT = 0; + + if (IN_RANGE(rc_signal, 900, 2100)){ + timeout = 0; + pwm_timeout = 0; + pwm_captured_ch2_value = CLAMP(rc_signal, 1000, 2000) - 1000; + } +} + +// SysTick executes once each ms +void PWM_SysTick_Callback(void) { + pwm_timeout++; + // Stop after 500 ms without PPM signal + if(pwm_timeout > 500) { + //pwm_captured_ch1_value = 500; + pwm_captured_ch2_value = 500; + pwm_timeout = 0; + } +} + +void PWM_Init(void) { + // Channel 1 (steering) + /* + GPIO_InitTypeDef GPIO_InitStruct2; + // Configure GPIO pin : PA2 + GPIO_InitStruct2.Pin = GPIO_PIN_2; + GPIO_InitStruct2.Mode = GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct2.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct2.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct2); + + __HAL_RCC_TIM3_CLK_ENABLE(); + TimHandle2.Instance = TIM3; + TimHandle2.Init.Period = UINT16_MAX; + TimHandle2.Init.Prescaler = (SystemCoreClock/DELAY_TIM_FREQUENCY_US)-1;; + TimHandle2.Init.ClockDivision = 0; + TimHandle2.Init.CounterMode = TIM_COUNTERMODE_UP; + HAL_TIM_Base_Init(&TimHandle2); + + // EXTI interrupt init + HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(EXTI2_IRQn); + HAL_TIM_Base_Start(&TimHandle2); +*/ + + // Channel 2 (speed) + + GPIO_InitTypeDef GPIO_InitStruct; + /*Configure GPIO pin : PA3 */ + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + __HAL_RCC_TIM2_CLK_ENABLE(); + TimHandle.Instance = TIM2; + TimHandle.Init.Period = UINT16_MAX; + TimHandle.Init.Prescaler = (SystemCoreClock/DELAY_TIM_FREQUENCY_US)-1;; + TimHandle.Init.ClockDivision = 0; + TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + HAL_TIM_Base_Init(&TimHandle); + + /* EXTI interrupt init*/ + HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(EXTI3_IRQn); + HAL_TIM_Base_Start(&TimHandle); +} +#endif + + uint8_t Nunchuk_Ping(void) { if (HAL_I2C_Master_Receive(&hi2c2,0xA4,(uint8_t*)nunchuk_data, 1, 10) == HAL_OK) { return 1; diff --git a/Src/main.c b/Src/main.c index e0b48f8..446ee58 100644 --- a/Src/main.c +++ b/Src/main.c @@ -82,6 +82,10 @@ extern SerialSideboard Sideboard_L; #if defined(SIDEBOARD_SERIAL_USART3) extern SerialSideboard Sideboard_R; #endif +#if defined(CONTROL_PWM) && defined(DEBUG_SERIAL_USART3) +//extern volatile uint16_t pwm_captured_ch1_value; +extern volatile uint16_t pwm_captured_ch2_value; +#endif //------------------------------------------------------------------------ @@ -381,6 +385,10 @@ int main(void) { setScopeChannel(0, (int16_t)adc_buffer.l_tx2); // 1: ADC1 setScopeChannel(1, (int16_t)adc_buffer.l_rx2); // 2: ADC2 #endif + #ifdef CONTROL_PWM + setScopeChannel(0, 0);//pwm_captured_ch1_value); // 1: CH1 + setScopeChannel(1, pwm_captured_ch2_value); // 2: CH2 + #endif setScopeChannel(2, (int16_t)speedR); // 3: output command: [-1000, 1000] setScopeChannel(3, (int16_t)speedL); // 4: output command: [-1000, 1000] setScopeChannel(4, (int16_t)adc_buffer.batt1); // 5: for battery voltage calibration diff --git a/Src/stm32f1xx_it.c b/Src/stm32f1xx_it.c index 40fb78d..2f69f7c 100644 --- a/Src/stm32f1xx_it.c +++ b/Src/stm32f1xx_it.c @@ -165,6 +165,11 @@ void PendSV_Handler(void) { #ifdef CONTROL_PPM void PPM_SysTick_Callback(void); #endif + +#ifdef CONTROL_PWM +void PWM_SysTick_Callback(void); +#endif + void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ @@ -175,6 +180,10 @@ void SysTick_Handler(void) { #ifdef CONTROL_PPM PPM_SysTick_Callback(); #endif + +#ifdef CONTROL_PWM + PWM_SysTick_Callback(); +#endif /* USER CODE END SysTick_IRQn 1 */ } @@ -227,6 +236,21 @@ void EXTI3_IRQHandler(void) } #endif +#ifdef CONTROL_PWM +void EXTI3_IRQHandler(void) +{ + PWM_ISR_CH2_Callback(); + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_3); +} +/* +void EXTI2_IRQHandler(void) +{ + PWM_ISR_CH1_Callback(); + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_2); +}*/ + +#endif + #ifdef CONTROL_SERIAL_USART2 void DMA1_Channel6_IRQHandler(void) { diff --git a/Src/util.c b/Src/util.c index 2db082c..314f7f2 100644 --- a/Src/util.c +++ b/Src/util.c @@ -63,6 +63,16 @@ extern volatile uint32_t main_loop_counter; extern volatile uint16_t ppm_captured_value[PPM_NUM_CHANNELS+1]; #endif +#ifdef CONTROL_PWM +//extern volatile uint16_t pwm_captured_ch1_value; +extern volatile uint16_t pwm_captured_ch2_value; +#endif + +#ifdef BUTTONS_RIGHT +extern volatile uint8_t btn1; // Blue +extern volatile uint8_t btn2; // Green +#endif + //------------------------------------------------------------------------ // Global variables set here in util.c @@ -236,6 +246,10 @@ void Input_Init(void) { PPM_Init(); #endif + #ifdef CONTROL_PWM + PWM_Init(); + #endif + #ifdef CONTROL_NUNCHUK I2C_Init(); Nunchuk_Init(); @@ -634,6 +648,11 @@ void readCommand(void) { // float scale = ppm_captured_value[2] / 1000.0f; // not used for now, uncomment if needed #endif + #ifdef CONTROL_PWM + cmd1 = 0; // CLAMP(PWM_Signal_Correct((pwm_captured_ch1_value - 500) * 2, PWM_CH1_MAX, PWM_CH1_MIN), INPUT_MIN, INPUT_MAX); + cmd2 = CLAMP(PWM_Signal_Correct((pwm_captured_ch2_value - 500) * 2, PWM_CH2_MAX, PWM_CH2_MIN), INPUT_MIN, INPUT_MAX); + #endif + #ifdef CONTROL_ADC // ADC values range: 0-4095, see ADC-calibration in config.h #ifdef ADC1_MID_POT diff --git a/platformio.ini b/platformio.ini index 4570825..a910d93 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,6 +13,7 @@ src_dir = Src ;default_envs = VARIANT_USART ; Variant for Serial control via USART3 input ;default_envs = VARIANT_NUNCHUK ; Variant for Nunchuk controlled vehicle build ;default_envs = VARIANT_PPM ; Variant for RC-Remotes with PPM-Sum signal +default_envs = VARIANT_PWM ; Variant for RC-Remotes with PWM signal ;default_envs = VARIANT_IBUS ; Variant for RC-Remotes with FLYSKY IBUS ;default_envs = VARIANT_HOVERCAR ; Variant for HOVERCAR build ;default_envs = VARIANT_HOVERBOARD ; Variant for HOVERBOARD @@ -105,6 +106,25 @@ build_flags = ;================================================================ +[env:VARIANT_PWM] +platform = ststm32 +framework = stm32cube +board = genericSTM32F103RC +debug_tool = stlink +upload_protocol = stlink + +build_flags = + -DUSE_HAL_DRIVER + -DSTM32F103xE + -Wl,-T./STM32F103RCTx_FLASH.ld + -Wl,-lc + -Wl,-lm + -g -ggdb ; to generate correctly the 'firmware.elf' for STM STUDIO vizualization +# -Wl,-lnosys + -D VARIANT_PWM + +;================================================================ + [env:VARIANT_IBUS] platform = ststm32 framework = stm32cube