parent
c6fd3a2a16
commit
3734073350
@ -1,37 +0,0 @@
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_STM32_SYSTICK_H
|
||||
#define MICROPY_INCLUDED_STM32_SYSTICK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Works for x between 0 and 16 inclusive
|
||||
#define POW2_CEIL(x) ((((x) - 1) | ((x) - 1) >> 1 | ((x) - 1) >> 2 | ((x) - 1) >> 3) + 1)
|
||||
|
||||
#endif // MICROPY_INCLUDED_STM32_SYSTICK_H
|
@ -0,0 +1,12 @@
|
||||
#ifndef TREZORHAL_SYSTICK_INTERNAL_H
|
||||
#define TREZORHAL_SYSTICK_INTERNAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "systick.h"
|
||||
|
||||
// Internal function called from interrupt context.
|
||||
// Handles expired timers and invoked their callbacks.
|
||||
void systimer_dispatch_expired_timers(uint64_t cycles);
|
||||
|
||||
#endif // TREZORHAL_SYSTICK_INTERNAL_H
|
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "irq.h"
|
||||
#include "platform.h"
|
||||
#include "systick_internal.h"
|
||||
#include "systimer.h"
|
||||
|
||||
// Maximum number of registerd user timer
|
||||
//
|
||||
// Consider different implementation (i.e. priority queue
|
||||
// using binary heap if MAX_SYSTIMERS exceeds 10 or more)
|
||||
#define MAX_SYSTIMERS 4
|
||||
|
||||
// User timer instance
|
||||
struct systimer {
|
||||
// User callback function
|
||||
// Non-NULL if the timer entry is valid
|
||||
volatile systimer_callback_t callback;
|
||||
// User callback context
|
||||
void* context;
|
||||
// Set if the timer is suspended
|
||||
volatile bool suspended;
|
||||
// Set if the timer is scheduled
|
||||
volatile bool scheduled;
|
||||
// Expiration time (valid if scheduled is set)
|
||||
volatile uint64_t expiration;
|
||||
// Period (= 0 for non-periodic timers)
|
||||
volatile uint64_t period;
|
||||
};
|
||||
|
||||
// systimer driver state
|
||||
typedef struct {
|
||||
// Set if the driver is initialized
|
||||
bool initialized;
|
||||
// Registered timers
|
||||
// (unused slots have callback field set to NULL)
|
||||
systimer_t timers[MAX_SYSTIMERS];
|
||||
} systimer_driver_t;
|
||||
|
||||
static systimer_driver_t g_systimer_driver = {
|
||||
.initialized = false,
|
||||
};
|
||||
|
||||
void systimer_init(void) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(drv, 0, sizeof(systimer_driver_t));
|
||||
drv->initialized = true;
|
||||
}
|
||||
|
||||
void systimer_deinit(void) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
drv->initialized = false;
|
||||
}
|
||||
|
||||
static inline bool timer_valid(systimer_driver_t* drv, systimer_t* timer) {
|
||||
return drv->initialized && (timer >= &drv->timers[0]) &&
|
||||
(timer < &drv->timers[MAX_SYSTIMERS]);
|
||||
}
|
||||
|
||||
systimer_t* systimer_create(systimer_callback_t callback, void* context) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
// Since the callback is used to determine if the
|
||||
// timer is valid, it must be non-NULL.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t irq_state = disable_irq();
|
||||
|
||||
// Find a free timer entry
|
||||
for (int i = 0; i < MAX_SYSTIMERS; i++) {
|
||||
systimer_t* timer = &drv->timers[i];
|
||||
|
||||
if (timer->callback == NULL) {
|
||||
timer->scheduled = false;
|
||||
timer->suspended = false;
|
||||
timer->context = context;
|
||||
timer->callback = callback;
|
||||
|
||||
enable_irq(irq_state);
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
|
||||
// No free timer entry found
|
||||
enable_irq(irq_state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void systimer_delete(systimer_t* timer) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
if (!timer_valid(drv, timer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer->callback = NULL;
|
||||
}
|
||||
|
||||
void systimer_set(systimer_t* timer, uint32_t delay_ms) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (!timer_valid(drv, timer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t delay = systick_us_to_cycles((uint64_t)delay_ms * 1000);
|
||||
uint64_t expiration = systick_cycles() + delay;
|
||||
|
||||
uint32_t irq_state = disable_irq();
|
||||
timer->expiration = expiration;
|
||||
timer->period = 0;
|
||||
timer->scheduled = true;
|
||||
enable_irq(irq_state);
|
||||
}
|
||||
|
||||
void systimer_set_periodic(systimer_t* timer, uint32_t period_ms) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (!timer_valid(drv, timer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t period = systick_us_to_cycles((uint64_t)period_ms * 1000);
|
||||
uint64_t expiration = systick_cycles() + period;
|
||||
|
||||
uint32_t irq_state = disable_irq();
|
||||
timer->expiration = expiration;
|
||||
timer->period = period;
|
||||
timer->scheduled = true;
|
||||
enable_irq(irq_state);
|
||||
}
|
||||
|
||||
bool systimer_unset(systimer_t* timer) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (!timer_valid(drv, timer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t irq_state = disable_irq();
|
||||
bool was_scheduled = timer->scheduled;
|
||||
timer->scheduled = false;
|
||||
enable_irq(irq_state);
|
||||
return was_scheduled;
|
||||
}
|
||||
|
||||
systimer_key_t systimer_suspend(systimer_t* timer) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (!timer_valid(drv, timer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t irq_state = disable_irq();
|
||||
bool was_suspended = timer->suspended;
|
||||
timer->suspended = true;
|
||||
enable_irq(irq_state);
|
||||
return was_suspended;
|
||||
}
|
||||
|
||||
void systimer_resume(systimer_t* timer, systimer_key_t key) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (!timer_valid(drv, timer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer->suspended = key;
|
||||
}
|
||||
|
||||
// Called from interrupt context
|
||||
void systimer_dispatch_expired_timers(uint64_t cycles) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Go through all timer slots and invoke callbacks of expired timers
|
||||
// This algorithm is not efficient for large number of timers
|
||||
// but it is good enough if MAX_SYSTIMERS ~ 10
|
||||
|
||||
for (int i = 0; i < MAX_SYSTIMERS; i++) {
|
||||
systimer_t* timer = &drv->timers[i];
|
||||
|
||||
if (timer->callback != NULL && !timer->suspended && timer->scheduled) {
|
||||
if (cycles >= timer->expiration) {
|
||||
if (timer->period > 0) {
|
||||
// Reschedule periodic timer
|
||||
timer->expiration = cycles + timer->period;
|
||||
} else {
|
||||
// Stop one-shot timer
|
||||
timer->scheduled = false;
|
||||
}
|
||||
// Callback is invoked from interrupt context
|
||||
timer->callback(timer->context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
../stm32f4/systick.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/systick_internal.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/systimer.c
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_SYSTICK_H
|
||||
#define TREZORHAL_SYSTICK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Initializes systick subsystem
|
||||
//
|
||||
// Before calling this function, none of the other functions
|
||||
// from this module should be called.
|
||||
void systick_init(void);
|
||||
|
||||
// Deinitialize systick subsystem
|
||||
//
|
||||
// The function should be called before jumping to the
|
||||
// next bootloader stage or firmware.
|
||||
void systick_deinit(void);
|
||||
|
||||
// Updates systick subsystem with new system clock frequency
|
||||
//
|
||||
// The function should be called after the system clock frequency
|
||||
// has been changed.
|
||||
void systick_update_freq(void);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tick functions
|
||||
|
||||
// Returns number of system clock cycles since the system start.
|
||||
//
|
||||
// Read monotonic counter with high resolution (Cortex-M SysTick clock)
|
||||
// (On 160MHz CPU, 1 cycles is 1 / 160MHz = 6.25ns)
|
||||
uint64_t systick_cycles(void);
|
||||
|
||||
// Returns number of microseconds since the system start.
|
||||
uint64_t systick_us(void);
|
||||
|
||||
// Returns number of ticks (milliseconds) since the system start.
|
||||
//
|
||||
// The returned value is a 32-bit unsigned integer that wraps
|
||||
// around every 49.7 days.
|
||||
uint32_t systick_ms(void);
|
||||
|
||||
// Converts microseconds to system clock cycles
|
||||
uint64_t systick_us_to_cycles(uint64_t us);
|
||||
|
||||
// Number of ticks (milliseconds)
|
||||
typedef uint32_t ticks_t;
|
||||
|
||||
//
|
||||
#define ticks() systick_ms()
|
||||
|
||||
// Helper function for building expiration time
|
||||
#define ticks_timeout(timeout) (systick_ms() + (timeout))
|
||||
|
||||
// Helper function for checking ticks expiration
|
||||
//
|
||||
// It copes with the wrap-around of the `ticks_t` type but
|
||||
// still assumes that the difference between the two ticks
|
||||
// is less than half of the `ticks_t` range.
|
||||
#define ticks_expired(ticks) ((int32_t)(systick_ms() - (ticks)) >= 0)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Delay functions
|
||||
|
||||
// Waits for at least `ms` milliseconds
|
||||
void systick_delay_ms(uint32_t ms);
|
||||
|
||||
// Waits for at least `us` microseconds
|
||||
void systick_delay_us(uint64_t us);
|
||||
|
||||
// legacy functions
|
||||
|
||||
static inline uint32_t hal_ticks_ms(void) { return systick_ms(); }
|
||||
static inline void hal_delay(uint32_t ms) { systick_delay_ms(ms); }
|
||||
static inline void hal_delay_us(uint64_t us) { systick_delay_us(us); }
|
||||
|
||||
#endif // TREZORHAL_SYSTICK_H
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_SYSTIMER_H
|
||||
#define TREZORHAL_SYSTIMER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Initializes systimer subsystem
|
||||
//
|
||||
// Before calling this function, none of the other functions
|
||||
// from this module should be called.
|
||||
void systimer_init(void);
|
||||
|
||||
// Deinitialize sytimer subsystem
|
||||
void systimer_deinit(void);
|
||||
|
||||
// Timer handle
|
||||
typedef struct systimer systimer_t;
|
||||
|
||||
// Timer callback routine invoked when timer expires
|
||||
//
|
||||
// The callback should be as short as possible and should not
|
||||
// block. It is invoked from the timer interrupt context.
|
||||
//
|
||||
// `context` is the pointer passed to `timer_create`
|
||||
typedef void (*systimer_callback_t)(void* context);
|
||||
|
||||
// Initializes the timer and returns its handle.
|
||||
//
|
||||
// There a limited number of timers and `NULL` is returned
|
||||
// if no timer is available.
|
||||
systimer_t* systimer_create(systimer_callback_t callback, void* context);
|
||||
|
||||
// Deletes the timer
|
||||
//
|
||||
// Timer is unset and its resources are released.
|
||||
void systimer_delete(systimer_t* timer);
|
||||
|
||||
// Sets the timer to expire in `delay_ms` milliseconds
|
||||
//
|
||||
// If the timer is already set, it will be rescheduled.
|
||||
void systimer_set(systimer_t* timer, uint32_t delay_ms);
|
||||
|
||||
// Sets the timer to expire peridically every `period_ms` milliseconds
|
||||
//
|
||||
// If the timer is already set, it will be rescheduled.
|
||||
void systimer_set_periodic(systimer_t* timer, uint32_t period_ms);
|
||||
|
||||
// Unsets the timer (cancels the expiration)
|
||||
//
|
||||
// Timer is not deleted and can be set again.
|
||||
//
|
||||
// Returns `true` if the timer was unset before its expiration
|
||||
// so the callback will not be invoked.
|
||||
bool systimer_unset(systimer_t* timer);
|
||||
|
||||
// Timer suspension state (opaque type).
|
||||
// Allows to recursively suspend/resume timer.
|
||||
typedef bool systimer_key_t;
|
||||
|
||||
// Suspends timer callback invocation
|
||||
//
|
||||
// The purpose of this function is to prevent the timer callback
|
||||
// from being invoked for synchronization purposes. The function
|
||||
// returns a lock that should be passed to `timer_resume()` to
|
||||
// resume the timer callback invocation.
|
||||
systimer_key_t systimer_suspend(systimer_t* timer);
|
||||
|
||||
// Resumes timer callback invocation
|
||||
//
|
||||
// The timer callback invocation is resumed. The `key` should
|
||||
// be the same as returned by `timer_suspend()`.
|
||||
void systimer_resume(systimer_t* timer, systimer_key_t key);
|
||||
|
||||
#endif // TREZORHAL_SYSTIMER_H
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "systick.h"
|
||||
|
||||
// Systick driver state
|
||||
typedef struct {
|
||||
// Set if the driver is initialized
|
||||
bool initialized;
|
||||
// Instant time [us] of driver initialization
|
||||
uint64_t initial_time;
|
||||
|
||||
} systick_driver_t;
|
||||
|
||||
static systick_driver_t g_systick_driver = {
|
||||
.initialized = false,
|
||||
};
|
||||
|
||||
// Returns number of microseconds since the os started
|
||||
static uint64_t get_monotonic_clock(void) {
|
||||
struct timespec tp;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
return tp.tv_sec * 1000000UL + tp.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
void systick_init(void) {
|
||||
systick_driver_t* drv = &g_systick_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(drv, 0, sizeof(systick_driver_t));
|
||||
drv->initial_time = get_monotonic_clock();
|
||||
drv->initialized = true;
|
||||
}
|
||||
|
||||
void systick_deinit(void) {
|
||||
systick_driver_t* drv = &g_systick_driver;
|
||||
|
||||
drv->initialized = false;
|
||||
}
|
||||
|
||||
void systick_update_freq(void){};
|
||||
|
||||
uint32_t systick_ms() {
|
||||
systick_driver_t* drv = &g_systick_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (get_monotonic_clock() - drv->initial_time) / 1000;
|
||||
}
|
||||
|
||||
uint64_t systick_us(void) {
|
||||
systick_driver_t* drv = &g_systick_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_monotonic_clock() - drv->initial_time;
|
||||
}
|
||||
|
||||
void systick_delay_us(uint64_t us) {
|
||||
systick_driver_t* drv = &g_systick_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct timespec tp;
|
||||
tp.tv_sec = us / 1000000;
|
||||
tp.tv_nsec = (us % 1000000) * 1000;
|
||||
nanosleep(&tp, NULL);
|
||||
}
|
||||
|
||||
void systick_delay_ms(uint32_t ms) {
|
||||
systick_driver_t* drv = &g_systick_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct timespec tp;
|
||||
tp.tv_sec = ms / 1000;
|
||||
tp.tv_nsec = (ms % 1000) * 1000000;
|
||||
nanosleep(&tp, NULL);
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "systimer.h"
|
||||
|
||||
// systimer driver state
|
||||
typedef struct {
|
||||
// Set if the driver is initialized
|
||||
bool initialized;
|
||||
} systimer_driver_t;
|
||||
|
||||
static systimer_driver_t g_systimer_driver = {
|
||||
.initialized = false,
|
||||
};
|
||||
|
||||
void systimer_init(void) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&drv, 0, sizeof(systimer_driver_t));
|
||||
drv->initialized = true;
|
||||
}
|
||||
|
||||
void systimer_deinit(void) {
|
||||
systimer_driver_t* drv = &g_systimer_driver;
|
||||
|
||||
drv->initialized = false;
|
||||
}
|
||||
|
||||
// Timer driver is not fully implemented for unix platform
|
||||
// since not neeeded for the emulator
|
Loading…
Reference in new issue