major: refactor
- Introduced new enums for LoRa bandwidth and coding rate to improve clarity. - Updated default values for preamble length, frequency, bandwidth, and coding rate. - Added new structures for modulation and packet parameters, encapsulating related settings. - Refactored functions to utilize the new structures, improving parameter management in the llcc68 component.
This commit is contained in:
107
inc/llcc68.hpp
107
inc/llcc68.hpp
@ -444,7 +444,7 @@ set_dio2_as_rf_switch(const bool en) {
|
|||||||
/**
|
/**
|
||||||
* \brief set packet type and do the calibration
|
* \brief set packet type and do the calibration
|
||||||
*/
|
*/
|
||||||
inline Result<Unit, error_t> config_packet_type(const parameters_t ¶ms) {
|
inline Result<Unit, error_t> config_packet_type(uint8_t sf) {
|
||||||
Result<Unit, error_t> res;
|
Result<Unit, error_t> res;
|
||||||
constexpr auto mod = RADIOLIB_SX126X_PACKET_TYPE_LORA;
|
constexpr auto mod = RADIOLIB_SX126X_PACKET_TYPE_LORA;
|
||||||
uint8_t data[7];
|
uint8_t data[7];
|
||||||
@ -456,7 +456,7 @@ inline Result<Unit, error_t> config_packet_type(const parameters_t ¶ms) {
|
|||||||
APP_RADIO_RETURN_ERR(res);
|
APP_RADIO_RETURN_ERR(res);
|
||||||
|
|
||||||
data[0] = RADIOLIB_SX126X_CAD_ON_8_SYMB;
|
data[0] = RADIOLIB_SX126X_CAD_ON_8_SYMB;
|
||||||
data[1] = params.sf + 13;
|
data[1] = sf + 13;
|
||||||
data[2] = RADIOLIB_SX126X_CAD_PARAM_DET_MIN;
|
data[2] = RADIOLIB_SX126X_CAD_PARAM_DET_MIN;
|
||||||
data[3] = RADIOLIB_SX126X_CAD_GOTO_STDBY;
|
data[3] = RADIOLIB_SX126X_CAD_GOTO_STDBY;
|
||||||
data[4] = 0x00;
|
data[4] = 0x00;
|
||||||
@ -490,12 +490,16 @@ inline Result<Unit, error_t> config_packet_type(const parameters_t ¶ms) {
|
|||||||
\returns Expected time-on-air in microseconds.
|
\returns Expected time-on-air in microseconds.
|
||||||
*/
|
*/
|
||||||
constexpr uint32_t
|
constexpr uint32_t
|
||||||
calc_time_on_air(const size_t len, const calc_time_on_air_t params) {
|
calc_time_on_air(const size_t len,
|
||||||
|
uint8_t sf,
|
||||||
|
uint8_t bw,
|
||||||
|
uint8_t cr,
|
||||||
|
uint16_t preamble_length,
|
||||||
|
uint8_t header_type) {
|
||||||
// everything is in microseconds to allow integer arithmetic
|
// everything is in microseconds to allow integer arithmetic
|
||||||
// some constants have .25, these are multiplied by 4, and have _x4 postfix to indicate that fact
|
// some constants have .25, these are multiplied by 4, and have _x4 postfix to indicate that fact
|
||||||
const auto bw_ = float{bw_khz(params.bw)};
|
const auto bw_ = float{bw_khz(bw)};
|
||||||
const auto ubw = static_cast<uint32_t>(bw_ * 10);
|
const auto ubw = static_cast<uint32_t>(bw_ * 10);
|
||||||
const auto sf = params.sf;
|
|
||||||
const uint32_t symbolLength_us = (static_cast<uint32_t>(1000 * 10) << sf) / ubw;
|
const uint32_t symbolLength_us = (static_cast<uint32_t>(1000 * 10) << sf) / ubw;
|
||||||
uint8_t sfCoeff1_x4 = 17; // (4.25 * 4)
|
uint8_t sfCoeff1_x4 = 17; // (4.25 * 4)
|
||||||
uint8_t sfCoeff2 = 8;
|
uint8_t sfCoeff2 = 8;
|
||||||
@ -507,20 +511,20 @@ calc_time_on_air(const size_t len, const calc_time_on_air_t params) {
|
|||||||
if (symbolLength_us >= 16000) {
|
if (symbolLength_us >= 16000) {
|
||||||
sfDivisor = 4 * (sf - 2);
|
sfDivisor = 4 * (sf - 2);
|
||||||
}
|
}
|
||||||
constexpr int8_t bitsPerCrc = 16;
|
constexpr int8_t bitsPerCrc = 16;
|
||||||
constexpr int8_t N_symbol_header = params.header_type == RADIOLIB_SX126X_LORA_HEADER_EXPLICIT ? 20 : 0;
|
int8_t N_symbol_header = header_type == RADIOLIB_SX126X_LORA_HEADER_EXPLICIT ? 20 : 0;
|
||||||
|
|
||||||
// numerator of equation in section 6.1.4 of SX1268 datasheet v1.1 (might not actually be bitcount, but it has len * 8)
|
// numerator of equation in section 6.1.4 of SX1268 datasheet v1.1 (might not actually be bitcount, but it has len * 8)
|
||||||
int16_t bitCount = static_cast<int16_t>(8) * len + params.crc_type * bitsPerCrc - 4 * sf + sfCoeff2 + N_symbol_header;
|
int16_t bitCount = static_cast<int16_t>(8) * len + RADIOLIB_SX126X_LORA_CRC_ON * bitsPerCrc - 4 * sf + sfCoeff2 + N_symbol_header;
|
||||||
if (bitCount < 0) {
|
if (bitCount < 0) {
|
||||||
bitCount = 0;
|
bitCount = 0;
|
||||||
}
|
}
|
||||||
// add (sfDivisor) - 1 to the numerator to give integer CEIL(...)
|
// add (sfDivisor) - 1 to the numerator to give integer CEIL(...)
|
||||||
const uint16_t nPreCodedSymbols = (bitCount + (sfDivisor - 1)) / (sfDivisor);
|
const uint16_t nPreCodedSymbols = (bitCount + (sfDivisor - 1)) / (sfDivisor);
|
||||||
|
|
||||||
const auto de = std::get<1>(cr_to_ratio(params.cr));
|
const auto de = std::get<1>(cr_to_ratio(cr));
|
||||||
// preamble can be 65k, therefore nSymbol_x4 needs to be 32 bit
|
// preamble can be 65k, therefore nSymbol_x4 needs to be 32 bit
|
||||||
const uint32_t nSymbol_x4 = (params.preamble_length + 8) * 4 + sfCoeff1_x4 + nPreCodedSymbols * de * 4;
|
const uint32_t nSymbol_x4 = (preamble_length + 8) * 4 + sfCoeff1_x4 + nPreCodedSymbols * de * 4;
|
||||||
|
|
||||||
return symbolLength_us * nSymbol_x4 / 4;
|
return symbolLength_us * nSymbol_x4 / 4;
|
||||||
}
|
}
|
||||||
@ -1017,7 +1021,7 @@ read_data_internal() {
|
|||||||
\note The IRQ RxDone means that a packet has been received but the CRC could be wrong: the user must check the CRC before validating the packet.
|
\note The IRQ RxDone means that a packet has been received but the CRC could be wrong: the user must check the CRC before validating the packet.
|
||||||
*/
|
*/
|
||||||
inline Result<Unit, error_t>
|
inline Result<Unit, error_t>
|
||||||
kick_inf_rx() {
|
kick_inf_rx(const modulation_params_t &mod_params, const packet_params_t &packet_params) {
|
||||||
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, "failed to standby");
|
||||||
@ -1032,6 +1036,11 @@ kick_inf_rx() {
|
|||||||
DIO3_PIN == NC_PIN ? RADIOLIB_SX126X_IRQ_NONE : irq_mask,
|
DIO3_PIN == NC_PIN ? RADIOLIB_SX126X_IRQ_NONE : irq_mask,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
res = set_modulation_params(mod_params.sf, mod_params.bw, mod_params.cr, mod_params.ldr_optimize);
|
||||||
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to set modulation params");
|
||||||
|
res = set_packet_params(packet_params.preamble_len, packet_params.payload_len, packet_params.crc_type, packet_params.hdr_type);
|
||||||
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to set packet params");
|
||||||
|
|
||||||
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, "failed to set dio irq params");
|
||||||
res = clear_irq_status();
|
res = clear_irq_status();
|
||||||
@ -1042,27 +1051,6 @@ kick_inf_rx() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum class AFTER_TX_BEHAVIOR {
|
|
||||||
STDBY,
|
|
||||||
RX,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief will be called after each `sync_transmit`
|
|
||||||
* \note Application writer (i.e. myself) should manually enable the receiver after transmission
|
|
||||||
*/
|
|
||||||
inline void after_tx(const AFTER_TX_BEHAVIOR behavior = AFTER_TX_BEHAVIOR::RX) {
|
|
||||||
clear_irq_status();
|
|
||||||
switch (behavior) {
|
|
||||||
case AFTER_TX_BEHAVIOR::STDBY:
|
|
||||||
standby();
|
|
||||||
break;
|
|
||||||
case AFTER_TX_BEHAVIOR::RX:
|
|
||||||
kick_inf_rx();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
After power up (battery insertion or hard reset) the chip runs automatically a calibration procedure and goes to STDBY_RC
|
After power up (battery insertion or hard reset) the chip runs automatically a calibration procedure and goes to STDBY_RC
|
||||||
mode. This is indicated by a low state on BUSY pin. From this state the steps are:
|
mode. This is indicated by a low state on BUSY pin. From this state the steps are:
|
||||||
@ -1082,7 +1070,7 @@ inline void after_tx(const AFTER_TX_BEHAVIOR behavior = AFTER_TX_BEHAVIOR::RX) {
|
|||||||
14. Clear the IRQ TxDone flag
|
14. Clear the IRQ TxDone flag
|
||||||
*/
|
*/
|
||||||
inline Result<Unit, error_t>
|
inline Result<Unit, error_t>
|
||||||
sync_transmit(const uint8_t *data, const size_t len, const calc_time_on_air_t ¶ms) {
|
sync_transmit(const std::span<const uint8_t> data, const lora_parameters_t ¶ms) {
|
||||||
// unimplemented
|
// unimplemented
|
||||||
std::unreachable();
|
std::unreachable();
|
||||||
return {};
|
return {};
|
||||||
@ -1098,30 +1086,32 @@ sync_transmit(const uint8_t *data, const size_t len, const calc_time_on_air_t &p
|
|||||||
* \see poll_tx_state
|
* \see poll_tx_state
|
||||||
*/
|
*/
|
||||||
inline Result<transmit_state_t, error_t>
|
inline Result<transmit_state_t, error_t>
|
||||||
async_transmit(const uint8_t *data, const size_t len,
|
async_transmit(const std::span<const uint8_t> data,
|
||||||
const calc_time_on_air_t ¶ms,
|
const lora_parameters_t ¶ms,
|
||||||
const transmit_state_t &tx_state) {
|
const transmit_state_t &tx_state) {
|
||||||
if (tx_state.is_transmitting) {
|
if (tx_state.is_transmitting) {
|
||||||
return ue_t{error_t{error::RADIO_BUSY_TX}};
|
return ue_t{error_t{error::RADIO_BUSY_TX}};
|
||||||
}
|
}
|
||||||
if (len > RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
|
if (data.size() > RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
|
||||||
return ue_t{error_t{error::INVALID_SIZE}};
|
return ue_t{error_t{error::INVALID_SIZE}};
|
||||||
}
|
}
|
||||||
|
const auto &mod_params = params.mod_params;
|
||||||
|
const auto &packet_params = params.packet_params;
|
||||||
|
|
||||||
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, "failed to standby");
|
||||||
|
|
||||||
res = set_packet_params(params.preamble_length, len, params.crc_type, params.header_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, "failed to 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, "failed to set buffer base address");
|
||||||
|
|
||||||
res = write_buffer(std::span<const uint8_t>{data, len});
|
res = write_buffer(data);
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to write buffer");
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to write buffer");
|
||||||
|
|
||||||
res = fix_sensitivity(params.bw);
|
res = fix_sensitivity(mod_params.bw);
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to fix sensitivity");
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to 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;
|
||||||
@ -1139,7 +1129,14 @@ async_transmit(const uint8_t *data, const size_t len,
|
|||||||
res = tx();
|
res = tx();
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to transmit");
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to transmit");
|
||||||
|
|
||||||
const auto timeout_us = calc_time_on_air(len, params) * 11u / 10u;
|
constexpr auto TIMEOUT_FACTOR = 11u / 10u;
|
||||||
|
const auto timeout_us = calc_time_on_air(data.size(),
|
||||||
|
mod_params.sf,
|
||||||
|
mod_params.bw,
|
||||||
|
mod_params.cr,
|
||||||
|
packet_params.preamble_len,
|
||||||
|
packet_params.hdr_type) *
|
||||||
|
TIMEOUT_FACTOR;
|
||||||
const uint16_t timeout_ms = timeout_us / 1000;
|
const uint16_t timeout_ms = timeout_us / 1000;
|
||||||
auto instant = Instant<>{};
|
auto instant = Instant<>{};
|
||||||
return transmit_state_t{
|
return transmit_state_t{
|
||||||
@ -1149,13 +1146,6 @@ async_transmit(const uint8_t *data, const size_t len,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Result<transmit_state_t, error_t>
|
|
||||||
async_transmit(const std::span<const uint8_t> data,
|
|
||||||
const calc_time_on_air_t ¶ms,
|
|
||||||
const transmit_state_t &tx_state) {
|
|
||||||
return async_transmit(data.data(), data.size(), params, tx_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static constexpr auto init_pins = [](void (*isr)(void *), void *arg) {
|
static constexpr auto init_pins = [](void (*isr)(void *), void *arg) {
|
||||||
if (RST_PIN != GPIO_NUM_NC) {
|
if (RST_PIN != GPIO_NUM_NC) {
|
||||||
@ -1183,7 +1173,7 @@ static constexpr auto init_pins = [](void (*isr)(void *), void *arg) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr auto begin = [](const parameters_t ¶ms) -> Result<Unit, error_t> {
|
static constexpr auto begin = [](const lora_parameters_t ¶ms) -> 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
|
* Most of the commands can be sent in any order except for the radio configuration commands which will set the radio in
|
||||||
* the proper operating mode. Indeed, it is mandatory to set the radio protocol using the command SetPacketType(...) as a first
|
* the proper operating mode. Indeed, it is mandatory to set the radio protocol using the command SetPacketType(...) as a first
|
||||||
@ -1212,16 +1202,17 @@ static constexpr auto begin = [](const parameters_t ¶ms) -> Result<Unit, err
|
|||||||
details::__tcxo_delay__ = *voltage_;
|
details::__tcxo_delay__ = *voltage_;
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set TCXO");
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to set TCXO");
|
||||||
}
|
}
|
||||||
|
const auto &mod_params = params.mod_params;
|
||||||
|
const auto &packet_params = params.packet_params;
|
||||||
|
|
||||||
// SetPacketType
|
// SetPacketType
|
||||||
res = config_packet_type(params);
|
res = config_packet_type(mod_params.sf);
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to config packet type");
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to config packet type");
|
||||||
|
|
||||||
// SetModulationParams
|
res = set_modulation_params(mod_params.sf,
|
||||||
res = set_modulation_params(params.sf,
|
mod_params.bw,
|
||||||
params.bw,
|
mod_params.cr,
|
||||||
params.cr,
|
mod_params.ldr_optimize);
|
||||||
params.ldr_optimize);
|
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set modulation params");
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to set modulation params");
|
||||||
|
|
||||||
res = set_sync_word(params.sync_word);
|
res = set_sync_word(params.sync_word);
|
||||||
@ -1245,10 +1236,10 @@ static constexpr auto begin = [](const parameters_t ¶ms) -> Result<Unit, err
|
|||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set frequency");
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to set frequency");
|
||||||
|
|
||||||
// SetPacketParams
|
// SetPacketParams
|
||||||
res = set_packet_params(params.preamble_len,
|
res = set_packet_params(packet_params.preamble_len,
|
||||||
0x00,
|
packet_params.payload_len,
|
||||||
DEFAULT_CRC_TYPE,
|
packet_params.crc_type,
|
||||||
DEFAULT_HEADER_TYPE);
|
packet_params.hdr_type);
|
||||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set packet params");
|
APP_RADIO_RETURN_ERR_CTX(res, "failed to set packet params");
|
||||||
|
|
||||||
res = set_output_power(chip_type_to_max_tx_power(chip));
|
res = set_output_power(chip_type_to_max_tx_power(chip));
|
||||||
|
|||||||
@ -11,19 +11,86 @@
|
|||||||
#include "radiolib_definitions.hpp"
|
#include "radiolib_definitions.hpp"
|
||||||
|
|
||||||
namespace app::driver::llcc68 {
|
namespace app::driver::llcc68 {
|
||||||
using freq_t = float;
|
using freq_t = float;
|
||||||
|
enum LoRaBandwidth : uint8_t {
|
||||||
|
BW_10_4 = 0x08,
|
||||||
|
BW_15_6 = 0x01,
|
||||||
|
BW_20_8 = 0x09,
|
||||||
|
BW_31_25 = 0x02,
|
||||||
|
BW_41_7 = 0x0A,
|
||||||
|
BW_62_5 = 0x03,
|
||||||
|
BW_125_0 = 0x04,
|
||||||
|
BW_250_0 = 0x05,
|
||||||
|
BW_500_0 = 0x06,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LoRaCodingRate : uint8_t {
|
||||||
|
CR_4_5 = 0x01,
|
||||||
|
CR_4_6 = 0x02,
|
||||||
|
CR_4_7 = 0x03,
|
||||||
|
CR_4_8 = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint16_t DEFAULT_PREAMBLE_LEN = 8;
|
||||||
constexpr uint8_t DEFAULT_SYNC_WORD = RADIOLIB_SX126X_SYNC_WORD_PRIVATE;
|
constexpr uint8_t DEFAULT_SYNC_WORD = RADIOLIB_SX126X_SYNC_WORD_PRIVATE;
|
||||||
constexpr uint16_t DEFAULT_PREAMBLE_LEN = 6; // recommended is 8 symbols though
|
|
||||||
constexpr uint8_t DEFAULT_CRC_TYPE = RADIOLIB_SX126X_LORA_CRC_OFF;
|
constexpr uint8_t DEFAULT_CRC_TYPE = RADIOLIB_SX126X_LORA_CRC_OFF;
|
||||||
constexpr uint8_t DEFAULT_HEADER_TYPE = RADIOLIB_SX126X_LORA_HEADER_EXPLICIT;
|
constexpr uint8_t DEFAULT_HEADER_TYPE = RADIOLIB_SX126X_LORA_HEADER_EXPLICIT;
|
||||||
constexpr uint8_t DEFAULT_IQ_TYPE = RADIOLIB_SX126X_LORA_IQ_STANDARD;
|
constexpr uint8_t DEFAULT_IQ_TYPE = RADIOLIB_SX126X_LORA_IQ_STANDARD;
|
||||||
constexpr uint8_t PACKET_TYPE = RADIOLIB_SX126X_PACKET_TYPE_LORA;
|
|
||||||
|
|
||||||
constexpr auto DEFAULT_BW = RADIOLIB_SX126X_LORA_BW_125_0;
|
constexpr auto DEFAULT_SF = 7;
|
||||||
constexpr auto DEFAULT_SF = 9;
|
constexpr auto DEFAULT_FREQUENCY = freq_t{433.05};
|
||||||
constexpr auto DEFAULT_CR = RADIOLIB_SX126X_LORA_CR_4_6;
|
constexpr auto DEFAULT_BW = BW_250_0;
|
||||||
constexpr auto DEFAULT_LDR_OPTIMIZE = RADIOLIB_SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_ON;
|
constexpr auto DEFAULT_CR = CR_4_5;
|
||||||
constexpr auto DEFAULT_FREQUENCY = freq_t{433.2};
|
constexpr auto DEFAULT_LDR_OPTIMIZE = RADIOLIB_SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_OFF;
|
||||||
|
|
||||||
|
|
||||||
|
struct modulation_params_t {
|
||||||
|
uint8_t bw;
|
||||||
|
uint8_t sf;
|
||||||
|
uint8_t cr;
|
||||||
|
uint8_t ldr_optimize;
|
||||||
|
|
||||||
|
static modulation_params_t Default() {
|
||||||
|
return modulation_params_t{
|
||||||
|
.bw = DEFAULT_BW,
|
||||||
|
.sf = DEFAULT_SF,
|
||||||
|
.cr = DEFAULT_CR,
|
||||||
|
.ldr_optimize = DEFAULT_LDR_OPTIMIZE,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct packet_params_t {
|
||||||
|
uint16_t preamble_len;
|
||||||
|
uint8_t payload_len;
|
||||||
|
uint8_t crc_type;
|
||||||
|
uint8_t hdr_type;
|
||||||
|
|
||||||
|
static packet_params_t Default() {
|
||||||
|
return packet_params_t{
|
||||||
|
.preamble_len = DEFAULT_PREAMBLE_LEN,
|
||||||
|
.payload_len = 0xff,
|
||||||
|
.crc_type = DEFAULT_CRC_TYPE,
|
||||||
|
.hdr_type = DEFAULT_HEADER_TYPE,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lora_parameters_t {
|
||||||
|
modulation_params_t mod_params;
|
||||||
|
packet_params_t packet_params;
|
||||||
|
freq_t frequency;
|
||||||
|
uint8_t sync_word;
|
||||||
|
|
||||||
|
static lora_parameters_t Default() {
|
||||||
|
return lora_parameters_t{
|
||||||
|
.mod_params = modulation_params_t::Default(),
|
||||||
|
.packet_params = packet_params_t::Default(),
|
||||||
|
.frequency = DEFAULT_FREQUENCY,
|
||||||
|
.sync_word = DEFAULT_SYNC_WORD,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
enum class ChipType {
|
enum class ChipType {
|
||||||
Unknown,
|
Unknown,
|
||||||
@ -116,32 +183,6 @@ struct __attribute__((packed)) status_t {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(status_t) == 1);
|
static_assert(sizeof(status_t) == 1);
|
||||||
|
|
||||||
struct parameters_t {
|
|
||||||
uint8_t bw;
|
|
||||||
uint8_t sf;
|
|
||||||
uint8_t cr;
|
|
||||||
uint8_t ldr_optimize;
|
|
||||||
uint16_t preamble_len;
|
|
||||||
uint8_t sync_word;
|
|
||||||
freq_t frequency;
|
|
||||||
|
|
||||||
static parameters_t Default() {
|
|
||||||
return parameters_t{
|
|
||||||
.bw = DEFAULT_BW,
|
|
||||||
.sf = DEFAULT_SF,
|
|
||||||
.cr = DEFAULT_CR,
|
|
||||||
.ldr_optimize = DEFAULT_LDR_OPTIMIZE,
|
|
||||||
.preamble_len = DEFAULT_PREAMBLE_LEN,
|
|
||||||
.sync_word = DEFAULT_SYNC_WORD,
|
|
||||||
.frequency = DEFAULT_FREQUENCY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr static size_t size() {
|
|
||||||
return sizeof(parameters_t);
|
|
||||||
}
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
|
|
||||||
struct __attribute__((packed)) lora_packet_status_t {
|
struct __attribute__((packed)) lora_packet_status_t {
|
||||||
// Average over last packet received of RSSI
|
// Average over last packet received of RSSI
|
||||||
@ -209,25 +250,6 @@ struct __attribute__((packed)) op_error_t {
|
|||||||
|
|
||||||
static_assert(sizeof(op_error_t) == 2);
|
static_assert(sizeof(op_error_t) == 2);
|
||||||
|
|
||||||
struct calc_time_on_air_t {
|
|
||||||
uint8_t bw;
|
|
||||||
uint8_t sf;
|
|
||||||
uint8_t cr;
|
|
||||||
uint16_t preamble_length;
|
|
||||||
static constexpr uint8_t ldro = DEFAULT_LDR_OPTIMIZE;
|
|
||||||
static constexpr uint8_t crc_type = DEFAULT_CRC_TYPE;
|
|
||||||
static constexpr uint8_t header_type = DEFAULT_HEADER_TYPE;
|
|
||||||
static constexpr uint8_t iq_type = DEFAULT_IQ_TYPE;
|
|
||||||
static constexpr uint8_t sync_word = DEFAULT_SYNC_WORD;
|
|
||||||
static calc_time_on_air_t from_parameters(const parameters_t ¶ms) {
|
|
||||||
return calc_time_on_air_t{
|
|
||||||
.bw = params.bw,
|
|
||||||
.sf = params.sf,
|
|
||||||
.cr = params.cr,
|
|
||||||
.preamble_length = params.preamble_len};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr bool in_range(const auto v, const auto min, const auto max) {
|
constexpr bool in_range(const auto v, const auto min, const auto max) {
|
||||||
return v >= min && v <= max;
|
return v >= min && v <= max;
|
||||||
}
|
}
|
||||||
@ -332,60 +354,6 @@ constexpr bool valid_sf(const uint8_t bw, const uint8_t sf) {
|
|||||||
constexpr bool valid_freq(const freq_t freq) {
|
constexpr bool valid_freq(const freq_t freq) {
|
||||||
return in_range(freq, freq_t{150.0}, freq_t{960.0});
|
return in_range(freq, freq_t{150.0}, freq_t{960.0});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief check if the parameters are valid. if not, set them to default.
|
|
||||||
* \param params the parameters to check
|
|
||||||
* \return if the parameters are valid, and the modified parameters
|
|
||||||
*/
|
|
||||||
constexpr std::tuple<bool, parameters_t>
|
|
||||||
check_fix_params(parameters_t params) {
|
|
||||||
bool ok = true;
|
|
||||||
|
|
||||||
if (not valid_bw(params.bw)) {
|
|
||||||
params.bw = DEFAULT_BW;
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
if (not valid_sf(params.bw, params.sf)) {
|
|
||||||
params.sf = DEFAULT_SF;
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
if (not valid_cr(params.cr)) {
|
|
||||||
params.cr = DEFAULT_CR;
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
if (not valid_freq(params.frequency)) {
|
|
||||||
params.frequency = DEFAULT_FREQUENCY;
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
if (not valid_ldr_optimize(params.ldr_optimize)) {
|
|
||||||
params.ldr_optimize = DEFAULT_LDR_OPTIMIZE;
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
return {ok, params};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief only do the check
|
|
||||||
*/
|
|
||||||
constexpr bool check_params(const parameters_t ¶ms) {
|
|
||||||
if (not valid_bw(params.bw)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (not valid_sf(params.bw, params.sf)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (not valid_cr(params.cr)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (not valid_freq(params.frequency)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (not valid_ldr_optimize(params.ldr_optimize)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // LLCC68_DEFINITIONS_H
|
#endif // LLCC68_DEFINITIONS_H
|
||||||
|
|||||||
Reference in New Issue
Block a user