Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
fhss_beacon.c
00001 /* 00002 * Copyright (c) 2015-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 00019 #include "nsconfig.h" 00020 #include "fhss_api.h " 00021 #include "fhss_config.h " 00022 #include "fhss.h" 00023 #include "fhss_beacon.h" 00024 00025 #include "common_functions.h" 00026 #include <string.h> // memcpy 00027 #include "ns_trace.h" 00028 00029 #define TRACE_GROUP "fhss" 00030 00031 // This function should be called just prior actually sending a beacon packet 00032 // to get precise information. Especially the time variables are essential. 00033 int fhss_beacon_update_payload(fhss_structure_t *fhss_structure, 00034 fhss_synchronization_beacon_payload_s *payload) 00035 { 00036 00037 int ret_val = 0; 00038 if (!fhss_structure || !payload) { 00039 return -1; 00040 } 00041 00042 const fhss_synch_configuration_t *config = &fhss_structure->synch_configuration; 00043 00044 payload->channel_index = fhss_structure->current_channel_index; 00045 00046 payload->sender_unicast_channel = 0; 00047 00048 payload->current_superframe = fhss_structure->current_superframe; 00049 00050 // This assumes that the time is always in the range of 0..2**16, which 00051 // should be the case as the superframe length field is also in that range. 00052 payload->remaining_slots = (uint16_t) fhss_get_remaining_time_to_next_superframe(fhss_structure); 00053 payload->channel_list_counter = fhss_structure->channel_list_counter; 00054 00055 payload->hop_count = fhss_structure->own_hop; 00056 payload->number_of_broadcast_channels = config->fhss_number_of_bc_channels; 00057 payload->number_of_tx_slots = config->fhss_number_of_tx_slots; 00058 payload->time_since_last_beacon = 0; // XXX not available yet 00059 // TODO: Get Beacon length from MAC 00060 uint32_t tx_time = fhss_get_tx_time(fhss_structure, 71, 0, 0); 00061 payload->processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.tx_processing_delay + tx_time; 00062 00063 payload->superframe_length = config->fhss_superframe_length; 00064 00065 payload->number_of_superframes_per_channel = config->fhss_number_of_superframes; 00066 00067 return ret_val; 00068 } 00069 00070 uint8_t* fhss_beacon_encode_raw(uint8_t* buffer, const fhss_synchronization_beacon_payload_s* source) 00071 { 00072 *buffer++ = FHSS_DATA_START_DELIMETER; 00073 *buffer++ = source->channel_index; 00074 *buffer++ = source->sender_unicast_channel; 00075 buffer = common_write_16_bit(source->current_superframe, buffer); 00076 buffer = common_write_16_bit(source->remaining_slots, buffer); 00077 buffer = common_write_16_bit(source->channel_list_counter, buffer); 00078 *buffer++ = source->hop_count; 00079 *buffer++ = source->number_of_broadcast_channels; 00080 *buffer++ = source->number_of_tx_slots; 00081 buffer = common_write_32_bit(source->time_since_last_beacon, buffer); 00082 buffer = common_write_16_bit(source->processing_delay, buffer); 00083 buffer = common_write_16_bit(source->superframe_length, buffer); 00084 *buffer++ = source->number_of_superframes_per_channel; 00085 00086 return buffer; 00087 } 00088 00089 uint8_t fhss_calculate_uc_index(uint8_t channel_index, uint16_t number_of_channels, uint8_t number_of_broadcast_channels) 00090 { 00091 // When channel index is 0, return last unicast index 00092 if (channel_index == 0) { 00093 return (number_of_channels - number_of_broadcast_channels - 1); 00094 } 00095 uint16_t bc_channel_density = (number_of_channels/number_of_broadcast_channels); 00096 return channel_index - (channel_index/bc_channel_density) - 1; 00097 } 00098 00099 00100 uint32_t fhss_get_time_to_next_channel_change(uint16_t remaining_slots_to_next_superframe, uint8_t number_of_superframes, 00101 uint8_t current_superframe, uint16_t superframe_length) 00102 { 00103 return remaining_slots_to_next_superframe + ((uint32_t)((number_of_superframes - 1) - current_superframe) * superframe_length); 00104 } 00105 00106 void fhss_beacon_decode_raw(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer) 00107 { 00108 dest->data_start_delimeter = *buffer++; 00109 00110 dest->channel_index = *buffer++; 00111 dest->sender_unicast_channel = *buffer++; 00112 00113 dest->current_superframe = common_read_16_bit(buffer); 00114 buffer += BEACON_FIELD_SIZE(current_superframe); 00115 00116 dest->remaining_slots = common_read_16_bit(buffer); 00117 buffer += BEACON_FIELD_SIZE(remaining_slots); 00118 00119 dest->channel_list_counter = common_read_16_bit(buffer); 00120 buffer += BEACON_FIELD_SIZE(channel_list_counter); 00121 00122 dest->hop_count = *buffer++; 00123 dest->number_of_broadcast_channels = *buffer++; 00124 dest->number_of_tx_slots = *buffer++; 00125 00126 dest->time_since_last_beacon = common_read_32_bit(buffer); 00127 buffer += BEACON_FIELD_SIZE(time_since_last_beacon); 00128 00129 dest->processing_delay += common_read_16_bit(buffer); 00130 00131 buffer += BEACON_FIELD_SIZE(processing_delay); 00132 00133 dest->superframe_length = common_read_16_bit(buffer); 00134 buffer += BEACON_FIELD_SIZE(superframe_length); 00135 00136 dest->number_of_superframes_per_channel = *buffer; 00137 } 00138 00139 // Decode the given raw byte buffer into a struct into dest struct and calculate 00140 // the new values for elapsed_time, channel_index, current_superframe and remaining_slots 00141 // from current state and given data. 00142 void fhss_beacon_decode(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer, uint32_t elapsed_time, uint16_t number_of_channels) 00143 { 00144 fhss_beacon_decode_raw(dest, buffer); 00145 00146 elapsed_time += dest->processing_delay; 00147 00148 /* To calculate channel index after beacon scan, following calculation is performed 00149 * 00150 * rem. slots to channel change(X) Channel length (V) 00151 * |---------------------| |-----------------------------------------------| 00152 * | RX'd channel index (Y) | ... | Y+n | 00153 * ...| sf1 | sf2 | sf3 | sf4 | ... | sf1 | sf2 | sf3 | sf4 |... 00154 * ^ ^ 00155 * |beacon received |beacon scan done 00156 * |-------------------------------------| 00157 * measured time after beacon RX'd(Z) 00158 * V = superframe length * number of superframes 00159 * X = remaining slots to superframe change + length of the remaining full superframes to channel change 00160 * 00161 * Y+n = Y + ((Z - X) / V) + 1 00162 * 00163 * Or if (Z < X) 00164 * Y+n = Y 00165 */ 00166 00167 uint32_t remaining_slots_to_next_channel = fhss_get_time_to_next_channel_change(dest->remaining_slots, dest->number_of_superframes_per_channel, dest->current_superframe, dest->superframe_length); 00168 uint16_t temp_channel_index = dest->channel_index; 00169 if (elapsed_time >= remaining_slots_to_next_channel) { 00170 uint32_t channel_length = (uint32_t) dest->number_of_superframes_per_channel * dest->superframe_length; 00171 temp_channel_index = dest->channel_index + ((elapsed_time - remaining_slots_to_next_channel) / channel_length) + 1; 00172 } 00173 while (temp_channel_index >= number_of_channels) { 00174 temp_channel_index -= number_of_channels; 00175 dest->channel_list_counter++; 00176 } 00177 dest->channel_index = temp_channel_index; 00178 while (dest->channel_list_counter >= (number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES)) { 00179 dest->channel_list_counter -= (number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES); 00180 } 00181 00182 /* To calculate superframe after beacon scan, following calculation is performed 00183 * 00184 * rem. slots(X) sf. length(V) 00185 * |---------------| |-----------------| 00186 *...| RX'd superframe (Y)| ... | Y+n | Y+n+1 |.... 00187 * ^ ^ 00188 * |beacon received |beacon scan done 00189 * |-------------------------------------| 00190 * measured time after beacon RX'd(Z) 00191 * 00192 * Y+n = Y + ((Z - X) / V) + 1 00193 * 00194 * Or if (Z < X) 00195 * Y+n = Y 00196 */ 00197 00198 if (elapsed_time >= dest->remaining_slots) { 00199 dest->current_superframe = dest->current_superframe + ((elapsed_time - dest->remaining_slots) / dest->superframe_length) + 1; 00200 } 00201 while (dest->current_superframe >= dest->number_of_superframes_per_channel) { 00202 dest->current_superframe -= dest->number_of_superframes_per_channel; 00203 } 00204 00205 /* To get the remaining slots after beacon scan, following calculation is performed 00206 * 00207 * rem. slots(Y) sf. length(V) new rem. slots(X) 00208 * |----------| |---------------| |-------------| 00209 *...| superframe 1 | superframe 2 | superframe 3 | superframe 4 |... 00210 * ^ ^ 00211 * |beacon received |beacon scan done 00212 * |--------------------------------------------| 00213 * measured time after beacon RX'd(Z) 00214 * 00215 * X = V - ((Z - Y) % V) 00216 * 00217 * Or if (Z < Y) 00218 * X = Y - Z 00219 */ 00220 00221 if (elapsed_time < dest->remaining_slots) { 00222 dest->remaining_slots = dest->remaining_slots - elapsed_time; 00223 } else { 00224 dest->remaining_slots = dest->superframe_length - ((elapsed_time - dest->remaining_slots) % dest->superframe_length); 00225 } 00226 00227 }
Generated on Fri Jul 22 2022 04:53:48 by
 1.7.2
 1.7.2 
    