/* * Copyright (c) 2016-2018 Nordic Semiconductor ASA * Copyright (c) 2016 Vinayak Kariappa Chettimada * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include "hal/cntr.h" #include "util/memq.h" #include "util/mayfly.h" #include "ticker/ticker.h" #include "hal/debug.h" #if defined(CONFIG_BT_LL_SW_SPLIT) #include "ll_sw/lll.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 }; #else #error Unknown LL variant. #endif 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) { #if defined(CONFIG_BT_LL_SW_SPLIT) 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; #endif /* CONFIG_BT_LL_SW_SPLIT */ 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); }