1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 22:43:50 +01:00

Merge pull request #21713 from fabian18/pr/sx126x_radio_hal_img_calibration

drivers/sx126x: image calibration after frequency change
This commit is contained in:
crasbe 2025-10-06 13:02:10 +00:00 committed by GitHub
commit 0a2bd01134
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 94 additions and 20 deletions

View File

@ -122,6 +122,23 @@ static inline bool sx126x_is_stm32wl(sx126x_t *dev)
}
}
/**
* @brief Get the current chip state
*
* @param[in] dev Device descriptor of the driver
*
* @return Chip state
*/
sx126x_chip_modes_t sx126x_get_state(const sx126x_t *dev);
/**
* @brief Set the internal chip state
*
* @param[in] dev Device descriptor of the driver
* @param[in] state State to set
*/
void sx126x_set_state(sx126x_t *dev, sx126x_chip_modes_t state);
#ifdef __cplusplus
}
#endif

View File

@ -22,6 +22,7 @@
#include "sx126x_netdev.h"
#include "macros/units.h"
#include "net/lora.h"
#include "periph/spi.h"
@ -434,17 +435,84 @@ int sx126x_init(sx126x_t *dev)
return res;
}
sx126x_chip_modes_t sx126x_get_state(const sx126x_t *dev)
{
sx126x_chip_status_t radio_status;
sx126x_get_status(dev, &radio_status);
return radio_status.chip_mode;
}
void sx126x_set_state(sx126x_t *dev, sx126x_chip_modes_t state)
{
switch (state) {
case SX126X_CHIP_MODE_TX:
sx126x_set_tx(dev, 0); /* no TX frame timeout */
break;
case SX126X_CHIP_MODE_RX: {
int timeout = (sx126x_symbol_to_msec(dev, dev->rx_timeout));
sx126x_set_rx_tx_fallback_mode(dev, SX126X_FALLBACK_STDBY_XOSC);
if (timeout > 0) {
sx126x_set_rx(dev, timeout);
}
else {
sx126x_set_rx(dev, SX126X_RX_SINGLE_MODE);
}
} break;
case SX126X_CHIP_MODE_STBY_RC:
case SX126X_CHIP_MODE_STBY_XOSC:
sx126x_set_standby(dev, state);
break;
default:
break;
}
}
uint32_t sx126x_get_channel(const sx126x_t *dev)
{
DEBUG("[sx126x]: sx126x_get_radio_status \n");
return dev->channel;
}
/* 9.2.1 Image Calibration for Specific Frequency Bands */
static void _cal_img(sx126x_t *dev, uint32_t freq)
{
sx126x_chip_modes_t state = sx126x_get_state(dev);
/* don't know what to do with frequencies that don't fit in the intervals from the datasheet */
if (freq >= MHZ(902) && freq <= MHZ(928)) {
/* 902 - 928 MHz band and anything upper */
sx126x_cal_img_in_mhz(dev, 902, 928);
}
else if (freq >= MHZ(863) && freq <= MHZ(870)) {
/* 863 - 870 MHz band */
sx126x_cal_img_in_mhz(dev, 863, 870);
}
else if (freq >= MHZ(779) && freq <= MHZ(787)) {
/* 779 - 787 MHz band */
sx126x_cal_img_in_mhz(dev, 779, 787);
}
else if (freq >= MHZ(470) && freq <= MHZ(510)) {
/* 470 - 510 MHz band */
sx126x_cal_img_in_mhz(dev, 470, 510);
}
else if (freq >= MHZ(430) && freq <= MHZ(440)) {
/* 430 - 440 MHz band and anything lower */
sx126x_cal_img_in_mhz(dev, 430, 440);
}
else {
/* Contact your Semtech representative for the other optimal calibration settings
outside of the given frequency bands. */
}
/* Image calibration sets the chip mode back to STBY_RC */
/* When using DIO3, TCXO switches off. */
sx126x_set_state(dev, state);
}
void sx126x_set_channel(sx126x_t *dev, uint32_t freq)
{
DEBUG("[sx126x]: sx126x_set_channel %" PRIu32 "Hz \n", freq);
dev->channel = freq;
sx126x_set_rf_freq(dev, dev->channel);
_cal_img(dev, freq);
}
uint8_t sx126x_get_bandwidth(const sx126x_t *dev)

View File

@ -206,16 +206,11 @@ static void _isr(netdev_t *netdev)
static int _get_state(sx126x_t *dev, void *val)
{
sx126x_chip_status_t radio_status;
sx126x_get_status(dev, &radio_status);
netopt_state_t state = NETOPT_STATE_OFF;
switch (radio_status.chip_mode) {
case SX126X_CHIP_MODE_RFU:
case SX126X_CHIP_MODE_STBY_RC:
case SX126X_CHIP_MODE_STBY_XOSC:
state = NETOPT_STATE_STANDBY;
netopt_state_t state;
sx126x_chip_modes_t mode = sx126x_get_state(dev);
switch (mode) {
case SX126X_CHIP_MODE_FS:
state = NETOPT_STATE_IDLE;
break;
case SX126X_CHIP_MODE_TX:
@ -227,6 +222,7 @@ static int _get_state(sx126x_t *dev, void *val)
break;
default:
state = NETOPT_STATE_STANDBY;
break;
}
memcpy(val, &state, sizeof(netopt_state_t));
@ -312,7 +308,7 @@ static int _set_state(sx126x_t *dev, netopt_state_t state)
switch (state) {
case NETOPT_STATE_STANDBY:
DEBUG("[sx126x] netdev: set NETOPT_STATE_STANDBY state\n");
sx126x_set_standby(dev, SX126X_CHIP_MODE_STBY_XOSC);
sx126x_set_state(dev, SX126X_CHIP_MODE_STBY_XOSC);
break;
case NETOPT_STATE_IDLE:
@ -324,14 +320,7 @@ static int _set_state(sx126x_t *dev, netopt_state_t state)
dev->params->set_rf_mode(dev, SX126X_RF_MODE_RX);
}
#endif
sx126x_cfg_rx_boosted(dev, true);
int _timeout = (sx126x_symbol_to_msec(dev, dev->rx_timeout));
if (_timeout != 0) {
sx126x_set_rx(dev, _timeout);
}
else {
sx126x_set_rx(dev, SX126X_RX_SINGLE_MODE);
}
sx126x_set_state(dev, SX126X_CHIP_MODE_RX);
break;
case NETOPT_STATE_TX:
@ -341,7 +330,7 @@ static int _set_state(sx126x_t *dev, netopt_state_t state)
dev->params->set_rf_mode(dev, dev->params->tx_pa_mode);
}
#endif
sx126x_set_tx(dev, 0);
sx126x_set_state(dev, SX126X_CHIP_MODE_TX);
break;
case NETOPT_STATE_RESET: