Skip to content

Commit

Permalink
Merge pull request ARMmbed#2638 from PelionIoT/mbed_os_fix_ufsi_calcu…
Browse files Browse the repository at this point in the history
…lation

(via Mbed OS) Correct ufsi timing calculation
  • Loading branch information
Arto Kinnunen authored Jun 14, 2021
2 parents 560619d + 2012347 commit 04de6e2
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 8 deletions.
33 changes: 27 additions & 6 deletions source/Service_Libs/fhss/fhss_ws.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,16 +499,37 @@ static uint32_t fhss_ws_calculate_ufsi(fhss_structure_t *fhss_structure, uint32_
}
}
cur_slot--;
uint32_t remaining_time_ms = 0;
if (fhss_structure->ws->unicast_timer_running == true) {
remaining_time_ms = US_TO_MS(get_remaining_slots_us(fhss_structure, fhss_unicast_handler, MS_TO_US(dwell_time) - NS_TO_US((int64_t)(fhss_structure->ws->drift_per_millisecond_ns * dwell_time))));
}

uint32_t time_to_tx = 0;
uint32_t cur_time = fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api);
if (cur_time < tx_time) {
// High time to TX value (1000ms) is because actual TX time already passed.
if (US_TO_MS(tx_time - cur_time) < 1000) {
time_to_tx = US_TO_MS(tx_time - cur_time);
}
uint64_t ms_since_seq_start = (cur_slot * dwell_time) + (dwell_time - remaining_time_ms) + time_to_tx;
uint64_t ms_since_seq_start;
if (fhss_structure->ws->unicast_timer_running == true) {
// Allow timer interrupt to delay max 10 seconds, otherwise assume next_uc_timeout overflowed
if ((fhss_structure->ws->next_uc_timeout < cur_time) && ((cur_time - fhss_structure->ws->next_uc_timeout) < 10000000)) {
// The unicast timer has already expired, so count all previous slots
// plus 1 completed slot
// plus the time from timer expiration to now
// plus the time until Tx
ms_since_seq_start = ((cur_slot + 1) * dwell_time) + US_TO_MS(cur_time - fhss_structure->ws->next_uc_timeout) + time_to_tx;
} else {
// The unicast timer is still running, so count all previous slots
// plus the remaining time in the slot
// plus the time until Tx
uint32_t remaining_time_ms = US_TO_MS(fhss_structure->ws->next_uc_timeout - cur_time);
ms_since_seq_start = (cur_slot * dwell_time) + (dwell_time - remaining_time_ms) + time_to_tx;
}
} else {
// The unicast timer is not running. Act as if the slot has completed.
// count all previous slots
// plus 1 completed slot
// plus the time until Tx
ms_since_seq_start = ((cur_slot + 1) * dwell_time) + time_to_tx;
}

uint32_t seq_length = 0x10000;
if (fhss_structure->ws->fhss_configuration.ws_uc_channel_function == WS_TR51CF) {
ms_since_seq_start %= (dwell_time * fhss_structure->number_of_uc_channels);
Expand Down
56 changes: 54 additions & 2 deletions test/nanostack/unittest/service_libs/fhss_ws/test_fhss_ws.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,13 +648,36 @@ bool test_fhss_ws_synch_state_set_callback()
return true;
}

static void test_reset_synch_info(uint8_t *synch_info)
{
memset(synch_info, 0, 100);
synch_info[0] = 0x05;
synch_info[1] = 0x15;
synch_info[2] = 0x02;
synch_info[3] = 0x00;
synch_info[4] = 0x00;
synch_info[5] = 0x00;
synch_info[6] = 0x00;
synch_info[7] = 0x05;
synch_info[8] = 0x15;
synch_info[9] = 0x01;
synch_info[10] = 0x04;
synch_info[11] = 0x00;
synch_info[12] = 0x00;
synch_info[13] = 0x00;
synch_info[14] = 0x00;
synch_info[15] = 0x3f;
}

bool test_fhss_ws_write_synch_info_callback()
{
fhss_api_t *api = test_generate_fhss_api();
fhss_common_stub.fhss_struct.ws->fhss_configuration.ws_uc_channel_function = WS_TR51CF;
fhss_common_stub.fhss_struct.rx_channel = 0;
fhss_common_stub.fhss_struct.ws->unicast_timer_running = true;
uint8_t synch_info[100] = {0x05, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3f};
uint8_t synch_info[100];
test_reset_synch_info(synch_info);

// Test when FHSS struct not found
disable_fhss_struct();
if (fhss_common_stub.fhss_struct.fhss_api->write_synch_info(api, synch_info, sizeof(synch_info), DEFAULT_FRAME_TYPE, DEFAULT_TX_TIME) != -1) {
Expand All @@ -671,6 +694,7 @@ bool test_fhss_ws_write_synch_info_callback()
}
fhss_platform_stub.remaining_slots_value = 100000;
fhss_callbacks_stub.uint32_value = 1000000;
fhss_common_stub.fhss_struct.ws->next_uc_timeout = fhss_callbacks_stub.uint32_value + fhss_platform_stub.remaining_slots_value;
/* Test the UFSI field in synch info
* slot: | 0(200ms) | 1(200ms) | 2(200ms) | 3(200ms) |
* | ufsi(597ms) -> 1001599 |
Expand All @@ -680,8 +704,10 @@ bool test_fhss_ws_write_synch_info_callback()
|| (test_ufsi(&synch_info[11], 1001599) != true)) {
return false;
}
test_reset_synch_info(synch_info);
// Test when timestamp overflows
fhss_callbacks_stub.uint32_value = 4294960000;
fhss_common_stub.fhss_struct.ws->next_uc_timeout = fhss_callbacks_stub.uint32_value + fhss_platform_stub.remaining_slots_value;
/* Test the UFSI field in synch info
* slot: | 0(200ms) | 1(200ms) | 2(200ms) | 3(200ms) |
* | ufsi(597ms) -> 1001599 |
Expand All @@ -691,7 +717,33 @@ bool test_fhss_ws_write_synch_info_callback()
|| (test_ufsi(&synch_info[11], 1001599) != true)) {
return false;
}

test_reset_synch_info(synch_info);
// Test when TX time has passed
fhss_callbacks_stub.uint32_value = 1000000;
fhss_common_stub.fhss_struct.ws->next_uc_timeout = fhss_callbacks_stub.uint32_value + fhss_platform_stub.remaining_slots_value;
/* Test the UFSI field in synch info
* slot: | 0(200ms) | 1(200ms) | 2(200ms) | 3(200ms) |
* | ufsi(500ms) -> 838860
* timestamps: TX at 995000us|written at 1000000us|
*/
if ((fhss_common_stub.fhss_struct.fhss_api->write_synch_info(api, synch_info, sizeof(synch_info), DEFAULT_FRAME_TYPE, fhss_callbacks_stub.uint32_value - 5000) != 0)
|| (test_ufsi(&synch_info[11], 838860) != true)) {
return false;
}
test_reset_synch_info(synch_info);
// Test when interrupt is delayed
fhss_platform_stub.remaining_slots_value = 0;
fhss_callbacks_stub.uint32_value = 1000000;
fhss_common_stub.fhss_struct.ws->next_uc_timeout = fhss_callbacks_stub.uint32_value - 5000;
/* Test the UFSI field in synch info
* slot: | 0(200ms) | 1(200ms) | 2(200ms) | 3(200ms) |
* | ufsi(597ms) -> 1001599
* timestamps: written at 1000000us|TX at 1005000us|
*/
if ((fhss_common_stub.fhss_struct.fhss_api->write_synch_info(api, synch_info, sizeof(synch_info), DEFAULT_FRAME_TYPE, fhss_callbacks_stub.uint32_value + 7000) != 0)
|| (test_ufsi(&synch_info[11], 1026765) != true)) {
return false;
}
// Test when IE element not found
memset(synch_info, 0, sizeof(synch_info));
if (fhss_common_stub.fhss_struct.fhss_api->write_synch_info(api, synch_info, sizeof(synch_info), DEFAULT_FRAME_TYPE, DEFAULT_TX_TIME) != 0) {
Expand Down

0 comments on commit 04de6e2

Please sign in to comment.