feat: add option to disable radio calibration and update status error handling

This commit is contained in:
2025-08-07 14:51:57 +08:00
parent c4a61d2708
commit 72299b62ce
6 changed files with 57 additions and 25 deletions

View File

@ -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()

View File

@ -3,7 +3,8 @@
#include <array>
#include <tuple>
#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<std::tuple<t, const char *>>(
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),

View File

@ -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<const llcc68::status_t *>(&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<const llcc68::status_t *>(&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;
}
/*!

View File

@ -494,16 +494,17 @@ inline Result<Unit, error_t> 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<const uint8_t>{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<const uint8_t> data,
Result<Unit, error_t> 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<const uint8_t> 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 &params) -> Result<Unit
res = set_dio2_as_rf_switch(false);
APP_RADIO_RETURN_ERR_CTX(res, "set dio2 as rf switch");
res = set_frequency(params.frequency);
#ifdef APP_RADIO_DISABLE_CALIBRATION
res = set_frequency(params.frequency, false);
#else
res = set_frequency(params.frequency, true);
#endif /* APP_RADIO_DISABLE_CALIBRATION */
APP_RADIO_RETURN_ERR_CTX(res, "set frequency");
// SetPacketParams

View File

@ -284,10 +284,12 @@ inline const char *to_str(const ChipMode &mode) {
struct __attribute__((packed)) status_t {
// LSB
uint8_t reserved_1 : 1;
CommandStatus command_status : 3;
ChipMode chip_mode : 3;
uint8_t reserved_2 : 1;
// MSB
};
static_assert(sizeof(status_t) == 1);

View File

@ -43,7 +43,7 @@ static constexpr auto verify_statuses = [](std::span<const uint8_t> 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;