[lightwaverf] Fix ISR safety issues (#14563)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jonathan Swoboda
2026-03-06 16:04:12 -05:00
committed by GitHub
parent 5777908da7
commit de7572bd3e
4 changed files with 17 additions and 8 deletions
+11 -3
View File
@@ -8,6 +8,7 @@
#include "LwRx.h"
#include <cstring>
#include "esphome/core/helpers.h"
namespace esphome {
namespace lightwaverf {
@@ -185,13 +186,20 @@ bool LwRx::lwrx_getmessage(uint8_t *buf, uint8_t len) {
bool ret = true;
int16_t j = 0; // int
if (this->rx_msgcomplete && len <= RX_MSGLEN) {
// Copy message under interrupt lock to prevent ISR overwriting rx_msg mid-read
uint8_t msg_copy[RX_MSGLEN];
{
InterruptLock lock;
memcpy(msg_copy, this->rx_msg, RX_MSGLEN);
this->rx_msgcomplete = false;
}
for (uint8_t i = 0; ret && i < RX_MSGLEN; i++) {
if (this->rx_translate || (len != RX_MSGLEN)) {
j = this->rx_find_nibble_(this->rx_msg[i]);
j = this->rx_find_nibble_(msg_copy[i]);
if (j < 0)
ret = false;
} else {
j = this->rx_msg[i];
j = msg_copy[i];
}
switch (len) {
case 4:
@@ -199,6 +207,7 @@ bool LwRx::lwrx_getmessage(uint8_t *buf, uint8_t len) {
buf[2] = j;
if (i == 2)
buf[3] = j;
[[fallthrough]];
case 2:
if (i == 3)
buf[0] = j;
@@ -212,7 +221,6 @@ bool LwRx::lwrx_getmessage(uint8_t *buf, uint8_t len) {
break;
}
}
this->rx_msgcomplete = false;
} else {
ret = false;
}
+2 -2
View File
@@ -105,8 +105,8 @@ class LwRx {
uint32_t rx_prev; // time of previous interrupt in microseconds
bool rx_msgcomplete = false; // set high when message available
bool rx_translate = true; // Set false to get raw data
volatile bool rx_msgcomplete = false; // set high when message available
bool rx_translate = true; // Set false to get raw data
uint8_t rx_state = 0;
+2 -1
View File
@@ -192,7 +192,8 @@ void LwTx::lwtx_set_gap_multiplier(uint8_t gap_multiplier) { this->tx_gap_multip
void LwTx::lw_timer_start() {
{
InterruptLock lock;
static LwTx *arg = this; // NOLINT
static LwTx *arg;
arg = this;
timer1_attachInterrupt([] { isr_t_xtimer(arg); });
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
timer1_write(this->espPeriod);
+2 -2
View File
@@ -62,8 +62,8 @@ class LwTx {
uint8_t tx_repeats = 12; // Number of repeats of message sent
uint8_t txon = 1;
uint8_t txoff = 0;
bool tx_msg_active = false; // set true to activate message sending
bool tx_translate = true; // Set false to send raw data
volatile bool tx_msg_active = false; // set true to activate message sending
bool tx_translate = true; // Set false to send raw data
uint8_t tx_buf[TX_MSGLEN]; // the message buffer during reception
uint8_t tx_repeat = 0; // counter for repeats