@@ -83,7 +83,7 @@ static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
8383static void fhss_ws_update_uc_channel_callback (fhss_structure_t * fhss_structure );
8484static void fhss_unicast_handler (const fhss_api_t * fhss_api , uint16_t delay );
8585static bool fhss_ws_check_tx_allowed (fhss_structure_t * fhss_structure );
86- static uint32_t fhss_set_txrx_slot_length (fhss_structure_t * fhss_structure );
86+ static void fhss_set_txrx_slot_length (fhss_structure_t * fhss_structure );
8787
8888// This function supports rounding up
8989static int64_t divide_integer (int64_t dividend , int32_t divisor )
@@ -150,7 +150,6 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
150150 fhss_ws_set_hop_count (fhss_struct , 0xff );
151151 fhss_struct -> rx_channel = fhss_configuration -> unicast_fixed_channel ;
152152 fhss_struct -> ws -> min_synch_interval = DEFAULT_MIN_SYNCH_INTERVAL ;
153- fhss_set_txrx_slot_length (fhss_struct );
154153 ns_list_init (& fhss_struct -> fhss_failed_tx_list );
155154 return fhss_struct ;
156155}
@@ -173,14 +172,46 @@ static int fhss_ws_manage_channel_table_allocation(fhss_structure_t *fhss_struct
173172 return 0 ;
174173}
175174
176- static uint32_t fhss_set_txrx_slot_length (fhss_structure_t * fhss_structure )
175+ static void fhss_set_txrx_slot_length (fhss_structure_t * fhss_structure )
177176{
178- uint32_t number_of_tx_slots = ((fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) / WS_MAX_TXRX_SLOT_LEN_MS ) / 2 ;
177+ // No broadcast schedule, no TX slots
178+ if (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval == 0 || fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval == 0 ) {
179+ return ;
180+ }
181+ uint32_t txrx_slot_length_ms_tmp = WS_TXRX_SLOT_LEN_MS ;
182+ if (fhss_structure -> callbacks .read_datarate ) {
183+ /* Calculate minimum TX slot length which can fit optimal packet length twice.
184+ * Twice, because 0, 1, 4, 5... hop starts transmission at the beginning of TX slot and 2, 3, 6, 7... hop at the middle of TX slot
185+ *
186+ * hop 0
187+ * tx'ing | | | | | |
188+ * | BC | RX | TX | RX | TX | RX | TX | BC |
189+ * hop 1
190+ * tx'ing | | | | | |
191+ * | BC | TX | RX | TX | RX | TX | RX | BC |
192+ * hop 2
193+ * tx'ing | | | | | |
194+ * | BC | RX | TX | RX | TX | RX | TX | BC |
195+ * hop 3
196+ * tx'ing | | | | | |
197+ * | BC | TX | RX | TX | RX | TX | RX | BC |
198+ */
199+ uint32_t datarate = fhss_structure -> callbacks .read_datarate (fhss_structure -> fhss_api );
200+ if (datarate ) {
201+ txrx_slot_length_ms_tmp = ((OPTIMAL_PACKET_LENGTH * 2 ) * (8000000 / datarate )) / 1000 ;
202+ }
203+ }
204+ uint32_t number_of_tx_slots = ((fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) / txrx_slot_length_ms_tmp ) / 2 ;
179205 if (!number_of_tx_slots ) {
180- return 0 ;
206+ return ;
181207 }
182208 fhss_structure -> ws -> txrx_slot_length_ms = (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) / (number_of_tx_slots * 2 );
183- return number_of_tx_slots ;
209+ tr_info ("TX slot length: %" PRIu32 "ms" , fhss_structure -> ws -> txrx_slot_length_ms );
210+ }
211+
212+ static uint32_t fhss_get_number_of_tx_slots (fhss_structure_t * fhss_structure )
213+ {
214+ return ((fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) / fhss_structure -> ws -> txrx_slot_length_ms ) / 2 ;
184215}
185216
186217static int32_t fhss_ws_calc_bc_channel (fhss_structure_t * fhss_structure )
@@ -397,7 +428,7 @@ static int16_t fhss_ws_synch_state_set_callback(const fhss_api_t *api, fhss_stat
397428 if (fhss_state == FHSS_SYNCHRONIZED ) {
398429 uint32_t fhss_broadcast_interval = fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval ;
399430 uint8_t fhss_bc_dwell_interval = fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ;
400-
431+ fhss_set_txrx_slot_length ( fhss_structure );
401432 // Start broadcast schedule when BC intervals are known
402433 if (fhss_broadcast_interval && fhss_bc_dwell_interval ) {
403434 fhss_broadcast_handler (fhss_structure -> fhss_api , 0 );
@@ -537,17 +568,30 @@ static bool fhss_ws_check_tx_allowed(fhss_structure_t *fhss_structure)
537568 if (fhss_structure -> ws -> is_on_bc_channel == true) {
538569 return true;
539570 }
540- uint32_t number_of_tx_slots = fhss_set_txrx_slot_length (fhss_structure );
571+ uint32_t number_of_tx_slots = fhss_get_number_of_tx_slots (fhss_structure );
541572 // Allow transmission when broadcast interval is very short comparing to MAX slot length
542573 if (!number_of_tx_slots ) {
543574 return true;
544575 }
545576
546577 uint32_t remaining_time_ms = get_remaining_slots_us (fhss_structure , fhss_broadcast_handler , MS_TO_US (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval )) / 1000 ;
547578 uint32_t tx_slot_begin_ms = (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) - (fhss_structure -> ws -> txrx_slot_length_ms * (fhss_structure -> own_hop & 1 ));
579+ /* Return false when our first TX slot has not yet started
580+ * |------remaining_time_ms---|
581+ * |
582+ * v
583+ * | BC | RX | TX | RX | TX | RX | TX | BC |
584+ */
585+ if (tx_slot_begin_ms < remaining_time_ms ) {
586+ return false;
587+ }
548588 tx_slot_begin_ms = tx_slot_begin_ms - (((tx_slot_begin_ms - remaining_time_ms ) / (2 * fhss_structure -> ws -> txrx_slot_length_ms )) * (2 * fhss_structure -> ws -> txrx_slot_length_ms ));
549589 uint32_t rx_slot_begin_ms = tx_slot_begin_ms - fhss_structure -> ws -> txrx_slot_length_ms ;
550- // Check if we are currently on TX slot.
590+ /* Check if we are currently on TX slot.
591+ * | | |
592+ * v v v
593+ * | BC | RX | TX | RX | TX | RX | TX | BC |
594+ */
551595 if ((remaining_time_ms <= tx_slot_begin_ms ) && (remaining_time_ms > rx_slot_begin_ms )) {
552596 return true;
553597 }
0 commit comments