Hi,
There is an issue that rx done or rx timeout irq never fires after header valid irq came when the node try to RX so mac state check timer keeps expiring.
This happens sometimes when it is running rx sensitivity test with repeating echo request / response usually with relatively low signal.
Here is the irq handler code I am using like below. I guess it could be fixed with a software timer for rx but I don’t understand why lora chip is stuck after header valid irq fires. Also, I need to make sure if it can happen with sx1262 (any history or known issue?) or if the code could has a potential problem related to the issue.
void SX126X_LoRaRadio::handle_dio1_irq()
{
uint16_t irq_status = get_irq_status();
clear_irq_status(IRQ_RADIO_ALL);
if ((irq_status & IRQ_TX_DONE) == IRQ_TX_DONE) {
if (_radio_events->tx_done) {
_radio_events->tx_done();
}
}
if ((irq_status & IRQ_RX_DONE) == IRQ_RX_DONE) {
if ((irq_status & IRQ_CRC_ERROR) == IRQ_CRC_ERROR) {
if (_radio_events && _radio_events->rx_error) {
_radio_events->rx_error();
}
} else {
if (_radio_events->rx_done) {
uint8_t offset = 0;
uint8_t payload_len = 0;
int16_t rssi = 0;
int8_t snr = 0;
packet_status_t pkt_status;
// from https://github.com/Lora-net/LoRaMac-node/releases/tag/v4.5.1
// WORKAROUND - Implicit Header Mode Timeout Behavior, see DS_SX1261-2_V1.2 datasheet chapter 15.3
// RegRtcControl = @address 0x0902
write_to_register(0x0902, 0x00);
// RegEventMask = @address 0x0944
write_to_register(0x0944, read_register(0x0944) | (1 << 1));
// WORKAROUND END
get_rx_buffer_status(&payload_len, &offset);
read_fifo(_data_buffer, payload_len, offset);
get_packet_status(&pkt_status);
if (pkt_status.modem_type == MODEM_FSK) {
rssi = pkt_status.params.gfsk.rssi_sync;
} else {
rssi = pkt_status.params.lora.rssi_pkt;
snr = pkt_status.params.lora.snr_pkt;
}
_radio_events->rx_done(_data_buffer, payload_len, rssi, snr);
}
}
}
if((irq_status & IRQ_HEADER_VALID) == IRQ_HEADER_VALID)
{
if(_radio_events->rx_valid)
{
_radio_events->rx_valid();
}
}
if ((irq_status & IRQ_CAD_DONE) == IRQ_CAD_DONE) {
if (_radio_events->cad_done) {
_radio_events->cad_done((irq_status & IRQ_CAD_ACTIVITY_DETECTED)
== IRQ_CAD_ACTIVITY_DETECTED);
}
}
if ((irq_status & IRQ_RX_TX_TIMEOUT) == IRQ_RX_TX_TIMEOUT) {
if ((_radio_events->tx_timeout) && (_operation_mode == MODE_TX)) {
_radio_events->tx_timeout();
} else if ((_radio_events && _radio_events->rx_timeout) && (_operation_mode == MODE_RX)) {
_radio_events->rx_timeout();
}
}
}