@@ -57,9 +57,11 @@ struct ws_ie_t {
57
57
uint8_t id ;
58
58
};
59
59
60
+ static void fhss_event_timer_cb (int8_t timer_id , uint16_t slots );
60
61
static void fhss_ws_update_uc_channel_callback (fhss_structure_t * fhss_structure );
61
62
static void fhss_unicast_handler (const fhss_api_t * fhss_api , uint16_t delay );
62
- static void fhss_ws_start_tx_poll_timer (fhss_structure_t * fhss_structure , uint16_t queue_size , uint8_t channel_dwell_interval );
63
+ static bool fhss_ws_check_tx_allowed (fhss_structure_t * fhss_structure );
64
+ static uint8_t fhss_set_txrx_slot_length (fhss_structure_t * fhss_structure );
63
65
64
66
fhss_structure_t * fhss_ws_enable (fhss_api_t * fhss_api , const fhss_ws_configuration_t * fhss_configuration , const fhss_timer_t * fhss_timer )
65
67
{
@@ -83,13 +85,25 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
83
85
}
84
86
memset (fhss_struct -> ws , 0 , sizeof (fhss_ws_t ));
85
87
88
+ fhss_struct -> fhss_event_timer = eventOS_callback_timer_register (fhss_event_timer_cb );
86
89
fhss_struct -> ws -> fhss_configuration = * fhss_configuration ;
87
90
fhss_struct -> number_of_channels = channel_count ;
88
91
fhss_struct -> own_hop = 0xff ;
92
+ fhss_set_txrx_slot_length (fhss_struct );
89
93
ns_list_init (& fhss_struct -> fhss_failed_tx_list );
90
94
return fhss_struct ;
91
95
}
92
96
97
+ static uint8_t fhss_set_txrx_slot_length (fhss_structure_t * fhss_structure )
98
+ {
99
+ uint8_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 ;
100
+ if (!number_of_tx_slots ) {
101
+ return 0 ;
102
+ }
103
+ 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 );
104
+ return number_of_tx_slots ;
105
+ }
106
+
93
107
static int32_t fhss_ws_calc_bc_channel (fhss_structure_t * fhss_structure )
94
108
{
95
109
int32_t next_channel = fhss_structure -> rx_channel ;
@@ -130,12 +144,37 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
130
144
fhss_start_timer (fhss_structure , fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval * 1000 - (delay * fhss_structure -> platform_functions .fhss_resolution_divider ), fhss_broadcast_handler );
131
145
fhss_structure -> ws -> is_on_bc_channel = true;
132
146
next_channel = fhss_structure -> ws -> bc_channel = fhss_ws_calc_bc_channel (fhss_structure );
147
+
148
+ /* Start timer with random timeout to trigger broadcast TX queue poll event.
149
+ * Min random is 1/50 of the channel dwell interval.
150
+ * Max random is 1/10 of the channel dwell interval.
151
+ * Event timer resolution is 50us.
152
+ */
153
+ uint32_t bc_dwell_us = fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval * 1000 ;
154
+ uint16_t bc_min_random = (bc_dwell_us / 50 ) / 50 ;
155
+ uint16_t bc_max_random = (bc_dwell_us / 10 ) / 50 ;
156
+ eventOS_callback_timer_start (fhss_structure -> fhss_event_timer , randLIB_get_random_in_range (bc_min_random , bc_max_random ));
133
157
} else {
134
158
uint32_t timeout = (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) * 1000 ;
135
159
fhss_start_timer (fhss_structure , timeout - (delay * fhss_structure -> platform_functions .fhss_resolution_divider ), fhss_broadcast_handler );
136
160
fhss_structure -> ws -> is_on_bc_channel = false;
137
161
// Should return to own (unicast) listening channel after broadcast channel
138
162
next_channel = fhss_structure -> rx_channel ;
163
+ /* Start timer with random timeout to trigger unicast TX queue poll event.
164
+ * Min random is 50us.
165
+ * Max random is 1/10 of the TX slot length.
166
+ * Event timer resolution is 50us.
167
+ */
168
+ uint32_t txrx_slot_length_us = fhss_structure -> ws -> txrx_slot_length_ms * 1000 ;
169
+ uint16_t uc_min_random = 1 ;
170
+ uint16_t uc_max_random = (txrx_slot_length_us / 10 ) / 50 ;
171
+ bool tx_allowed = fhss_ws_check_tx_allowed (fhss_structure );
172
+ if (!tx_allowed ) {
173
+ uc_min_random += (txrx_slot_length_us )/50 ;
174
+ uc_max_random += (txrx_slot_length_us )/50 ;
175
+ }
176
+ eventOS_callback_timer_start (fhss_structure -> fhss_event_timer , randLIB_get_random_in_range (uc_min_random , uc_max_random ));
177
+
139
178
#ifdef FHSS_CHANNEL_DEBUG
140
179
tr_info ("%" PRIu32 " UC %u" , fhss_structure -> platform_functions .fhss_get_timestamp (fhss_structure -> fhss_api ), fhss_structure -> rx_channel );
141
180
#endif /*FHSS_CHANNEL_DEBUG*/
@@ -146,8 +185,6 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
146
185
fhss_bc_switch ();
147
186
}
148
187
#endif /*FHSS_CHANNEL_DEBUG_CBS*/
149
- fhss_ws_start_tx_poll_timer (fhss_structure , fhss_structure -> callbacks .read_tx_queue_size (fhss_structure -> fhss_api , true),
150
- fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval );
151
188
}
152
189
153
190
static int own_floor (float value )
@@ -164,6 +201,28 @@ static int own_ceil(float value)
164
201
return ivalue + 1 ;
165
202
}
166
203
204
+ static void fhss_event_timer_cb (int8_t timer_id , uint16_t slots )
205
+ {
206
+ (void ) slots ;
207
+ uint16_t queue_size = 0 ;
208
+ fhss_structure_t * fhss_structure = fhss_get_object_with_timer_id (timer_id );
209
+
210
+
211
+ if (fhss_structure -> ws -> is_on_bc_channel == true) {
212
+ queue_size = fhss_structure -> callbacks .read_tx_queue_size (fhss_structure -> fhss_api , true);
213
+ } else {
214
+ // On unicast, start timer to trigger polling event on next TX slot
215
+ uint32_t delay_between_tx_slots_us = fhss_structure -> ws -> txrx_slot_length_ms * 1000 * 2 ;
216
+ if (delay_between_tx_slots_us < fhss_structure -> platform_functions .fhss_get_remaining_slots (fhss_broadcast_handler , fhss_structure -> fhss_api )) {
217
+ eventOS_callback_timer_start (fhss_structure -> fhss_event_timer , delay_between_tx_slots_us /50 );
218
+ }
219
+ queue_size = fhss_structure -> callbacks .read_tx_queue_size (fhss_structure -> fhss_api , false);
220
+ }
221
+ if (queue_size ) {
222
+ fhss_structure -> callbacks .tx_poll (fhss_structure -> fhss_api );
223
+ }
224
+ }
225
+
167
226
static uint32_t fhss_ws_calculate_ufsi (fhss_structure_t * fhss_structure , uint32_t tx_time )
168
227
{
169
228
uint8_t dwell_time = fhss_structure -> ws -> fhss_configuration .fhss_uc_dwell_interval ;
@@ -348,23 +407,22 @@ static bool fhss_ws_check_tx_allowed(fhss_structure_t *fhss_structure)
348
407
if (fhss_structure -> ws -> is_on_bc_channel == true) {
349
408
return true;
350
409
}
351
- uint8_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 ;
410
+ uint8_t number_of_tx_slots = fhss_set_txrx_slot_length ( fhss_structure ) ;
352
411
// Allow transmission when broadcast interval is very short comparing to MAX slot length
353
412
if (!number_of_tx_slots ) {
354
413
return true;
355
414
}
356
- uint32_t slot_len_ms = (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) / (number_of_tx_slots * 2 );
357
415
uint32_t remaining_time_ms = fhss_structure -> platform_functions .fhss_get_remaining_slots (fhss_broadcast_handler , fhss_structure -> fhss_api ) / 1000 ;
358
- uint32_t tx_slot_begin = (fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval - fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) - (slot_len_ms * (fhss_structure -> own_hop & 1 ));
359
- uint32_t rx_slot_begin = tx_slot_begin - slot_len_ms ;
416
+ uint32_t tx_slot_begin = (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 ));
417
+ uint32_t rx_slot_begin = tx_slot_begin - fhss_structure -> ws -> txrx_slot_length_ms ;
360
418
uint8_t n_o_tx_slots = number_of_tx_slots ;
361
419
362
420
while (n_o_tx_slots -- ) {
363
421
if ((remaining_time_ms <= tx_slot_begin ) && (remaining_time_ms > rx_slot_begin )) {
364
422
return true;
365
423
}
366
- tx_slot_begin -= (2 * slot_len_ms );
367
- rx_slot_begin = tx_slot_begin - slot_len_ms ;
424
+ tx_slot_begin -= (2 * fhss_structure -> ws -> txrx_slot_length_ms );
425
+ rx_slot_begin = tx_slot_begin - fhss_structure -> ws -> txrx_slot_length_ms ;
368
426
}
369
427
370
428
return false;
@@ -564,24 +622,12 @@ static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay)
564
622
timeout = fhss_ws_get_sf_timeout_callback (fhss_structure );
565
623
fhss_start_timer (fhss_structure , timeout - (delay * fhss_structure -> platform_functions .fhss_resolution_divider ), fhss_unicast_handler );
566
624
fhss_ws_update_uc_channel_callback (fhss_structure );
567
- fhss_ws_start_tx_poll_timer (fhss_structure , fhss_structure -> callbacks .read_tx_queue_size (fhss_structure -> fhss_api , false),
568
- fhss_structure -> ws -> fhss_configuration .fhss_uc_dwell_interval );
569
- }
570
-
571
- static void fhss_ws_start_tx_poll_timer (fhss_structure_t * fhss_structure , uint16_t queue_size , uint8_t channel_dwell_interval )
572
- {
573
- if (!queue_size ) {
574
- return ;
625
+ // Unless we have broadcast schedule, we have to poll unicast queue when changing channel. This is randomized by the unicast schedule.
626
+ if (!fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval || !fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval ) {
627
+ if (fhss_structure -> callbacks .read_tx_queue_size (fhss_structure -> fhss_api , false)) {
628
+ fhss_structure -> callbacks .tx_poll (fhss_structure -> fhss_api );
629
+ }
575
630
}
576
- /* Start timer with random timeout to trigger TX queue poll event.
577
- * Min random is 1/50 of the channel dwell interval.
578
- * Max random is 1/10 of the channel dwell interval.
579
- * Event timer resolution is 50us.
580
- * Divide random with TX queue size to transmit faster when TX queue is growing
581
- */
582
- uint16_t min_random = ((((uint32_t )channel_dwell_interval * 1000 ) / 50 ) / 50 ) / queue_size ;
583
- uint16_t max_random = ((((uint32_t )channel_dwell_interval * 1000 ) / 10 ) / 50 ) / queue_size ;
584
- eventOS_callback_timer_start (fhss_structure -> fhss_event_timer , randLIB_get_random_in_range (min_random , max_random ));
585
631
}
586
632
587
633
int fhss_ws_set_callbacks (fhss_structure_t * fhss_structure )
@@ -623,6 +669,7 @@ int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8],
623
669
// TODO: Calculate drift error
624
670
fhss_structure -> ws -> fhss_configuration .fhss_bc_dwell_interval = bc_timing_info -> broadcast_dwell_interval ;
625
671
fhss_structure -> ws -> fhss_configuration .fhss_broadcast_interval = bc_timing_info -> broadcast_interval ;
672
+ fhss_set_txrx_slot_length (fhss_structure );
626
673
fhss_structure -> ws -> bc_slot = bc_timing_info -> broadcast_slot + slots_since_reception ;
627
674
628
675
//TODO: support multiple parents
0 commit comments