Improved UART error recovery

- In case of an Rx error instead of stopping the complete UART, only the Rx DMA is aborted and restarted.
This commit is contained in:
EmanuelFeru 2020-06-23 19:58:36 +02:00
parent ac90ed1b6b
commit 5f2eb196af
4 changed files with 49 additions and 24 deletions

View File

@ -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

View File

@ -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

View File

@ -23,6 +23,8 @@
#include <stdint.h>
// 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);

View File

@ -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 =========================== */
@ -777,7 +799,6 @@ 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;
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;
}