feat: enhance error handling and add device error reporting for radio operations

This commit is contained in:
2025-08-07 15:36:20 +08:00
parent 72299b62ce
commit 7637906efe
6 changed files with 101 additions and 47 deletions

View File

@ -255,24 +255,26 @@ get_packet_status() {
.raw = {data[0], data[1], data[2]}};
}
inline Result<op_error_t, error_t>
/**
* @note ignore any possible transmission errors
*/
inline Result<DeviceErrors, error_t>
get_device_errors() {
uint8_t data[] = {0x00, 0x00};
const auto res = spi::read_stream(RADIOLIB_SX126X_CMD_GET_DEVICE_ERRORS, data);
APP_RADIO_RETURN_ERR(res);
// assuming little endian (as most microcontrollers are)
uint16_t opError_le = data[0] << 8 | data[1];
auto opError = *reinterpret_cast<op_error_t *>(&opError_le);
return opError;
uint8_t data[] = {0x00, 0x00};
std::ignore = spi::read_stream(RADIOLIB_SX126X_CMD_GET_DEVICE_ERRORS, data);
uint16_t device_err_code = data[0] << 8 | data[1];
return *reinterpret_cast<DeviceErrors *>(&device_err_code);
}
/**
* \brief This commands clears all the errors recorded in the device. The errors can not be cleared independently.
* \note ignore any possible transmission errors
*/
inline Result<Unit, error_t>
clear_device_errors() {
constexpr uint8_t data[] = {RADIOLIB_SX126X_CMD_NOP, RADIOLIB_SX126X_CMD_NOP};
return spi::write_stream(RADIOLIB_SX126X_CMD_CLEAR_DEVICE_ERRORS, data);
std::ignore = spi::write_stream(RADIOLIB_SX126X_CMD_CLEAR_DEVICE_ERRORS, data);
return {};
}
/**
@ -296,7 +298,7 @@ inline constexpr uint32_t frequency_raw(const freq_t freq) {
inline Result<Unit, error_t>
set_frequency(freq_t freq, const bool calibrate = true) {
using f_t = decltype(freq);
if (!valid_freq(freq)) {
if (not valid_freq(freq)) {
return ue_t{error_t{error::RADIO_INVALID_FREQUENCY}};
}
if (calibrate) {
@ -322,13 +324,7 @@ set_frequency(freq_t freq, const bool calibrate = true) {
delay_ms(5);
}
static freq_t last_freq = 0;
static uint32_t raw_last_freq = 0;
if (last_freq != freq) {
last_freq = freq;
raw_last_freq = frequency_raw(freq);
}
return set_rf_frequency(raw_last_freq);
return set_rf_frequency(frequency_raw(freq));
}
inline Result<uint8_t, error_t>
@ -1232,6 +1228,19 @@ static constexpr auto init_pins = [](void (*isr)(void *), void *arg) {
init_tx_rx_en();
};
inline Result<Unit, error_t> get_device_error_print_and_clear(const char *tag) {
auto res = get_device_errors();
if (not res) {
return ue_t{res.error()};
}
if (res->has_any_error()) {
ESP_LOGE(tag, "%s", res->to_string().c_str());
} else {
ESP_LOGI(tag, "no device errors");
}
return clear_device_errors();
}
static constexpr auto begin = [](const lora_parameters_t &params) -> Result<Unit, error_t> {
/**
* Most of the commands can be sent in any order except for the radio configuration commands which will set the radio in
@ -1297,6 +1306,7 @@ static constexpr auto begin = [](const lora_parameters_t &params) -> Result<Unit
mod_params.bw,
mod_params.cr,
mod_params.ldr_optimize);
res = get_device_error_print_and_clear(TAG);
APP_RADIO_RETURN_ERR_CTX(res, "set modulation params");
res = set_lora_sync_word(params.sync_word);
@ -1313,8 +1323,10 @@ static constexpr auto begin = [](const lora_parameters_t &params) -> Result<Unit
#ifdef APP_RADIO_DISABLE_CALIBRATION
res = set_frequency(params.frequency, false);
res = get_device_error_print_and_clear(TAG);
#else
res = set_frequency(params.frequency, true);
res = get_device_error_print_and_clear(TAG);
#endif /* APP_RADIO_DISABLE_CALIBRATION */
APP_RADIO_RETURN_ERR_CTX(res, "set frequency");