| /* |
| * Copyright (c) 2016-2018 Nordic Semiconductor ASA |
| * Copyright (c) 2016 Vinayak Kariappa Chettimada |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <stdbool.h> |
| #include <zephyr/sys/dlist.h> |
| #include <zephyr/sys/util.h> |
| |
| #include "hal/cntr.h" |
| |
| #include "util/memq.h" |
| #include "util/mayfly.h" |
| |
| #include "ticker/ticker.h" |
| |
| #include "ll_sw/lll.h" |
| |
| #include "hal/debug.h" |
| |
| #define TICKER_MAYFLY_CALL_ID_ISR TICKER_USER_ID_LLL |
| #define TICKER_MAYFLY_CALL_ID_TRIGGER TICKER_USER_ID_ULL_HIGH |
| #define TICKER_MAYFLY_CALL_ID_WORKER TICKER_USER_ID_ULL_HIGH |
| #define TICKER_MAYFLY_CALL_ID_JOB TICKER_USER_ID_ULL_LOW |
| #define TICKER_MAYFLY_CALL_ID_PROGRAM TICKER_USER_ID_THREAD |
| |
| static uint8_t const caller_id_lut[] = { |
| TICKER_CALL_ID_ISR, |
| TICKER_CALL_ID_WORKER, |
| TICKER_CALL_ID_JOB, |
| TICKER_CALL_ID_PROGRAM |
| }; |
| |
| uint8_t hal_ticker_instance0_caller_id_get(uint8_t user_id) |
| { |
| uint8_t caller_id; |
| |
| LL_ASSERT(user_id < sizeof(caller_id_lut)); |
| |
| caller_id = caller_id_lut[user_id]; |
| LL_ASSERT(caller_id != TICKER_CALL_ID_NONE); |
| |
| return caller_id; |
| } |
| |
| void hal_ticker_instance0_sched(uint8_t caller_id, uint8_t callee_id, uint8_t chain, |
| void *instance) |
| { |
| /* return value not checked as we allow multiple calls to schedule |
| * before being actually needing the work to complete before new |
| * schedule. |
| */ |
| switch (caller_id) { |
| case TICKER_CALL_ID_ISR: |
| switch (callee_id) { |
| case TICKER_CALL_ID_JOB: |
| { |
| static memq_link_t link; |
| static struct mayfly m = {0, 0, &link, NULL, |
| ticker_job}; |
| |
| m.param = instance; |
| |
| /* TODO: scheduler lock, if preemptive threads used */ |
| mayfly_enqueue(TICKER_MAYFLY_CALL_ID_ISR, |
| TICKER_MAYFLY_CALL_ID_JOB, |
| chain, |
| &m); |
| } |
| break; |
| |
| default: |
| LL_ASSERT(0); |
| break; |
| } |
| break; |
| |
| case TICKER_CALL_ID_TRIGGER: |
| switch (callee_id) { |
| case TICKER_CALL_ID_WORKER: |
| { |
| static memq_link_t link; |
| static struct mayfly m = {0, 0, &link, NULL, |
| ticker_worker}; |
| |
| m.param = instance; |
| |
| mayfly_enqueue(TICKER_MAYFLY_CALL_ID_TRIGGER, |
| TICKER_MAYFLY_CALL_ID_WORKER, |
| chain, |
| &m); |
| } |
| break; |
| |
| default: |
| LL_ASSERT(0); |
| break; |
| } |
| break; |
| |
| case TICKER_CALL_ID_WORKER: |
| switch (callee_id) { |
| case TICKER_CALL_ID_JOB: |
| { |
| static memq_link_t link; |
| static struct mayfly m = {0, 0, &link, NULL, |
| ticker_job}; |
| |
| m.param = instance; |
| |
| mayfly_enqueue(TICKER_MAYFLY_CALL_ID_WORKER, |
| TICKER_MAYFLY_CALL_ID_JOB, |
| chain, |
| &m); |
| } |
| break; |
| |
| default: |
| LL_ASSERT(0); |
| break; |
| } |
| break; |
| |
| case TICKER_CALL_ID_JOB: |
| switch (callee_id) { |
| case TICKER_CALL_ID_WORKER: |
| { |
| static memq_link_t link; |
| static struct mayfly m = {0, 0, &link, NULL, |
| ticker_worker}; |
| |
| m.param = instance; |
| |
| mayfly_enqueue(TICKER_MAYFLY_CALL_ID_JOB, |
| TICKER_MAYFLY_CALL_ID_WORKER, |
| chain, |
| &m); |
| } |
| break; |
| |
| case TICKER_CALL_ID_JOB: |
| { |
| static memq_link_t link; |
| static struct mayfly m = {0, 0, &link, NULL, |
| ticker_job}; |
| |
| m.param = instance; |
| |
| mayfly_enqueue(TICKER_MAYFLY_CALL_ID_JOB, |
| TICKER_MAYFLY_CALL_ID_JOB, |
| chain, |
| &m); |
| } |
| break; |
| |
| default: |
| LL_ASSERT(0); |
| break; |
| } |
| break; |
| |
| case TICKER_CALL_ID_PROGRAM: |
| switch (callee_id) { |
| case TICKER_CALL_ID_JOB: |
| { |
| static memq_link_t link; |
| static struct mayfly m = {0, 0, &link, NULL, |
| ticker_job}; |
| |
| m.param = instance; |
| |
| /* TODO: scheduler lock, if preemptive threads used */ |
| mayfly_enqueue(TICKER_MAYFLY_CALL_ID_PROGRAM, |
| TICKER_MAYFLY_CALL_ID_JOB, |
| chain, |
| &m); |
| } |
| break; |
| |
| default: |
| LL_ASSERT(0); |
| break; |
| } |
| break; |
| |
| default: |
| LL_ASSERT(0); |
| break; |
| } |
| } |
| |
| void hal_ticker_instance0_trigger_set(uint32_t value) |
| { |
| cntr_cmp_set(0, value); |
| } |