feat: add shared GMSK radio profile helpers
Add a fixed 6-byte 100 kbps GMSK profile matching the health-band telemetry packet, plus FSK packet-status helpers for RSSI and error checks. Expose instantaneous RSSI reads for CCA and image calibration for 430-440 MHz GFSK bring-up.
This commit is contained in:
@@ -125,6 +125,7 @@ struct LLCC68 {
|
|||||||
|
|
||||||
expected<status_t, error_code> get_status();
|
expected<status_t, error_code> get_status();
|
||||||
expected<packet_status_t, error_code> get_packet_status();
|
expected<packet_status_t, error_code> get_packet_status();
|
||||||
|
expected<uint8_t, error_code> get_rssi_inst_x2_neg();
|
||||||
expected<unit, error_code> reset();
|
expected<unit, error_code> reset();
|
||||||
expected<unit, error_code> set_standby();
|
expected<unit, error_code> set_standby();
|
||||||
expected<ChipType, error_code> hal_get_chip_type();
|
expected<ChipType, error_code> hal_get_chip_type();
|
||||||
@@ -164,6 +165,7 @@ struct LLCC68 {
|
|||||||
expected<unit, error_code> set_gfsk_crc_seed(uint16_t seed);
|
expected<unit, error_code> set_gfsk_crc_seed(uint16_t seed);
|
||||||
expected<unit, error_code> set_gfsk_crc_polynomial(uint16_t polynomial);
|
expected<unit, error_code> set_gfsk_crc_polynomial(uint16_t polynomial);
|
||||||
expected<unit, error_code> set_gfsk_whitening_seed(uint16_t seed);
|
expected<unit, error_code> set_gfsk_whitening_seed(uint16_t seed);
|
||||||
|
expected<unit, error_code> calibrate_image(uint8_t freq1, uint8_t freq2);
|
||||||
expected<unit, error_code> set_tx_params(tx_params_t params);
|
expected<unit, error_code> set_tx_params(tx_params_t params);
|
||||||
expected<unit, error_code> set_tx_params(int8_t pwr,
|
expected<unit, error_code> set_tx_params(int8_t pwr,
|
||||||
LoRaTxRampTime ramp_time);
|
LoRaTxRampTime ramp_time);
|
||||||
|
|||||||
@@ -476,6 +476,40 @@ struct gfsk_parameters_t {
|
|||||||
.broadcast_address = std::nullopt,
|
.broadcast_address = std::nullopt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr gfsk_parameters_t
|
||||||
|
Gmsk100kFixed6(freq_t frequency_mhz = 433.45,
|
||||||
|
tx_params_t tx_params = tx_params_t::Default()) {
|
||||||
|
return {
|
||||||
|
.mod_params =
|
||||||
|
{
|
||||||
|
.bitrate_bps = 100'000,
|
||||||
|
.frequency_deviation_hz = 25'000,
|
||||||
|
.pulse_shape = GfskPulseShape::Gauss05,
|
||||||
|
.rx_bandwidth = GfskRxBandwidth::Bw187200,
|
||||||
|
},
|
||||||
|
.packet_params =
|
||||||
|
{
|
||||||
|
.preamble_bits = 32,
|
||||||
|
.detector_length = GfskPreambleDetector::Bits16,
|
||||||
|
.sync_length_bits = 32,
|
||||||
|
.address_filtering = GfskAddressFiltering::Disabled,
|
||||||
|
.packet_length_mode = GfskPacketLengthMode::Fixed,
|
||||||
|
.payload_length = 6,
|
||||||
|
.crc_type = GfskCrcType::Off,
|
||||||
|
.whitening = GfskWhitening::On,
|
||||||
|
},
|
||||||
|
.tx_params = tx_params,
|
||||||
|
.frequency_mhz = frequency_mhz,
|
||||||
|
.sync_word = {0x2D, 0xD4, 0xA1, 0x7E, 0, 0, 0, 0},
|
||||||
|
.sync_word_length = 4,
|
||||||
|
.crc_seed = 0x1D0F,
|
||||||
|
.crc_polynomial = 0x1021,
|
||||||
|
.whitening_seed = 0x0100,
|
||||||
|
.node_address = std::nullopt,
|
||||||
|
.broadcast_address = std::nullopt,
|
||||||
|
};
|
||||||
|
}
|
||||||
void log(const char *tag) const;
|
void log(const char *tag) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -656,6 +690,26 @@ struct __attribute__((packed)) fsk_packet_status_t {
|
|||||||
// the pkt_done IRQ. [negated, dBm, fixdt(0,8,1)] Actual signal power is
|
// the pkt_done IRQ. [negated, dBm, fixdt(0,8,1)] Actual signal power is
|
||||||
// –RssiAvg/2 (dBm)
|
// –RssiAvg/2 (dBm)
|
||||||
uint8_t rssi_avg;
|
uint8_t rssi_avg;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
bool has_error() const {
|
||||||
|
return (rx_status & 0b11111100U) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
bool packet_received() const {
|
||||||
|
return (rx_status & 0b00000010U) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
auto rssi_sync_dbm() const -> float {
|
||||||
|
return -static_cast<float>(rssi_sync) / 2.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
auto rssi_avg_dbm() const -> float {
|
||||||
|
return -static_cast<float>(rssi_avg) / 2.0F;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
union packet_status_t {
|
union packet_status_t {
|
||||||
|
|||||||
@@ -569,6 +569,14 @@ expected<packet_status_t, error_code> LLCC68::get_packet_status() {
|
|||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expected<uint8_t, error_code> LLCC68::get_rssi_inst_x2_neg() {
|
||||||
|
uint8_t raw = 0;
|
||||||
|
auto r = read_stream(RADIOLIB_SX126X_CMD_GET_RSSI_INST,
|
||||||
|
std::span<uint8_t>{&raw, 1});
|
||||||
|
APP_RADIO_RETURN_ERR_IGNORE_PROC_ERR(r);
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
expected<unit, error_code> LLCC68::reset() {
|
expected<unit, error_code> LLCC68::reset() {
|
||||||
// Drive RESET low-high with delays per datasheet, then poll standby
|
// Drive RESET low-high with delays per datasheet, then poll standby
|
||||||
if (not device_is_ready(config().reset_gpio.port)) {
|
if (not device_is_ready(config().reset_gpio.port)) {
|
||||||
@@ -899,6 +907,12 @@ expected<unit, error_code> LLCC68::set_gfsk_whitening_seed(uint16_t seed) {
|
|||||||
std::span<const uint8_t>{&lsb, 1});
|
std::span<const uint8_t>{&lsb, 1});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expected<unit, error_code> LLCC68::calibrate_image(uint8_t freq1,
|
||||||
|
uint8_t freq2) {
|
||||||
|
const uint8_t data[] = {freq1, freq2};
|
||||||
|
return write_stream(RADIOLIB_SX126X_CMD_CALIBRATE_IMAGE, data);
|
||||||
|
}
|
||||||
|
|
||||||
expected<unit, error_code> LLCC68::fix_inverted_iq(uint8_t iq_config) {
|
expected<unit, error_code> LLCC68::fix_inverted_iq(uint8_t iq_config) {
|
||||||
uint8_t iqCfg = 0;
|
uint8_t iqCfg = 0;
|
||||||
auto r = read_register(RADIOLIB_SX126X_REG_IQ_CONFIG,
|
auto r = read_register(RADIOLIB_SX126X_REG_IQ_CONFIG,
|
||||||
@@ -1202,6 +1216,9 @@ LLCC68::hal_gfsk_modem_init(gfsk_parameters_t params) {
|
|||||||
|
|
||||||
APP_RADIO_RETURN_ERR_CTX(set_packet_type_gfsk(),
|
APP_RADIO_RETURN_ERR_CTX(set_packet_type_gfsk(),
|
||||||
"gfsk_init::set_packet_type");
|
"gfsk_init::set_packet_type");
|
||||||
|
APP_RADIO_RETURN_ERR_CTX(calibrate_image(RADIOLIB_SX126X_CAL_IMG_430_MHZ_1,
|
||||||
|
RADIOLIB_SX126X_CAL_IMG_430_MHZ_2),
|
||||||
|
"gfsk_init::calibrate_image");
|
||||||
APP_RADIO_RETURN_ERR_CTX(set_gfsk_modulation_params(params.mod_params),
|
APP_RADIO_RETURN_ERR_CTX(set_gfsk_modulation_params(params.mod_params),
|
||||||
"gfsk_init::set_modulation_params");
|
"gfsk_init::set_modulation_params");
|
||||||
APP_RADIO_RETURN_ERR_CTX(
|
APP_RADIO_RETURN_ERR_CTX(
|
||||||
|
|||||||
Reference in New Issue
Block a user