fix: Various mostly X10E soft serial issues (#3382)

* fix: pulse driver with 32bit timers

* fix(mpm): clear RX buffer before signature

* fix: add some debouncing on soft-serial start bit detection

This helps coping with spurious impulses on S.PORT created by payload sent over PPM pin (X10E).

* fix: whenever the RXNE bit is set, read the register

... regardless of errors. That allows for reducing the effect of detected errors.
This commit is contained in:
Raphael Coeffic
2023-03-26 11:23:32 +10:00
committed by GitHub
parent 8560c1f6bf
commit e016598b56
4 changed files with 21 additions and 7 deletions
+2
View File
@@ -233,6 +233,8 @@ const char * MultiFirmwareUpdateDriver::waitForInitialSync()
const char * MultiFirmwareUpdateDriver::getDeviceSignature(uint8_t * signature) const
{
clear();
// Read signature
sendByte(STK_READ_SIGN);
sendByte(CRC_EOP);
@@ -70,7 +70,11 @@ void stm32_pulse_init(const stm32_pulse_timer_t* tim, uint32_t freq)
}
timInit.Prescaler = __LL_TIM_CALC_PSC(tim->TIM_Freq, freq);
timInit.Autoreload = STM32_DEFAULT_TIMER_AUTORELOAD;
if (IS_TIM_32B_COUNTER_INSTANCE(tim->TIMx)) {
timInit.Autoreload = 0xFFFFFFFFUL;
} else {
timInit.Autoreload = STM32_DEFAULT_TIMER_AUTORELOAD;
}
enable_tim_clock(tim->TIMx);
LL_TIM_Init(tim->TIMx, &timInit);
@@ -43,14 +43,21 @@ static const stm32_softserial_rx_port* _softserialPort;
static void _softserial_exti()
{
if (rxBitCount == 0) {
auto port = _softserialPort;
// cheap debouncing...
for (uint8_t i = 0; i < 16; ++i) {
if (LL_GPIO_IsInputPinSet(port->GPIOx, port->GPIO_Pin) == 0)
return;
}
// enable timer counter
auto TIMx = _softserialPort->TIMx;
auto TIMx = port->TIMx;
LL_TIM_SetAutoReload(TIMx, (BITLEN + BITLEN/2) - 1);
LL_TIM_EnableCounter(TIMx);
// disable start bit interrupt
LL_EXTI_DisableIT_0_31(_softserialPort->EXTI_Line);
LL_EXTI_DisableIT_0_31(port->EXTI_Line);
}
}
@@ -557,14 +557,15 @@ void stm32_usart_isr(const stm32_usart_t* usart, etx_serial_callbacks_t* cb)
// Drain RX
while (status & (LL_USART_SR_RXNE | USART_FLAG_ERRORS)) {
// This will clear the RXNE bit in USART_DR register
uint8_t data = LL_USART_ReadReg(usart->USARTx, DR);
if (status & USART_FLAG_ERRORS) {
if (cb->on_error)
cb->on_error();
}
else {
if (status & LL_USART_SR_RXNE) {
// This will clear the RXNE bit in USART_DR register
uint8_t data = LL_USART_ReadReg(usart->USARTx, DR);
if (cb->on_receive)
cb->on_receive(data);
}