diff --git a/CHANGELOG.md b/CHANGELOG.md index 428a1d0e..f4337a8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * Add user access to the `smtc_modem_factory_reset` function. * Add support for 2.4 Ghz multicast class C session frequency setting. +### Changed + +* Starting join bank can be set over SMTC modem API for regions that support this (AU915, US915) +* Subsequent join attempts cycle through all banks for regions that support this (AU915, US915) + ## [v4.8.0] 2024-12-20 This version is based on feature branch v4.5.0 of the LoRa Basics Modem. diff --git a/lbm_lib/smtc_modem_api/smtc_modem_api.h b/lbm_lib/smtc_modem_api/smtc_modem_api.h index bd131915..b016f5cf 100755 --- a/lbm_lib/smtc_modem_api/smtc_modem_api.h +++ b/lbm_lib/smtc_modem_api/smtc_modem_api.h @@ -1289,6 +1289,31 @@ smtc_modem_return_code_t smtc_modem_set_adr_ack_limit_delay( uint8_t stack_id, u smtc_modem_return_code_t smtc_modem_get_adr_ack_limit_delay( uint8_t stack_id, uint8_t* adr_ack_limit, uint8_t* adr_ack_delay ); +/** + * @brief Set the starting bank for join channel cycling + * + * @remark Join attempts cycle through banks sequentially, + * picking one random channel per bank on each attempt. This + * setting controls which bank the cycle starts from or join failure + * reset occurs. It also sets number of banks supported for used + * region. Only applicable to regions that use channel banks to + * choose next channel for join request (AU915, US915). + * Returns SMTC_MODEM_RC_INVALID for other regions or invalid bank. + * Default is 0 (LoRaWAN spec default). + * + * @param [in] stack_id Stack identifier + * @param [in] start_bank Starting bank index + * @param [in] p_bank_count Pointer to set value of number of banks supported + * + * @return Modem return code as defined in @ref smtc_modem_return_code_t + * @retval SMTC_MODEM_RC_OK Command executed without errors + * @retval SMTC_MODEM_RC_INVALID Invalid bank or unsupported region + * @retval SMTC_MODEM_RC_BUSY Modem is currently in test mode + * @retval SMTC_MODEM_RC_INVALID_STACK_ID Invalid \p stack_id + */ +smtc_modem_return_code_t smtc_modem_set_join_start_bank( uint8_t stack_id, + uint8_t start_bank, + uint8_t* p_bank_count); /* * ----------------------------------------------------------------------------- * ----------- BOARD MANAGEMENT MODEM FUNCTIONS -------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.c index 648b05f1..a2b9c02c 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.c @@ -166,7 +166,7 @@ void region_au_915_init( smtc_real_t* real ) memset( &unwrapped_channel_mask[0], 0xFF, BANK_MAX_AU915 ); memset( &snapshot_channel_tx_mask[0], 0xFF, BANK_MAX_AU915 ); - snapshot_bank_tx_mask = 0; + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; } void region_au_915_config( smtc_real_t* real ) @@ -453,7 +453,12 @@ void region_au_915_set_channel_mask( smtc_real_t* real ) void region_au_915_init_join_snapshot_channel_mask( smtc_real_t* real ) { memset( snapshot_channel_tx_mask, 0xFF, BANK_MAX_AU915 ); - snapshot_bank_tx_mask = 0; + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; +} + +void region_au_915_init_join_snapshot_bank_tx_mask( smtc_real_t* real ) +{ + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; } void region_au_915_init_after_join_snapshot_channel_mask( smtc_real_t* real, uint8_t tx_data_rate, diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.h index 4b68f02b..7646b1c5 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.h @@ -122,6 +122,13 @@ void region_au_915_set_channel_mask( smtc_real_t* real ); * \param [OUT] return */ void region_au_915_init_join_snapshot_channel_mask( smtc_real_t* real ); +/** + * \brief + * \remark + * \param [IN] none + * \param [OUT] return + */ +void region_au_915_init_join_snapshot_bank_tx_mask( smtc_real_t* real ); /** * \brief * \remark diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c index 8d1bfb4d..87112f83 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c @@ -164,7 +164,7 @@ void region_us_915_init( smtc_real_t* real ) memset( &unwrapped_channel_mask[0], 0xFF, BANK_MAX_US915 ); memset( &snapshot_channel_tx_mask[0], 0xFF, BANK_MAX_US915 ); - snapshot_bank_tx_mask = 0; + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; } void region_us_915_config( smtc_real_t* real ) @@ -450,7 +450,12 @@ void region_us_915_set_channel_mask( smtc_real_t* real ) void region_us_915_init_join_snapshot_channel_mask( smtc_real_t* real ) { memset( snapshot_channel_tx_mask, 0xFF, BANK_MAX_US915 ); - snapshot_bank_tx_mask = 0; + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; +} + +void region_us_915_init_join_snapshot_bank_tx_mask( smtc_real_t* real ) +{ + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; } void region_us_915_init_after_join_snapshot_channel_mask( smtc_real_t* real, uint8_t tx_data_rate, diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.h index ab7fe0fc..04af8aef 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.h @@ -122,6 +122,13 @@ void region_us_915_set_channel_mask( smtc_real_t* real ); * \param [OUT] return */ void region_us_915_init_join_snapshot_channel_mask( smtc_real_t* real ); +/** + * \brief + * \remark + * \param [IN] none + * \param [OUT] return + */ +void region_us_915_init_join_snapshot_bank_tx_mask( smtc_real_t* real ); /** * \brief * \remark diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c index f2fbe59d..b8075f0a 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c @@ -98,6 +98,7 @@ #define custom_dr_distribution_init_ctx real_ctx.custom_dr_distribution_init_ctx #define uplink_dwell_time_ctx real_ctx.uplink_dwell_time_ctx #define downlink_dwell_time_ctx real_ctx.downlink_dwell_time_ctx +#define join_start_bank_tx_mask real_ctx.join_start_bank_tx_mask smtc_real_status_t smtc_real_is_supported_region( smtc_real_region_types_t region_type ) { @@ -206,6 +207,7 @@ void smtc_real_init( smtc_real_t* real, smtc_real_region_types_t region_type ) } real_ctx.sync_word_ctx = real_const.const_sync_word_public; + join_start_bank_tx_mask = 0; } void smtc_real_config( smtc_real_t* real ) @@ -1020,6 +1022,65 @@ void smtc_real_init_join_snapshot_channel_mask( smtc_real_t* real ) } } +void smtc_real_init_join_snapshot_bank_tx_mask( smtc_real_t* real ) +{ + switch( real->region_type ) + { +#if defined( REGION_WW2G4 ) + case SMTC_REAL_REGION_WW2G4: +#endif +#if defined( REGION_EU_868 ) + case SMTC_REAL_REGION_EU_868: +#endif +#if defined( REGION_AS_923 ) + case SMTC_REAL_REGION_AS_923: + case SMTC_REAL_REGION_AS_923_GRP2: + case SMTC_REAL_REGION_AS_923_GRP3: +#if defined( RP2_103 ) + case SMTC_REAL_REGION_AS_923_GRP4: +#endif +#endif +#if defined( REGION_CN_470 ) + case SMTC_REAL_REGION_CN_470: +#endif +#if defined( REGION_CN_470_RP_1_0 ) + case SMTC_REAL_REGION_CN_470_RP_1_0: +#endif +#if defined( REGION_IN_865 ) + case SMTC_REAL_REGION_IN_865: +#endif +#if defined( REGION_KR_920 ) + case SMTC_REAL_REGION_KR_920: +#endif +#if defined( REGION_RU_864 ) + case SMTC_REAL_REGION_RU_864: +#endif +#if defined( REGION_WW2G4 ) || defined( REGION_EU_868 ) || defined( REGION_AS_923 ) || defined( REGION_CN_470 ) || \ + defined( REGION_CN_470_RP_1_0 ) || defined( REGION_IN_865 ) || defined( REGION_KR_920 ) || \ + defined( REGION_RU_864 ) + { + // Not used for these regions + break; + } +#endif +#if defined( REGION_US_915 ) + case SMTC_REAL_REGION_US_915: { + region_us_915_init_join_snapshot_bank_tx_mask( real ); + break; + } +#endif +#if defined( REGION_AU_915 ) + case SMTC_REAL_REGION_AU_915: { + region_au_915_init_join_snapshot_bank_tx_mask( real ); + break; + } +#endif + default: + SMTC_MODEM_HAL_PANIC( ); + break; + } +} + void smtc_real_init_after_join_snapshot_channel_mask( smtc_real_t* real, uint8_t tx_data_rate, uint32_t tx_frequency ) { switch( real->region_type ) diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.h index 829ce013..ef49bf0d 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.h @@ -231,6 +231,14 @@ void smtc_real_init_channel_mask( smtc_real_t* real ); */ void smtc_real_init_join_snapshot_channel_mask( smtc_real_t* real ); +/** + * \brief + * \remark + * \param [IN] none + * \param [OUT] return + */ +void smtc_real_init_join_snapshot_bank_tx_mask( smtc_real_t* real ); + /** * \brief * \remark diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real_defs.h index 5f497975..2be1630e 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real_defs.h @@ -236,6 +236,7 @@ typedef struct smtc_real_ctx_s uint8_t sync_word_ctx; bool uplink_dwell_time_ctx; bool downlink_dwell_time_ctx; + uint8_t join_start_bank_tx_mask; } smtc_real_ctx_t; typedef struct smtc_real_const_s diff --git a/lbm_lib/smtc_modem_core/smtc_modem.c b/lbm_lib/smtc_modem_core/smtc_modem.c index fac6a25e..3d8bfdc8 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem.c +++ b/lbm_lib/smtc_modem_core/smtc_modem.c @@ -1404,6 +1404,45 @@ smtc_modem_return_code_t smtc_modem_get_adr_ack_limit_delay( uint8_t stack_id, u return SMTC_MODEM_RC_OK; } +smtc_modem_return_code_t smtc_modem_set_join_start_bank( uint8_t stack_id, + uint8_t start_bank, + uint8_t* p_bank_count) +{ + RETURN_BUSY_IF_TEST_MODE( ); + + lr1_stack_mac_t* stack_mac = lorawan_api_stack_mac_get( stack_id ); + if( stack_mac == NULL ) + { + return SMTC_MODEM_RC_INVALID_STACK_ID; + } + + /* Only regions with channel banks support this setting */ + if( (stack_mac->real->region_type != SMTC_REAL_REGION_AU_915) && + (stack_mac->real->region_type != SMTC_REAL_REGION_US_915) ) + { + SMTC_MODEM_HAL_TRACE_WARNING( + "smtc_modem_set_join_start_bank: region does not support " + "channel bank cycling\n" ); + return SMTC_MODEM_RC_INVALID; + } + + /* Validate bank index against region's bank count */ + if( start_bank >= stack_mac->real->real_const.const_number_of_channel_bank ) + { + SMTC_MODEM_HAL_TRACE_WARNING( + "smtc_modem_set_join_start_bank: invalid bank %d for region, " + "max is %d\n", start_bank, + stack_mac->real->real_const.const_number_of_channel_bank - 1); + return SMTC_MODEM_RC_INVALID; + } + + *p_bank_count = stack_mac->real->real_const.const_number_of_channel_bank; + stack_mac->real->real_ctx.join_start_bank_tx_mask = start_bank; + smtc_real_init_join_snapshot_bank_tx_mask(stack_mac->real); + + return SMTC_MODEM_RC_OK; +} + /* * ----------------------------------------------------------------------------- * ----------- BOARD MANAGEMENT MODEM FUNCTIONS --------------------------------