From 5f2eb196af640425b07e4c44b5ef823f1bdea96d Mon Sep 17 00:00:00 2001 From: EmanuelFeru Date: Tue, 23 Jun 2020 19:58:36 +0200 Subject: [PATCH] Improved UART error recovery - In case of an Rx error instead of stopping the complete UART, only the Rx DMA is aborted and restarted. --- Inc/config.h | 2 +- Inc/defines.h | 3 ++- Inc/util.h | 5 +++- Src/util.c | 63 ++++++++++++++++++++++++++++++++++----------------- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/Inc/config.h b/Inc/config.h index 86fbe40..dad170e 100644 --- a/Inc/config.h +++ b/Inc/config.h @@ -396,8 +396,8 @@ #if defined(FEEDBACK_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) || \ defined(FEEDBACK_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3) #define SERIAL_START_FRAME 0xABCD // [-] Start frame definition for serial commands - #define SERIAL_TIMEOUT 160 // [-] Serial timeout duration for the received data. 160 ~= 0.8 sec. Calculation: 0.8 sec / 0.005 sec #define SERIAL_BUFFER_SIZE 64 // [bytes] Size of Serial Rx buffer. Make sure it is always larger than the structure size + #define SERIAL_TIMEOUT 160 // [-] Serial timeout duration for the received data. 160 ~= 0.8 sec. Calculation: 0.8 sec / 0.005 sec #endif #if defined(FEEDBACK_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) #ifndef USART2_BAUD diff --git a/Inc/defines.h b/Inc/defines.h index 0371729..3a1942b 100644 --- a/Inc/defines.h +++ b/Inc/defines.h @@ -24,6 +24,7 @@ #define DEFINES_H #include "stm32f1xx_hal.h" +#include "config.h" #define LEFT_HALL_U_PIN GPIO_PIN_5 #define LEFT_HALL_V_PIN GPIO_PIN_6 @@ -188,5 +189,5 @@ void PWM_ISR_CH2_Callback(void); #define SENSOR2_SET (0x02) #define SENSOR_MPU (0x04) -#endif +#endif // DEFINES_H diff --git a/Inc/util.h b/Inc/util.h index a7f9abb..30ac113 100644 --- a/Inc/util.h +++ b/Inc/util.h @@ -23,6 +23,8 @@ #include + +// Rx Structures USART #if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3) #ifdef CONTROL_IBUS typedef struct{ @@ -66,6 +68,7 @@ void calcAvgSpeed(void); void adcCalibLim(void); void updateCurSpdLim(void); void saveConfig(void); +int addDeadBand(int16_t u, int16_t deadBand, int16_t min, int16_t max); // Poweroff Functions void poweroff(void); @@ -84,7 +87,7 @@ void usart_process_command(SerialCommand *command_in, SerialCommand *command_out #if defined(SIDEBOARD_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART3) void usart_process_sideboard(SerialSideboard *Sideboard_in, SerialSideboard *Sideboard_out, uint8_t usart_idx); #endif -int addDeadBand(int16_t u, int16_t deadBand, int16_t min, int16_t max); +void UART_EndRxTransfer(UART_HandleTypeDef *huart); // Sideboard functions void sideboardLeds(uint8_t *leds); diff --git a/Src/util.c b/Src/util.c index dbed0fa..c79b630 100644 --- a/Src/util.c +++ b/Src/util.c @@ -156,6 +156,7 @@ static int16_t timeoutCntADC = 0; // Timeout counter for ADC Protection #if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) static uint8_t rx_buffer_L[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer static uint32_t rx_buffer_L_len = ARRAY_LEN(rx_buffer_L); +static uint32_t old_pos; #endif #if defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) static uint16_t timeoutCntSerial_L = 0; // Timeout counter for Rx Serial command @@ -170,6 +171,7 @@ static uint32_t Sideboard_L_len = sizeof(Sideboard_L); #if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3) static uint8_t rx_buffer_R[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer static uint32_t rx_buffer_R_len = ARRAY_LEN(rx_buffer_R); +static uint32_t old_pos; #endif #if defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3) static uint16_t timeoutCntSerial_R = 0; // Timeout counter for Rx Serial command @@ -548,6 +550,26 @@ void saveConfig() { #endif } + /* + * Add Dead-band to a signal + * This function realizes a dead-band around 0 and scales the input within a min and a max + */ +int addDeadBand(int16_t u, int16_t deadBand, int16_t min, int16_t max) { +#if defined(CONTROL_PPM) || defined(CONTROL_PWM) + int outVal = 0; + if(u > -deadBand && u < deadBand) { + outVal = 0; + } else if(u > 0) { + outVal = (INPUT_MAX * CLAMP(u - deadBand, 0, max - deadBand)) / (max - deadBand); + } else { + outVal = (INPUT_MIN * CLAMP(u + deadBand, min + deadBand, 0)) / (min + deadBand); + } + return outVal; +#else + return 0; +#endif +} + /* =========================== Poweroff Functions =========================== */ @@ -776,8 +798,7 @@ void readCommand(void) { */ void usart2_rx_check(void) { - #if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) - static uint32_t old_pos; + #if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) uint32_t pos; pos = rx_buffer_L_len - __HAL_DMA_GET_COUNTER(huart2.hdmarx); // Calculate current position in buffer #endif @@ -847,7 +868,6 @@ void usart2_rx_check(void) void usart3_rx_check(void) { #if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3) - static uint32_t old_pos; uint32_t pos; pos = rx_buffer_R_len - __HAL_DMA_GET_COUNTER(huart3.hdmarx); // Calculate current position in buffer #endif @@ -1014,35 +1034,36 @@ void usart_process_sideboard(SerialSideboard *Sideboard_in, SerialSideboard *Sid void HAL_UART_ErrorCallback(UART_HandleTypeDef *uartHandle) { #if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) if(uartHandle->Instance == USART2) { + HAL_DMA_Abort(uartHandle->hdmarx); + UART_EndRxTransfer(uartHandle); HAL_UART_Receive_DMA(uartHandle, (uint8_t *)rx_buffer_L, sizeof(rx_buffer_L)); + old_pos = 0; } #endif #if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3) if(uartHandle->Instance == USART3) { + HAL_DMA_Abort(uartHandle->hdmarx); + UART_EndRxTransfer(uartHandle); HAL_UART_Receive_DMA(uartHandle, (uint8_t *)rx_buffer_R, sizeof(rx_buffer_R)); + old_pos = 0; } #endif } +/** + * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). + * @param huart: UART handle. + * @retval None + */ +void UART_EndRxTransfer(UART_HandleTypeDef *huart) +{ + /* Disable RXNE (Interrupt Enable) and PE (Parity Error) interrupts */ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + /* Disable EIE (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); - /* - * Add Dead-band to a signal - * This function realizes a dead-band around 0 and scales the input within a min and a max - */ -int addDeadBand(int16_t u, int16_t deadBand, int16_t min, int16_t max) { -#if defined(CONTROL_PPM) || defined(CONTROL_PWM) - int outVal = 0; - if(u > -deadBand && u < deadBand) { - outVal = 0; - } else if(u > 0) { - outVal = (INPUT_MAX * CLAMP(u - deadBand, 0, max - deadBand)) / (max - deadBand); - } else { - outVal = (INPUT_MIN * CLAMP(u + deadBand, min + deadBand, 0)) / (min + deadBand); - } - return outVal; -#else - return 0; -#endif + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; }