Skip to content

Commit 628fa27

Browse files
author
Jarkko Paso
authored
Merge pull request ARMmbed#1885 from ARMmbed/IOTTHD-2752
Iotthd 2752
2 parents cfea7b2 + 766e305 commit 628fa27

File tree

1 file changed

+56
-33
lines changed

1 file changed

+56
-33
lines changed

source/Service_Libs/fhss/fhss_ws.c

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,18 @@
4242
void (*fhss_uc_switch)(void) = NULL;
4343
void (*fhss_bc_switch)(void) = NULL;
4444
#endif /*FHSS_CHANNEL_DEBUG_CBS*/
45-
45+
// Seconds to milliseconds
46+
#define S_TO_MS(x) (((uint32_t)x)*1000)
47+
// Milliseconds to seconds
48+
#define MS_TO_S(x) divide_integer(x, 1000)
49+
// Seconds to microseconds
50+
#define S_TO_US(x) (((uint32_t)x)*1000000)
51+
// Microseconds to seconds
52+
#define US_TO_S(x) divide_integer(x, 1000000)
53+
// Milliseconds to microseconds
54+
#define MS_TO_US(x) (((uint32_t)x)*1000)
55+
// Microseconds to milliseconds
56+
#define US_TO_MS(x) divide_integer(x, 1000)
4657
#define DEF_2E24 0x1000000
4758
#define IE_HEADER_LENGTH_MASK 0x007f
4859
#define IE_HEADER_ID_MASK 0x7f80
@@ -71,6 +82,16 @@ static uint32_t divide_integer(uint32_t dividend, uint32_t divisor)
7182
return (dividend + divisor/2) / divisor;
7283
}
7384

85+
static uint32_t get_remaining_slots_us(fhss_structure_t *fhss_structure, void (*callback)(const fhss_api_t *api, uint16_t), uint32_t max_timeout_us)
86+
{
87+
uint32_t remaining_time_us = fhss_structure->platform_functions.fhss_get_remaining_slots(callback, fhss_structure->fhss_api);
88+
// When remaining time goes negative, use 0.
89+
if (remaining_time_us > max_timeout_us) {
90+
remaining_time_us = 0;
91+
}
92+
return remaining_time_us;
93+
}
94+
7495
fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer)
7596
{
7697
if (!fhss_api || !fhss_configuration || !fhss_timer) {
@@ -156,7 +177,7 @@ static int32_t fhss_ws_calc_bc_channel(fhss_structure_t *fhss_structure)
156177
}
157178
}
158179
#ifdef FHSS_CHANNEL_DEBUG
159-
tr_info("%"PRIu32" BC %u %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), next_channel, fhss_structure->ws->bc_slot);
180+
tr_info("%"PRIu32" BC %u %u", fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api), next_channel, fhss_structure->ws->bc_slot);
160181
#endif /*FHSS_CHANNEL_DEBUG*/
161182
return next_channel;
162183
}
@@ -175,7 +196,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
175196
return;
176197
}
177198
if (fhss_structure->ws->is_on_bc_channel == false) {
178-
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);
199+
fhss_start_timer(fhss_structure, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
179200
fhss_structure->ws->is_on_bc_channel = true;
180201
next_channel = fhss_structure->ws->bc_channel = fhss_ws_calc_bc_channel(fhss_structure);
181202

@@ -184,12 +205,12 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
184205
* Max random is 1/10 of the channel dwell interval.
185206
* Event timer resolution is 50us.
186207
*/
187-
uint32_t bc_dwell_us = fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval*1000;
208+
uint32_t bc_dwell_us = MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval);
188209
uint16_t bc_min_random = (bc_dwell_us / 50) / 50;
189210
uint16_t bc_max_random = (bc_dwell_us / 10) / 50;
190211
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(bc_min_random, bc_max_random));
191212
} else {
192-
uint32_t timeout = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) * 1000;
213+
uint32_t timeout = MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval);
193214
fhss_start_timer(fhss_structure, timeout - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
194215
fhss_structure->ws->is_on_bc_channel = false;
195216
// Should return to own (unicast) listening channel after broadcast channel
@@ -199,7 +220,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
199220
* Max random is 1/10 of the TX slot length.
200221
* Event timer resolution is 50us.
201222
*/
202-
uint32_t txrx_slot_length_us = fhss_structure->ws->txrx_slot_length_ms * 1000;
223+
uint32_t txrx_slot_length_us = MS_TO_US(fhss_structure->ws->txrx_slot_length_ms);
203224
uint16_t uc_min_random = (txrx_slot_length_us / 30) / 50;
204225
uint16_t uc_max_random = (txrx_slot_length_us / 10) / 50;
205226
bool tx_allowed = fhss_ws_check_tx_allowed(fhss_structure);
@@ -210,7 +231,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
210231
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(uc_min_random, uc_max_random));
211232

212233
#ifdef FHSS_CHANNEL_DEBUG
213-
tr_info("%"PRIu32" UC %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), fhss_structure->rx_channel);
234+
tr_info("%"PRIu32" UC %u", fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api), fhss_structure->rx_channel);
214235
#endif /*FHSS_CHANNEL_DEBUG*/
215236
}
216237
fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, next_channel);
@@ -246,8 +267,8 @@ static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots)
246267
queue_size = fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, true);
247268
} else {
248269
// On unicast, start timer to trigger polling event on next TX slot
249-
uint32_t delay_between_tx_slots_us = fhss_structure->ws->txrx_slot_length_ms*1000*2;
250-
if (delay_between_tx_slots_us < fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api)) {
270+
uint32_t delay_between_tx_slots_us = MS_TO_US(fhss_structure->ws->txrx_slot_length_ms)*2;
271+
if (delay_between_tx_slots_us < get_remaining_slots_us(fhss_structure, fhss_broadcast_handler, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval))) {
251272
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, delay_between_tx_slots_us/50);
252273
}
253274
queue_size = fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, false);
@@ -265,16 +286,13 @@ static uint32_t fhss_ws_calculate_ufsi(fhss_structure_t *fhss_structure, uint32_
265286
cur_slot = fhss_structure->number_of_channels;
266287
}
267288
cur_slot--;
268-
uint32_t remaining_time = (fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_unicast_handler, fhss_structure->fhss_api) / 1000);
269-
if (remaining_time > dwell_time) {
270-
remaining_time = 0;
271-
}
289+
uint32_t remaining_time_ms = US_TO_MS(get_remaining_slots_us(fhss_structure, fhss_unicast_handler, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval)));
272290
uint32_t time_to_tx = 0;
273291
uint32_t cur_time = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
274292
if (cur_time < tx_time) {
275-
time_to_tx = (tx_time - cur_time) / 1000;
293+
time_to_tx = US_TO_MS(tx_time - cur_time);
276294
}
277-
uint64_t ms_since_seq_start = (cur_slot * dwell_time) + (dwell_time-remaining_time) + time_to_tx;
295+
uint64_t ms_since_seq_start = (cur_slot * dwell_time) + (dwell_time-remaining_time_ms) + time_to_tx;
278296
uint32_t seq_length = 0x10000;
279297
if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_TR51CF) {
280298
ms_since_seq_start %= (dwell_time*fhss_structure->number_of_channels);
@@ -287,17 +305,16 @@ static uint32_t fhss_ws_calculate_broadcast_interval_offset(fhss_structure_t *fh
287305
{
288306
uint8_t dwell_time = fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval;
289307
uint32_t broadcast_interval = fhss_structure->ws->fhss_configuration.fhss_broadcast_interval;
290-
291-
uint32_t remaining_time = divide_integer(fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api), 1000);
308+
uint32_t remaining_time_ms = US_TO_MS(get_remaining_slots_us(fhss_structure, fhss_broadcast_handler, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval)));
292309
if (fhss_structure->ws->is_on_bc_channel == true) {
293-
remaining_time += (broadcast_interval - dwell_time);
310+
remaining_time_ms += (broadcast_interval - dwell_time);
294311
}
295312
uint32_t time_to_tx = 0;
296313
uint32_t cur_time = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
297314
if (cur_time < tx_time) {
298-
time_to_tx = divide_integer(tx_time - cur_time, 1000);
315+
time_to_tx = US_TO_MS(tx_time - cur_time);
299316
}
300-
return (broadcast_interval-remaining_time) + time_to_tx;
317+
return (broadcast_interval-remaining_time_ms) + time_to_tx;
301318
}
302319

303320
static uint16_t fhss_ws_calculate_destination_slot(fhss_ws_neighbor_timing_info_t *neighbor_timing_info, uint32_t tx_time)
@@ -310,12 +327,12 @@ static uint16_t fhss_ws_calculate_destination_slot(fhss_ws_neighbor_timing_info_
310327
seq_length = neighbor_timing_info->uc_timing_info.unicast_number_of_channels;
311328
}
312329
uint32_t dest_ms_since_seq_start = own_ceil((float)((uint64_t)ufsi*seq_length*dwell_time) / DEF_2E24);
313-
return (own_floor(((float)((tx_time - ufsi_timestamp)/1000 + dest_ms_since_seq_start) / dwell_time)) % seq_length);
330+
return (own_floor(((float)(US_TO_MS(tx_time - ufsi_timestamp) + dest_ms_since_seq_start) / dwell_time)) % seq_length);
314331
}
315332

316333
static uint32_t fhss_ws_get_sf_timeout_callback(fhss_structure_t *fhss_structure)
317334
{
318-
return fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval * 1000;
335+
return MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval);
319336
}
320337

321338
static int16_t fhss_ws_synch_state_set_callback(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id)
@@ -336,7 +353,7 @@ static int16_t fhss_ws_synch_state_set_callback(const fhss_api_t *api, fhss_stat
336353
// Start unicast schedule
337354
if ((fhss_structure->ws->fhss_configuration.ws_uc_channel_function != WS_FIXED_CHANNEL)) {
338355
fhss_ws_update_uc_channel_callback(fhss_structure);
339-
fhss_start_timer(fhss_structure, fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval*1000, fhss_unicast_handler);
356+
fhss_start_timer(fhss_structure, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval), fhss_unicast_handler);
340357
fhss_structure->ws->unicast_timer_running = true;
341358
}
342359
}
@@ -374,7 +391,7 @@ static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure)
374391
return;
375392
}
376393
#ifdef FHSS_CHANNEL_DEBUG
377-
tr_info("%"PRIu32" UC %u %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), next_channel, fhss_structure->ws->uc_slot);
394+
tr_info("%"PRIu32" UC %u %u", fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api), next_channel, fhss_structure->ws->uc_slot);
378395
#endif /*FHSS_CHANNEL_DEBUG*/
379396
fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, next_channel);
380397
#ifdef FHSS_CHANNEL_DEBUG_CBS
@@ -466,7 +483,8 @@ static bool fhss_ws_check_tx_allowed(fhss_structure_t *fhss_structure)
466483
if (!number_of_tx_slots) {
467484
return true;
468485
}
469-
uint32_t remaining_time_ms = fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api) / 1000;
486+
487+
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;
470488
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));
471489
uint32_t rx_slot_begin = tx_slot_begin - fhss_structure->ws->txrx_slot_length_ms;
472490
uint8_t n_o_tx_slots = number_of_tx_slots;
@@ -488,8 +506,8 @@ static bool fhss_ws_check_tx_time(fhss_structure_t *fhss_structure, uint16_t tx_
488506
return true;
489507
}
490508
uint32_t tx_time = fhss_get_tx_time(fhss_structure, tx_length, phy_header_length, phy_tail_length);
491-
uint32_t time_to_bc_channel = fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api);
492-
if (tx_time > time_to_bc_channel) {
509+
uint32_t time_to_bc_channel_us = get_remaining_slots_us(fhss_structure, fhss_broadcast_handler, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_broadcast_interval));
510+
if (tx_time > time_to_bc_channel_us) {
493511
return false;
494512
}
495513
return true;
@@ -709,21 +727,23 @@ int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8],
709727
if (!bc_timing_info->broadcast_interval || !bc_timing_info->broadcast_dwell_interval) {
710728
return -1;
711729
}
712-
if ((((uint32_t)fhss_structure->ws->min_synch_interval*1000000) > (fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) - fhss_structure->ws->synchronization_time)) && !force_synch) {
730+
if ((S_TO_US(fhss_structure->ws->min_synch_interval) > (fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) - fhss_structure->ws->synchronization_time)) && !force_synch) {
713731
return 0;
714732
}
715-
fhss_structure->ws->synchronization_time = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
716733
platform_enter_critical();
734+
uint32_t prev_synchronization_time = fhss_structure->ws->synchronization_time;
735+
fhss_structure->ws->synchronization_time = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
736+
uint32_t own_bc_interval_offset = fhss_ws_calculate_broadcast_interval_offset(fhss_structure, fhss_structure->ws->synchronization_time);
717737
fhss_stop_timer(fhss_structure, fhss_broadcast_handler);
718-
uint32_t time_from_reception_ms = divide_integer(fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) - bc_timing_info->bt_rx_timestamp, 1000);
738+
uint32_t time_from_reception_ms = US_TO_MS(fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) - bc_timing_info->bt_rx_timestamp);
719739
uint32_t true_bc_interval_offset = (bc_timing_info->broadcast_interval_offset + time_from_reception_ms) % bc_timing_info->broadcast_interval;
720740
if (true_bc_interval_offset >= bc_timing_info->broadcast_dwell_interval) {
721741
fhss_structure->ws->is_on_bc_channel = false;
722742
}
723-
uint32_t timeout = ((bc_timing_info->broadcast_interval-true_bc_interval_offset)*1000);
743+
uint32_t timeout = MS_TO_US(bc_timing_info->broadcast_interval-true_bc_interval_offset);
724744

725745
if (fhss_structure->ws->is_on_bc_channel) {
726-
timeout -= ((bc_timing_info->broadcast_interval - bc_timing_info->broadcast_dwell_interval) *1000);
746+
timeout -= MS_TO_US(bc_timing_info->broadcast_interval-bc_timing_info->broadcast_dwell_interval);
727747
}
728748
fhss_start_timer(fhss_structure, timeout, fhss_broadcast_handler);
729749
uint16_t slots_since_reception = (bc_timing_info->broadcast_interval_offset + time_from_reception_ms) / bc_timing_info->broadcast_interval;
@@ -738,6 +758,9 @@ int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8],
738758
platform_exit_critical();
739759
//TODO: support multiple parents
740760
fhss_structure->ws->parent_bc_info = bc_timing_info;
761+
if (prev_synchronization_time) {
762+
tr_debug("synch to parent: %s, drift: %ims in %u seconds", trace_array(eui64, 8), true_bc_interval_offset-own_bc_interval_offset, US_TO_S(fhss_structure->ws->synchronization_time-prev_synchronization_time));
763+
}
741764
return 0;
742765
}
743766

@@ -763,7 +786,7 @@ int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_co
763786
fhss_structure->ws->unicast_timer_running = false;
764787
}
765788
if ((fhss_structure->ws->unicast_timer_running == false) && (fhss_configuration->ws_uc_channel_function != WS_FIXED_CHANNEL) && fhss_configuration->fhss_uc_dwell_interval) {
766-
fhss_start_timer(fhss_structure, fhss_configuration->fhss_uc_dwell_interval*1000, fhss_unicast_handler);
789+
fhss_start_timer(fhss_structure, MS_TO_US(fhss_configuration->fhss_uc_dwell_interval), fhss_unicast_handler);
767790
fhss_structure->ws->unicast_timer_running = true;
768791
}
769792
fhss_structure->ws->fhss_configuration = *fhss_configuration;

0 commit comments

Comments
 (0)