diff --git a/.vscode/settings.json b/.vscode/settings.json index b5629450e0dc..f2c42d5328b9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,8 @@ "Makefile.*": "makefile", "*.mk": "makefile", "kernel_defines.h": "c", - "sx126x_internal.h": "c" + "sx126x_internal.h": "c", + "submac.h": "c" }, "[shellscript][c][cpp]": { "editor.tabSize": 4, diff --git a/boards/rak3172/Makefile.features b/boards/rak3172/Makefile.features index 42d19682ebeb..51bf625975c1 100644 --- a/boards/rak3172/Makefile.features +++ b/boards/rak3172/Makefile.features @@ -12,3 +12,6 @@ FEATURES_PROVIDED += periph_uart # Put other features for this board (in alphabetical order) FEATURES_PROVIDED += riotboot + +CFLAGS += -DCONFIG_IEEE802154_DEFAULT_SUBGHZ_CHANNEL=5 +CFLAGS += -DCONFIG_IEEE802154_DEFAULT_TXPOWER=22 diff --git a/boards/rak3172/include/board.h b/boards/rak3172/include/board.h index da1a689545ca..70922a5a9102 100644 --- a/boards/rak3172/include/board.h +++ b/boards/rak3172/include/board.h @@ -39,7 +39,6 @@ extern "C" { extern void lora_e5_dev_sx126x_set_rf_mode(sx126x_t *dev, sx126x_rf_mode_t rf_mode); #define SX126X_PARAM_SET_RF_MODE_CB lora_e5_dev_sx126x_set_rf_mode #define SX126X_PARAM_TYPE SX126X_TYPE_STM32WL -#define CONFIG_SX126X_TX_POWER_DEFAULT (22) #endif /** @} */ diff --git a/drivers/sx126x/sx126x_radio_hal.c b/drivers/sx126x/sx126x_radio_hal.c index 2551e8164639..14477e20df37 100644 --- a/drivers/sx126x/sx126x_radio_hal.c +++ b/drivers/sx126x/sx126x_radio_hal.c @@ -39,14 +39,13 @@ #include "sx126x_params.h" #include "sx126x_internal.h" -#define LORA_ACK_REPLY_US 1024 +#define LORA_ACK_REPLY_US 100 -#define SX126X_HAL_CHAN_26 (869525000LU) -#define SX126X_HAL_CHAN_BASE (865500000LU) +#define SX126X_HAL_CHAN_BASE (868100000LU) #define SX126X_HAL_CHAN_SPACING (200000LU) -#define SX126X_CHAN_MIN (11) -#define SX126X_CHAN_MAX (26) +#define SX126X_CHAN_MIN (IEEE802154_CHANNEL_MIN_SUBGHZ) +#define SX126X_CHAN_MAX (8) #define SX126X_POWER_MIN (-9) #define SX126X_POWER_MAX (22) @@ -80,7 +79,7 @@ void isr_subghz_radio(void) /* Disable NVIC to avoid ISR conflict in CPU. */ NVIC_DisableIRQ(SUBGHZ_Radio_IRQn); NVIC_ClearPendingIRQ(SUBGHZ_Radio_IRQn); - event_post(EVENT_PRIO_HIGHEST, &sx126x_ev); + event_post(EVENT_PRIO_MEDIUM, &sx126x_ev); cortexm_isr_end(); } #endif @@ -412,7 +411,7 @@ switch (op){ if (info) { info->status = (dev->cad_detected) ? TX_STATUS_MEDIUM_BUSY : TX_STATUS_SUCCESS; } - while(state == STATE_TX) + _get_state(dev, &state); break; @@ -438,7 +437,7 @@ switch (op){ } if (eagain) { - DEBUG("EAGAIN"); + return -EAGAIN; } @@ -503,16 +502,10 @@ static int _config_phy(ieee802154_dev_t *hal, const ieee802154_phy_conf_t *conf) sx126x_t *dev = hal->priv; uint8_t channel = conf->channel; int8_t pow = conf->pow; - if((channel < SX126X_CHAN_MIN) && (channel > SX126X_CHAN_MAX)) + if((channel > SX126X_CHAN_MAX)) return -EINVAL; - - if (channel == 26) { - sx126x_set_channel(dev, SX126X_HAL_CHAN_26); - } - else { - sx126x_set_channel(dev, (channel-11)*SX126X_HAL_CHAN_SPACING + SX126X_HAL_CHAN_BASE); - } - + + sx126x_set_channel(dev, (channel)*SX126X_HAL_CHAN_SPACING + SX126X_HAL_CHAN_BASE); if((pow < SX126X_POWER_MIN) && (pow > SX126X_POWER_MAX)) return -EINVAL; @@ -628,7 +621,7 @@ static int _set_csma_params(ieee802154_dev_t *hal, const ieee802154_csma_be_t *b static const ieee802154_radio_ops_t sx126x_ops = { - .caps = IEEE802154_CAP_24_GHZ + .caps = IEEE802154_CAP_SUB_GHZ | IEEE802154_CAP_IRQ_CRC_ERROR | IEEE802154_CAP_IRQ_RX_START | IEEE802154_CAP_IRQ_TX_DONE diff --git a/sys/include/net/ieee802154.h b/sys/include/net/ieee802154.h index 5b4393502d83..5d14655c2582 100644 --- a/sys/include/net/ieee802154.h +++ b/sys/include/net/ieee802154.h @@ -550,6 +550,16 @@ static inline uint8_t ieee802154_dbm_to_rssi(int16_t dbm) return val - IEEE802154_RADIO_RSSI_OFFSET; } +/** + * @brief Get the symbol time for a given PHY channel. + * + * @param[in] channel_page channel page + * @param[in] channel_num channel number + * + * @return the symbol time in us + */ +uint32_t ieee802154_get_symbol_time(uint8_t channel_page, uint16_t channel_num); + #ifdef __cplusplus } #endif diff --git a/sys/net/link_layer/ieee802154/ieee802154.c b/sys/net/link_layer/ieee802154/ieee802154.c index 9d51bc815843..3929bf6dd70c 100644 --- a/sys/net/link_layer/ieee802154/ieee802154.c +++ b/sys/net/link_layer/ieee802154/ieee802154.c @@ -19,6 +19,32 @@ #include "net/ieee802154.h" +#define ENABLE_DEBUG 0 +#include "debug.h" + +#define CHANNEL_868MHZ (0U) /**< channel associated to the 868 MHz band */ + +/** + * @brief O-QPSK symbol time definition + * @see IEEE 802.15.4-2015 standard, section 12.3.3 + */ +#define SYMTIME_OQPSK_868MHZ (40U) /**< 25 ksymbols/s */ +#define SYMTIME_OQPSK_COMMON (16U) /**< 62.5 ksymbols/s */ + +/** + * @brief BPSK symbol time definition + * @see IEEE 802.15.4-2015 standard, section 13.3.3 + */ +#define SYMTIME_BPSK_868MHZ (50U) /**< 20 ksymbols/s */ +#define SYMTIME_BPSK_COMMON (25U) /**< 40 ksymbols/s */ + +/** + * @brief ASK symbol time definition + * @see IEEE 802.15.4-2015 standard, section 14.4.3 + */ +#define SYMTIME_ASK_868MHZ (80U) /**< 12.5 ksymbols/s */ +#define SYMTIME_ASK_COMMON (20U) /**< 50 ksymbols/s */ + const uint8_t ieee802154_addr_bcast[IEEE802154_ADDR_BCAST_LEN] = IEEE802154_ADDR_BCAST; size_t ieee802154_set_frame_hdr(uint8_t *buf, const uint8_t *src, size_t src_len, @@ -281,4 +307,58 @@ int ieee802154_dst_filter(const uint8_t *mhr, uint16_t pan, return 1; } +static inline uint8_t _get_oqpsk_symbol_time(uint16_t channel) +{ + if (channel == CHANNEL_868MHZ) { + return SYMTIME_OQPSK_868MHZ; + } + return SYMTIME_OQPSK_COMMON; +} + +static inline uint8_t _get_ask_symbol_time(uint16_t channel) +{ + if (channel == CHANNEL_868MHZ) { + return SYMTIME_ASK_868MHZ; + } + return SYMTIME_ASK_COMMON; +} + +static inline uint8_t _get_bpsk_symbol_time(uint16_t channel) +{ + if (channel == CHANNEL_868MHZ) { + return SYMTIME_BPSK_868MHZ; + } + return SYMTIME_BPSK_COMMON; +} + +uint32_t ieee802154_get_symbol_time(uint8_t channel_page, uint16_t channel_num) +{ + /* BPSK for SubGHZ, O-QPSK for 2.4 GHz (see IEEE 802.15.4-2015 standard, section 10.1.2.2) */ + if (channel_page == 0) { + if (channel_num <= IEEE802154_CHANNEL_MAX_SUBGHZ) { + return _get_bpsk_symbol_time(channel_num); + } + else { + return _get_oqpsk_symbol_time(channel_num); + } + } + /* ASK for SubGHZ (see IEEE 802.15.4-2015 standard, section 10.1.2.2) */ + else if (channel_page == 1) { + if (channel_num <= IEEE802154_CHANNEL_MAX_SUBGHZ) { + return _get_ask_symbol_time(channel_num); + } + } + /* O-QPSK for SubGHZ (see IEEE 802.15.4-2015 standard, section 10.1.2.2) */ + else if (channel_page == 2) { + if (channel_num <= IEEE802154_CHANNEL_MAX_SUBGHZ) { + return _get_oqpsk_symbol_time(channel_num); + } + } + /* add more channel pages as needed */ + + DEBUG("[ieee802154]: ieee802154_get_symbol_time: invalid PHY config or PHY not implemented"); + assert(false); + return 0; +} + /** @} */ diff --git a/sys/net/link_layer/ieee802154/submac.c b/sys/net/link_layer/ieee802154/submac.c index c04e1692f826..56f2eb873349 100644 --- a/sys/net/link_layer/ieee802154/submac.c +++ b/sys/net/link_layer/ieee802154/submac.c @@ -27,9 +27,9 @@ #define ENABLE_DEBUG 0 #include "debug.h" -#define CSMA_SENDER_BACKOFF_PERIOD_UNIT_US (320U) -//#define ACK_TIMEOUT_US (864U) -#define ACK_TIMEOUT_US (50000U) +#define CSMA_SENDER_BACKOFF_PERIOD_UNIT_US (320U) +#define ACK_TIMEOUT_SYMS (54U) + static char *str_states[IEEE802154_FSM_STATE_NUMOF] = { "INVALID", "RX", @@ -282,7 +282,9 @@ static ieee802154_fsm_state_t _fsm_state_tx_process_tx_done(ieee802154_submac_t assert (res >= 0); /* Handle ACK reception */ - ieee802154_submac_ack_timer_set(submac, ACK_TIMEOUT_US); + uint8_t symbol_time = ieee802154_get_symbol_time(submac->channel_page, + submac->channel_num); + ieee802154_submac_ack_timer_set(submac, symbol_time * ACK_TIMEOUT_SYMS); return IEEE802154_FSM_STATE_WAIT_FOR_ACK; } break;