mirror of https://github.com/ARMmbed/mbed-os.git
NS hal: Implemented FHSS driver
parent
a0a3dd6a06
commit
440fbfd694
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ARM Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "ns_types.h"
|
||||
#include "fhss_api.h"
|
||||
#include "fhss_config.h"
|
||||
#include "mbed.h"
|
||||
#include "mbed_trace.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
#include <Timer.h>
|
||||
|
||||
#define TRACE_GROUP "fhdr"
|
||||
#define NUMBER_OF_SIMULTANEOUS_TIMEOUTS 2
|
||||
|
||||
static Timer timer;
|
||||
static bool timer_initialized = false;
|
||||
static const fhss_api_t *fhss_active_handle = NULL;
|
||||
#if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
|
||||
static EventQueue *equeue;
|
||||
#endif
|
||||
|
||||
struct fhss_timeout_s
|
||||
{
|
||||
void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t);
|
||||
uint32_t start_time;
|
||||
uint32_t stop_time;
|
||||
bool active;
|
||||
Timeout timeout;
|
||||
};
|
||||
|
||||
fhss_timeout_s fhss_timeout[NUMBER_OF_SIMULTANEOUS_TIMEOUTS];
|
||||
|
||||
static uint32_t read_current_time(void)
|
||||
{
|
||||
return timer.read_us();
|
||||
}
|
||||
|
||||
static fhss_timeout_s *find_timeout(void (*callback)(const fhss_api_t *api, uint16_t))
|
||||
{
|
||||
for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) {
|
||||
if (fhss_timeout[i].fhss_timer_callback == callback) {
|
||||
return &fhss_timeout[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static fhss_timeout_s *allocate_timeout(void)
|
||||
{
|
||||
for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) {
|
||||
if (fhss_timeout[i].fhss_timer_callback == NULL) {
|
||||
memset(&fhss_timeout[i], sizeof(fhss_timeout_s), 0);
|
||||
return &fhss_timeout[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void fhss_timeout_handler(void)
|
||||
{
|
||||
for (int i = 0; i < NUMBER_OF_SIMULTANEOUS_TIMEOUTS; i++) {
|
||||
if (fhss_timeout[i].active && ((fhss_timeout[i].stop_time - fhss_timeout[i].start_time) <= (read_current_time() - fhss_timeout[i].start_time))) {
|
||||
fhss_timeout[i].active = false;
|
||||
fhss_timeout[i].fhss_timer_callback(fhss_active_handle, read_current_time() - fhss_timeout[i].stop_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_callback(void)
|
||||
{
|
||||
#if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
|
||||
fhss_timeout_handler();
|
||||
#else
|
||||
equeue->call(fhss_timeout_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int platform_fhss_timer_start(uint32_t slots, void (*callback)(const fhss_api_t *api, uint16_t), const fhss_api_t *callback_param)
|
||||
{
|
||||
int ret_val = -1;
|
||||
platform_enter_critical();
|
||||
if (timer_initialized == false) {
|
||||
#if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
|
||||
equeue = mbed_highprio_event_queue();
|
||||
MBED_ASSERT(equeue != NULL);
|
||||
#endif
|
||||
timer.start();
|
||||
timer_initialized = true;
|
||||
}
|
||||
fhss_timeout_s *fhss_tim = find_timeout(callback);
|
||||
if (!fhss_tim) {
|
||||
fhss_tim = allocate_timeout();
|
||||
}
|
||||
fhss_tim->fhss_timer_callback = callback;
|
||||
fhss_tim->start_time = read_current_time();
|
||||
fhss_tim->stop_time = fhss_tim->start_time + slots;
|
||||
fhss_tim->active = true;
|
||||
fhss_tim->timeout.attach_us(timer_callback, slots);
|
||||
fhss_active_handle = callback_param;
|
||||
ret_val = 0;
|
||||
platform_exit_critical();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int platform_fhss_timer_stop(void (*callback)(const fhss_api_t *api, uint16_t), const fhss_api_t *api)
|
||||
{
|
||||
(void)api;
|
||||
platform_enter_critical();
|
||||
fhss_timeout_s *fhss_tim = find_timeout(callback);
|
||||
if (!fhss_tim) {
|
||||
platform_exit_critical();
|
||||
return -1;
|
||||
}
|
||||
fhss_tim->timeout.detach();
|
||||
fhss_tim->active = false;
|
||||
platform_exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t platform_fhss_get_remaining_slots(void (*callback)(const fhss_api_t *api, uint16_t), const fhss_api_t *api)
|
||||
{
|
||||
(void)api;
|
||||
platform_enter_critical();
|
||||
fhss_timeout_s *fhss_tim = find_timeout(callback);
|
||||
if (!fhss_tim) {
|
||||
platform_exit_critical();
|
||||
return 0;
|
||||
}
|
||||
platform_exit_critical();
|
||||
return fhss_tim->stop_time - read_current_time();
|
||||
}
|
||||
|
||||
static uint32_t platform_fhss_timestamp_read(const fhss_api_t *api)
|
||||
{
|
||||
(void)api;
|
||||
return read_current_time();
|
||||
}
|
||||
|
||||
fhss_timer_t fhss_functions = {
|
||||
.fhss_timer_start = platform_fhss_timer_start,
|
||||
.fhss_timer_stop = platform_fhss_timer_stop,
|
||||
.fhss_get_remaining_slots = platform_fhss_get_remaining_slots,
|
||||
.fhss_get_timestamp = platform_fhss_timestamp_read,
|
||||
.fhss_resolution_divider = 1
|
||||
};
|
Loading…
Reference in New Issue