feat: add option to disable radio calibration and update status error handling
This commit is contained in:
@ -10,7 +10,12 @@ idf_component_register(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# This option would make LLCC68 ignore `SPI_CMD_INVALID` error.
|
# 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)
|
if (APP_SPI_DISABLE_INVALID_STATUS_CHECK)
|
||||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC APP_SPI_DISABLE_INVALID_STATUS_CHECK)
|
target_compile_definitions(${COMPONENT_LIB} PUBLIC APP_SPI_DISABLE_INVALID_STATUS_CHECK)
|
||||||
endif()
|
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()
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,8 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#define APP_ERR_TBL_IT(err) {err, #err}
|
#define APP_ERR_TBL_IT(err) \
|
||||||
|
{ err, #err }
|
||||||
|
|
||||||
namespace app::driver::hal::error {
|
namespace app::driver::hal::error {
|
||||||
using t = int;
|
using t = int;
|
||||||
@ -41,6 +42,7 @@ constexpr t SPI_CMD_INVALID = SPI_ERR_BASE + 3;
|
|||||||
// The command was successfully processed, however the chip could not execute the command;
|
// 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
|
// 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_ERR_BASE = 0x1'3000;
|
||||||
constexpr t RADIO_CHIP_NOT_FOUND = RADIO_ERR_BASE + 1;
|
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_TIMEOUT),
|
||||||
APP_ERR_TBL_IT(SPI_CMD_INVALID),
|
APP_ERR_TBL_IT(SPI_CMD_INVALID),
|
||||||
APP_ERR_TBL_IT(SPI_CMD_FAILED),
|
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_CHIP_NOT_FOUND),
|
||||||
APP_ERR_TBL_IT(RADIO_INVALID_TCXO_VOLTAGE),
|
APP_ERR_TBL_IT(RADIO_INVALID_TCXO_VOLTAGE),
|
||||||
|
|||||||
@ -48,7 +48,8 @@ void init(spi_config_t config = {SPI2_HOST, 4'000'000});
|
|||||||
|
|
||||||
inline error_t status_to_err(const uint8_t status) {
|
inline error_t status_to_err(const uint8_t status) {
|
||||||
const auto st = *reinterpret_cast<const llcc68::status_t *>(&status);
|
const auto st = *reinterpret_cast<const llcc68::status_t *>(&status);
|
||||||
switch (st.command_status) {
|
error_t status_ok = [](llcc68::CommandStatus st) {
|
||||||
|
switch (st) {
|
||||||
case llcc68::CommandStatus::COMMAND_TIMEOUT:
|
case llcc68::CommandStatus::COMMAND_TIMEOUT:
|
||||||
return error::SPI_TIMEOUT;
|
return error::SPI_TIMEOUT;
|
||||||
case llcc68::CommandStatus::FAILURE_TO_EXECUTE_COMMAND:
|
case llcc68::CommandStatus::FAILURE_TO_EXECUTE_COMMAND:
|
||||||
@ -62,6 +63,21 @@ inline error_t status_to_err(const uint8_t status) {
|
|||||||
default:
|
default:
|
||||||
return error::OK;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@ -494,16 +494,17 @@ inline Result<Unit, error_t> config_packet_type(uint8_t sf) {
|
|||||||
res = set_dio_irq_params(irq_params);
|
res = set_dio_irq_params(irq_params);
|
||||||
APP_RADIO_RETURN_ERR(res);
|
APP_RADIO_RETURN_ERR(res);
|
||||||
|
|
||||||
|
#ifndef APP_RADIO_DISABLE_CALIBRATION
|
||||||
data[0] = RADIOLIB_SX126X_CALIBRATE_ALL;
|
data[0] = RADIOLIB_SX126X_CALIBRATE_ALL;
|
||||||
res = spi::write_stream(RADIOLIB_SX126X_CMD_CALIBRATE, std::span<const uint8_t>{data, 1});
|
res = spi::write_stream(RADIOLIB_SX126X_CMD_CALIBRATE, std::span<const uint8_t>{data, 1});
|
||||||
APP_RADIO_RETURN_ERR(res);
|
APP_RADIO_RETURN_ERR(res);
|
||||||
|
|
||||||
// The total calibration time if all blocks are calibrated is 3.5 ms. The
|
// 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
|
// 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
|
// high during the calibration process. A falling edge of BUSY indicates the
|
||||||
// end of the procedure.
|
// end of the procedure.
|
||||||
delay_ms(5);
|
delay_ms(5);
|
||||||
while (gpio::digital_read(BUSY_PIN) == gpio::HIGH) {}
|
while (gpio::digital_read(BUSY_PIN) == gpio::HIGH) {}
|
||||||
|
#endif /** APP_RADIO_DISABLE_CALIBRATION */
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,19 +1131,19 @@ async_transmit(const std::span<const uint8_t> data,
|
|||||||
|
|
||||||
Result<Unit, error_t> res;
|
Result<Unit, error_t> res;
|
||||||
res = standby();
|
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);
|
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();
|
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);
|
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);
|
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_mask = RADIOLIB_SX126X_IRQ_TX_DONE | RADIOLIB_SX126X_IRQ_TIMEOUT;
|
||||||
constexpr auto irq_params = irq_params_t{
|
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,
|
DIO3_PIN == NC_PIN ? RADIOLIB_SX126X_IRQ_NONE : irq_mask,
|
||||||
};
|
};
|
||||||
res = set_dio_irq_params(irq_params);
|
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);
|
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();
|
res = tx();
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to transmit");
|
APP_RADIO_RETURN_ERR_CTX(res, "tx");
|
||||||
|
|
||||||
constexpr auto TIMEOUT_FACTOR = 11u / 10u;
|
constexpr auto TIMEOUT_FACTOR = 11u / 10u;
|
||||||
const auto timeout_us = calc_time_on_air(data.size(),
|
const auto timeout_us = calc_time_on_air(data.size(),
|
||||||
@ -1310,7 +1311,12 @@ static constexpr auto begin = [](const lora_parameters_t ¶ms) -> Result<Unit
|
|||||||
res = set_dio2_as_rf_switch(false);
|
res = set_dio2_as_rf_switch(false);
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "set dio2 as rf switch");
|
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");
|
APP_RADIO_RETURN_ERR_CTX(res, "set frequency");
|
||||||
|
|
||||||
// SetPacketParams
|
// SetPacketParams
|
||||||
|
|||||||
@ -284,10 +284,12 @@ inline const char *to_str(const ChipMode &mode) {
|
|||||||
|
|
||||||
|
|
||||||
struct __attribute__((packed)) status_t {
|
struct __attribute__((packed)) status_t {
|
||||||
|
// LSB
|
||||||
uint8_t reserved_1 : 1;
|
uint8_t reserved_1 : 1;
|
||||||
CommandStatus command_status : 3;
|
CommandStatus command_status : 3;
|
||||||
ChipMode chip_mode : 3;
|
ChipMode chip_mode : 3;
|
||||||
uint8_t reserved_2 : 1;
|
uint8_t reserved_2 : 1;
|
||||||
|
// MSB
|
||||||
};
|
};
|
||||||
static_assert(sizeof(status_t) == 1);
|
static_assert(sizeof(status_t) == 1);
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ static constexpr auto verify_statuses = [](std::span<const uint8_t> statuses) {
|
|||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
for (const auto st : statuses) {
|
for (const auto st : statuses) {
|
||||||
if (const auto err = status_to_err(st); err != error::OK) {
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user