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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
arm_hal_fhss_timer.cpp
00001 /* 00002 * Copyright (c) 2018-2019, 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 #ifdef MBED_CONF_NANOSTACK_CONFIGURATION 00019 00020 #include "ns_types.h" 00021 #include "fhss_api.h " 00022 #include "fhss_config.h " 00023 #include "mbed_trace.h" 00024 #include "platform/SingletonPtr.h" 00025 #include "platform/arm_hal_interrupt.h" 00026 #include <Timer.h> 00027 #include "equeue.h" 00028 #include "events/EventQueue.h" 00029 #include "mbed_shared_queues.h" 00030 #include "Timeout.h" 00031 00032 #define TRACE_GROUP "fhdr" 00033 #ifndef NUMBER_OF_SIMULTANEOUS_TIMEOUTS 00034 #define NUMBER_OF_SIMULTANEOUS_TIMEOUTS 2 00035 #endif //NUMBER_OF_SIMULTANEOUS_TIMEOUTS 00036 00037 namespace { 00038 using namespace mbed; 00039 using namespace events; 00040 00041 static SingletonPtr<Timer> timer; 00042 static bool timer_initialized = false; 00043 static const fhss_api_t *fhss_active_handle = NULL; 00044 #if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT 00045 static EventQueue *equeue; 00046 #endif 00047 00048 // All members of fhss_timeout_s must be initialized to make the structure 00049 // constant-initialized, and hence able to be omitted by the linker, 00050 // as SingletonPtr now relies on C++ constant-initialization. (Previously it 00051 // worked through C++ zero-initialization). And all the constants should be zero 00052 // to ensure it stays in the actual zero-init part of the image if used, avoiding 00053 // an initialized-data cost. 00054 struct fhss_timeout_s { 00055 void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t) = nullptr; 00056 uint32_t start_time = 0; 00057 uint32_t stop_time = 0; 00058 bool active = false; 00059 SingletonPtr<Timeout> timeout; 00060 }; 00061 00062 fhss_timeout_s fhss_timeout[NUMBER_OF_SIMULTANEOUS_TIMEOUTS]; 00063 00064 static uint32_t read_current_time(void) 00065 { 00066 return timer->read_us(); 00067 } 00068 00069 static fhss_timeout_s *find_timeout(void (*callback)(const fhss_api_t *api, uint16_t)) 00070 { 00071 for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) { 00072 if (fhss_timeout[i].fhss_timer_callback == callback) { 00073 return &fhss_timeout[i]; 00074 } 00075 } 00076 return NULL; 00077 } 00078 00079 static fhss_timeout_s *allocate_timeout(void) 00080 { 00081 for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) { 00082 if (fhss_timeout[i].fhss_timer_callback == NULL) { 00083 return &fhss_timeout[i]; 00084 } 00085 } 00086 return NULL; 00087 } 00088 00089 static void fhss_timeout_handler(void) 00090 { 00091 for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) { 00092 if (fhss_timeout[i].active && ((fhss_timeout[i].stop_time - fhss_timeout[i].start_time) <= (read_current_time() - fhss_timeout[i].start_time))) { 00093 fhss_timeout[i].active = false; 00094 fhss_timeout[i].fhss_timer_callback(fhss_active_handle, read_current_time() - fhss_timeout[i].stop_time); 00095 } 00096 } 00097 } 00098 00099 static void timer_callback(void) 00100 { 00101 #if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT 00102 fhss_timeout_handler(); 00103 #else 00104 equeue->call(fhss_timeout_handler); 00105 #endif 00106 } 00107 00108 static int platform_fhss_timer_start(uint32_t slots, void (*callback)(const fhss_api_t *api, uint16_t), const fhss_api_t *callback_param) 00109 { 00110 int ret_val = -1; 00111 platform_enter_critical(); 00112 if (timer_initialized == false) { 00113 #if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT 00114 equeue = mbed_highprio_event_queue(); 00115 MBED_ASSERT(equeue != NULL); 00116 #endif 00117 timer->start(); 00118 timer_initialized = true; 00119 } 00120 fhss_timeout_s *fhss_tim = find_timeout(callback); 00121 if (!fhss_tim) { 00122 fhss_tim = allocate_timeout(); 00123 } 00124 if (!fhss_tim) { 00125 platform_exit_critical(); 00126 tr_error("Failed to allocate timeout"); 00127 return ret_val; 00128 } 00129 fhss_tim->fhss_timer_callback = callback; 00130 fhss_tim->start_time = read_current_time(); 00131 fhss_tim->stop_time = fhss_tim->start_time + slots; 00132 fhss_tim->active = true; 00133 fhss_tim->timeout->attach_us(timer_callback, slots); 00134 fhss_active_handle = callback_param; 00135 ret_val = 0; 00136 platform_exit_critical(); 00137 return ret_val; 00138 } 00139 00140 static int platform_fhss_timer_stop(void (*callback)(const fhss_api_t *api, uint16_t), const fhss_api_t *api) 00141 { 00142 (void)api; 00143 platform_enter_critical(); 00144 fhss_timeout_s *fhss_tim = find_timeout(callback); 00145 if (!fhss_tim) { 00146 platform_exit_critical(); 00147 return -1; 00148 } 00149 fhss_tim->timeout->detach(); 00150 fhss_tim->active = false; 00151 platform_exit_critical(); 00152 return 0; 00153 } 00154 00155 static uint32_t platform_fhss_get_remaining_slots(void (*callback)(const fhss_api_t *api, uint16_t), const fhss_api_t *api) 00156 { 00157 (void)api; 00158 platform_enter_critical(); 00159 fhss_timeout_s *fhss_tim = find_timeout(callback); 00160 if (!fhss_tim) { 00161 platform_exit_critical(); 00162 return 0; 00163 } 00164 uint32_t remaining_slots = fhss_tim->stop_time - read_current_time(); 00165 platform_exit_critical(); 00166 return remaining_slots; 00167 } 00168 00169 static uint32_t platform_fhss_timestamp_read(const fhss_api_t *api) 00170 { 00171 (void)api; 00172 return read_current_time(); 00173 } 00174 } // anonymous namespace 00175 00176 fhss_timer_t fhss_functions = { 00177 .fhss_timer_start = platform_fhss_timer_start, 00178 .fhss_timer_stop = platform_fhss_timer_stop, 00179 .fhss_get_remaining_slots = platform_fhss_get_remaining_slots, 00180 .fhss_get_timestamp = platform_fhss_timestamp_read, 00181 .fhss_resolution_divider = 1 00182 }; 00183 00184 #endif
Generated on Tue Jul 12 2022 13:54:01 by
