From 72299b62ce4ede7f9bc724b4d76627417852fa50 Mon Sep 17 00:00:00 2001 From: crosstyan Date: Thu, 7 Aug 2025 14:51:57 +0800 Subject: [PATCH] feat: add option to disable radio calibration and update status error handling --- CMakeLists.txt | 7 ++++++- inc/hal_error.hpp | 7 +++++-- inc/hal_spi.hpp | 38 +++++++++++++++++++++++++++----------- inc/llcc68.hpp | 26 ++++++++++++++++---------- inc/llcc68_definitions.hpp | 2 ++ src/hal_spi.cpp | 2 +- 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b1b6b8..eee94d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,12 @@ idf_component_register( ) # This option would make LLCC68 ignore `SPI_CMD_INVALID` error. -option(APP_SPI_DISABLE_INVALID_STATUS_CHECK "Disable invalid status check" ON) +option(APP_SPI_DISABLE_INVALID_STATUS_CHECK "Disable invalid status check" OFF) if (APP_SPI_DISABLE_INVALID_STATUS_CHECK) target_compile_definitions(${COMPONENT_LIB} PUBLIC APP_SPI_DISABLE_INVALID_STATUS_CHECK) endif() +option(APP_RADIO_DISABLE_CALIBRATION "Disable radio calibration" ON) +if (APP_RADIO_DISABLE_CALIBRATION) + target_compile_definitions(${COMPONENT_LIB} PUBLIC APP_RADIO_DISABLE_CALIBRATION) +endif() + diff --git a/inc/hal_error.hpp b/inc/hal_error.hpp index 95b3db8..37e26f0 100644 --- a/inc/hal_error.hpp +++ b/inc/hal_error.hpp @@ -3,7 +3,8 @@ #include #include -#define APP_ERR_TBL_IT(err) {err, #err} +#define APP_ERR_TBL_IT(err) \ + { err, #err } namespace app::driver::hal::error { using t = int; @@ -40,7 +41,8 @@ constexpr t SPI_TIMEOUT = SPI_ERR_BASE + 2; constexpr t SPI_CMD_INVALID = SPI_ERR_BASE + 3; // The command was successfully processed, however the chip could not execute the command; // for instance it was unable to enter the specified device mode or send the requested data -constexpr t SPI_CMD_FAILED = SPI_ERR_BASE + 4; +constexpr t SPI_CMD_FAILED = SPI_ERR_BASE + 4; +constexpr t SPI_INVALID_RADIO_STATE = SPI_ERR_BASE + 5; /*!< Radio is in an invalid state for the requested operation */ constexpr t RADIO_ERR_BASE = 0x1'3000; constexpr t RADIO_CHIP_NOT_FOUND = RADIO_ERR_BASE + 1; @@ -76,6 +78,7 @@ constexpr auto error_table = std::to_array>( APP_ERR_TBL_IT(SPI_TIMEOUT), APP_ERR_TBL_IT(SPI_CMD_INVALID), APP_ERR_TBL_IT(SPI_CMD_FAILED), + APP_ERR_TBL_IT(SPI_INVALID_RADIO_STATE), APP_ERR_TBL_IT(RADIO_CHIP_NOT_FOUND), APP_ERR_TBL_IT(RADIO_INVALID_TCXO_VOLTAGE), diff --git a/inc/hal_spi.hpp b/inc/hal_spi.hpp index b79560d..6ef56ec 100644 --- a/inc/hal_spi.hpp +++ b/inc/hal_spi.hpp @@ -47,21 +47,37 @@ void init(spi_config_t config = {SPI2_HOST, 4'000'000}); inline error_t status_to_err(const uint8_t status) { - const auto st = *reinterpret_cast(&status); - switch (st.command_status) { - case llcc68::CommandStatus::COMMAND_TIMEOUT: - return error::SPI_TIMEOUT; - case llcc68::CommandStatus::FAILURE_TO_EXECUTE_COMMAND: - return error::SPI_CMD_FAILED; - case llcc68::CommandStatus::COMMAND_PROCESSING_ERROR: + const auto st = *reinterpret_cast(&status); + error_t status_ok = [](llcc68::CommandStatus st) { + switch (st) { + case llcc68::CommandStatus::COMMAND_TIMEOUT: + return error::SPI_TIMEOUT; + case llcc68::CommandStatus::FAILURE_TO_EXECUTE_COMMAND: + return error::SPI_CMD_FAILED; + case llcc68::CommandStatus::COMMAND_PROCESSING_ERROR: #ifdef APP_SPI_DISABLE_INVALID_STATUS_CHECK - return error::OK; + return error::OK; #else - return error::SPI_CMD_INVALID; + return error::SPI_CMD_INVALID; #endif - default: - return error::OK; + default: + return error::OK; + } + }(st.command_status); + if (status_ok != error::OK) { + return status_ok; } + error_t chip_mode_usual = [](llcc68::ChipMode mode) { + switch (mode) { + case llcc68::ChipMode::TX: + case llcc68::ChipMode::RX: + case llcc68::ChipMode::STBY_RC: + return error::OK; + default: + return error::SPI_INVALID_RADIO_STATE; + } + }(st.chip_mode); + return chip_mode_usual; } /*! diff --git a/inc/llcc68.hpp b/inc/llcc68.hpp index 3244cf6..8886fe6 100644 --- a/inc/llcc68.hpp +++ b/inc/llcc68.hpp @@ -494,16 +494,17 @@ inline Result config_packet_type(uint8_t sf) { res = set_dio_irq_params(irq_params); APP_RADIO_RETURN_ERR(res); +#ifndef APP_RADIO_DISABLE_CALIBRATION data[0] = RADIOLIB_SX126X_CALIBRATE_ALL; res = spi::write_stream(RADIOLIB_SX126X_CMD_CALIBRATE, std::span{data, 1}); APP_RADIO_RETURN_ERR(res); - // The total calibration time if all blocks are calibrated is 3.5 ms. The // calibration must be launched in STDBY_RC mode and the BUSY pins will be // high during the calibration process. A falling edge of BUSY indicates the // end of the procedure. delay_ms(5); while (gpio::digital_read(BUSY_PIN) == gpio::HIGH) {} +#endif /** APP_RADIO_DISABLE_CALIBRATION */ return {}; } @@ -1130,19 +1131,19 @@ async_transmit(const std::span data, Result res; res = standby(); - APP_RADIO_RETURN_ERR_CTX(res, "failed to standby"); + APP_RADIO_RETURN_ERR_CTX(res, "standby"); res = set_packet_params(packet_params.preamble_len, data.size(), packet_params.crc_type, packet_params.hdr_type); - APP_RADIO_RETURN_ERR_CTX(res, "failed to set packet params"); + APP_RADIO_RETURN_ERR_CTX(res, "set packet params"); res = set_buffer_base_address(); - APP_RADIO_RETURN_ERR_CTX(res, "failed to set buffer base address"); + APP_RADIO_RETURN_ERR_CTX(res, "set buffer base address"); res = write_buffer(data); - APP_RADIO_RETURN_ERR_CTX(res, "failed to write buffer"); + APP_RADIO_RETURN_ERR_CTX(res, "write buffer"); res = fix_sensitivity(mod_params.bw); - APP_RADIO_RETURN_ERR_CTX(res, "failed to fix sensitivity"); + APP_RADIO_RETURN_ERR_CTX(res, "fix sensitivity"); constexpr auto irq_mask = RADIOLIB_SX126X_IRQ_TX_DONE | RADIOLIB_SX126X_IRQ_TIMEOUT; constexpr auto irq_params = irq_params_t{ @@ -1152,12 +1153,12 @@ async_transmit(const std::span data, DIO3_PIN == NC_PIN ? RADIOLIB_SX126X_IRQ_NONE : irq_mask, }; res = set_dio_irq_params(irq_params); - APP_RADIO_RETURN_ERR_CTX(res, "failed to set dio irq params"); + APP_RADIO_RETURN_ERR_CTX(res, "set dio irq params"); clear_irq_status(irq_mask); - APP_RADIO_RETURN_ERR_CTX(res, "failed to clear irq status"); + APP_RADIO_RETURN_ERR_CTX(res, "clear irq status"); res = tx(); - APP_RADIO_RETURN_ERR_CTX(res, "failed to transmit"); + APP_RADIO_RETURN_ERR_CTX(res, "tx"); constexpr auto TIMEOUT_FACTOR = 11u / 10u; const auto timeout_us = calc_time_on_air(data.size(), @@ -1310,7 +1311,12 @@ static constexpr auto begin = [](const lora_parameters_t ¶ms) -> Result statuses) { uint8_t i = 0; for (const auto st : statuses) { if (const auto err = status_to_err(st); err != error::OK) { - ESP_LOGE(TAG, "failed to verify status 0x%02x at byte %u", st, i); + ESP_LOGE(TAG, "bad status 0x%02x at byte %u", st, i); return err; } i += 1;