| /* |
| * Copyright (c) 2018 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <kernel.h> |
| #include <string.h> |
| #include "wrapper.h" |
| |
| #define ACTIVE 1 |
| #define NOT_ACTIVE 0 |
| |
| static void zephyr_timer_wrapper(struct k_timer *timer); |
| |
| K_MEM_SLAB_DEFINE(cv2_timer_slab, sizeof(struct cv2_timer), |
| CONFIG_CMSIS_V2_TIMER_MAX_COUNT, 4); |
| |
| static const osTimerAttr_t init_timer_attrs = { |
| .name = "ZephyrTimer", |
| .attr_bits = 0, |
| .cb_mem = NULL, |
| .cb_size = 0, |
| }; |
| |
| static void zephyr_timer_wrapper(struct k_timer *timer) |
| { |
| struct cv2_timer *cm_timer; |
| |
| cm_timer = CONTAINER_OF(timer, struct cv2_timer, z_timer); |
| (cm_timer->callback_function)(cm_timer->arg); |
| } |
| |
| /** |
| * @brief Create a Timer |
| */ |
| osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, |
| void *argument, const osTimerAttr_t *attr) |
| { |
| struct cv2_timer *timer; |
| |
| if (type != osTimerOnce && type != osTimerPeriodic) { |
| return NULL; |
| } |
| |
| if (k_is_in_isr()) { |
| return NULL; |
| } |
| |
| if (attr == NULL) { |
| attr = &init_timer_attrs; |
| } |
| |
| if (k_mem_slab_alloc(&cv2_timer_slab, (void **)&timer, K_MSEC(100)) == 0) { |
| (void)memset(timer, 0, sizeof(struct cv2_timer)); |
| } else { |
| return NULL; |
| } |
| |
| timer->callback_function = func; |
| timer->arg = argument; |
| timer->type = type; |
| timer->status = NOT_ACTIVE; |
| |
| k_timer_init(&timer->z_timer, zephyr_timer_wrapper, NULL); |
| |
| if (attr->name == NULL) { |
| strncpy(timer->name, init_timer_attrs.name, |
| sizeof(timer->name) - 1); |
| } else { |
| strncpy(timer->name, attr->name, sizeof(timer->name) - 1); |
| } |
| |
| return (osTimerId_t)timer; |
| } |
| |
| /** |
| * @brief Start or restart a Timer |
| */ |
| osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks) |
| { |
| struct cv2_timer *timer = (struct cv2_timer *)timer_id; |
| u32_t millisec = k_ticks_to_ms_floor64(ticks); |
| |
| if (timer == NULL) { |
| return osErrorParameter; |
| } |
| |
| if (k_is_in_isr()) { |
| return osErrorISR; |
| } |
| |
| if (timer->type == osTimerOnce) { |
| k_timer_start(&timer->z_timer, millisec, K_NO_WAIT); |
| } else if (timer->type == osTimerPeriodic) { |
| k_timer_start(&timer->z_timer, K_NO_WAIT, millisec); |
| } |
| |
| timer->status = ACTIVE; |
| return osOK; |
| } |
| |
| /** |
| * @brief Stop the Timer |
| */ |
| osStatus_t osTimerStop(osTimerId_t timer_id) |
| { |
| struct cv2_timer *timer = (struct cv2_timer *)timer_id; |
| |
| if (timer == NULL) { |
| return osErrorParameter; |
| } |
| |
| if (k_is_in_isr()) { |
| return osErrorISR; |
| } |
| |
| if (timer->status == NOT_ACTIVE) { |
| return osErrorResource; |
| } |
| |
| k_timer_stop(&timer->z_timer); |
| timer->status = NOT_ACTIVE; |
| return osOK; |
| } |
| |
| /** |
| * @brief Delete the timer that was created by osTimerCreate |
| */ |
| osStatus_t osTimerDelete(osTimerId_t timer_id) |
| { |
| struct cv2_timer *timer = (struct cv2_timer *) timer_id; |
| |
| if (timer == NULL) { |
| return osErrorParameter; |
| } |
| |
| if (k_is_in_isr()) { |
| return osErrorISR; |
| } |
| |
| if (timer->status == ACTIVE) { |
| k_timer_stop(&timer->z_timer); |
| timer->status = NOT_ACTIVE; |
| } |
| |
| k_mem_slab_free(&cv2_timer_slab, (void *) &timer); |
| return osOK; |
| } |
| |
| /** |
| * @brief Get name of a timer. |
| */ |
| const char *osTimerGetName(osTimerId_t timer_id) |
| { |
| struct cv2_timer *timer = (struct cv2_timer *)timer_id; |
| |
| if (k_is_in_isr() || (timer == NULL)) { |
| return NULL; |
| } |
| |
| return timer->name; |
| } |
| |
| /** |
| * @brief Check if a timer is running. |
| */ |
| uint32_t osTimerIsRunning(osTimerId_t timer_id) |
| { |
| struct cv2_timer *timer = (struct cv2_timer *)timer_id; |
| |
| if (k_is_in_isr() || (timer == NULL)) { |
| return 0; |
| } |
| |
| return !(!(k_timer_remaining_get(&timer->z_timer))); |
| } |