1 /*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 * Copyright (c) 2024 NXP.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define LOG_MODULE_NAME net_openthread_alarm
9 #define LOG_LEVEL CONFIG_OPENTHREAD_LOG_LEVEL
10
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
13
14 #include <zephyr/kernel.h>
15 #include <string.h>
16 #include <inttypes.h>
17
18 #include <openthread/platform/alarm-milli.h>
19 #include <openthread/platform/alarm-micro.h>
20 #include <openthread/platform/diag.h>
21 #include <openthread-system.h>
22
23 #include <stdio.h>
24
25 #include "platform-zephyr.h"
26 #include "openthread-core-zephyr-config.h"
27
28 static bool timer_ms_fired, timer_us_fired;
29 static int32_t time_offset_us;
30 static int32_t time_offset_ms;
31
ot_timer_ms_fired(struct k_timer * timer)32 static void ot_timer_ms_fired(struct k_timer *timer)
33 {
34 ARG_UNUSED(timer);
35
36 timer_ms_fired = true;
37 otSysEventSignalPending();
38 }
39
ot_timer_us_fired(struct k_timer * timer)40 static void ot_timer_us_fired(struct k_timer *timer)
41 {
42 ARG_UNUSED(timer);
43
44 timer_us_fired = true;
45 otSysEventSignalPending();
46 }
47
48 K_TIMER_DEFINE(ot_ms_timer, ot_timer_ms_fired, NULL);
49 K_TIMER_DEFINE(ot_us_timer, ot_timer_us_fired, NULL);
50
platformAlarmInit(void)51 void platformAlarmInit(void)
52 {
53 #if defined(CONFIG_NET_PKT_TXTIME)
54 time_offset_us =
55 (int32_t)((int64_t)otPlatAlarmMicroGetNow() - (uint32_t)otPlatRadioGetNow(NULL));
56 time_offset_ms = time_offset_us / 1000;
57 #endif
58 }
59
platformAlarmProcess(otInstance * aInstance)60 void platformAlarmProcess(otInstance *aInstance)
61 {
62 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
63 if (timer_us_fired) {
64 timer_us_fired = false;
65 otPlatAlarmMicroFired(aInstance);
66 }
67 #endif
68 if (timer_ms_fired) {
69 timer_ms_fired = false;
70 #if defined(CONFIG_OPENTHREAD_DIAG)
71 if (otPlatDiagModeGet()) {
72 otPlatDiagAlarmFired(aInstance);
73 } else
74 #endif
75 {
76 otPlatAlarmMilliFired(aInstance);
77 }
78 }
79 }
80
otPlatAlarmMilliGetNow(void)81 uint32_t otPlatAlarmMilliGetNow(void)
82 {
83 return k_uptime_get_32() - time_offset_ms;
84 }
85
otPlatAlarmMilliStartAt(otInstance * aInstance,uint32_t aT0,uint32_t aDt)86 void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
87 {
88 ARG_UNUSED(aInstance);
89
90 int32_t delta = (int32_t)(aT0 + aDt - otPlatAlarmMilliGetNow());
91
92 if (delta > 0) {
93 k_timer_start(&ot_ms_timer, K_MSEC(delta), K_NO_WAIT);
94 } else {
95 ot_timer_ms_fired(NULL);
96 }
97 }
98
otPlatAlarmMilliStop(otInstance * aInstance)99 void otPlatAlarmMilliStop(otInstance *aInstance)
100 {
101 ARG_UNUSED(aInstance);
102
103 k_timer_stop(&ot_ms_timer);
104 }
105
otPlatAlarmMicroStartAt(otInstance * aInstance,uint32_t aT0,uint32_t aDt)106 void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
107 {
108 ARG_UNUSED(aInstance);
109
110 int32_t delta = (int32_t)(aT0 + aDt - otPlatAlarmMicroGetNow());
111
112 if (delta > 0) {
113 k_timer_start(&ot_us_timer, K_USEC(delta), K_NO_WAIT);
114 } else {
115 ot_timer_us_fired(NULL);
116 }
117 }
118
otPlatAlarmMicroStop(otInstance * aInstance)119 void otPlatAlarmMicroStop(otInstance *aInstance)
120 {
121 ARG_UNUSED(aInstance);
122
123 k_timer_stop(&ot_us_timer);
124 }
125
otPlatAlarmMicroGetNow(void)126 uint32_t otPlatAlarmMicroGetNow(void)
127 {
128 return (uint32_t)(k_ticks_to_us_floor64(k_uptime_ticks()) - time_offset_us);
129 }
130
otPlatTimeGetXtalAccuracy(void)131 uint16_t otPlatTimeGetXtalAccuracy(void)
132 {
133 return otPlatRadioGetCslAccuracy(NULL);
134 }
135
136 #ifdef CONFIG_HDLC_RCP_IF
otPlatTimeGet(void)137 uint64_t otPlatTimeGet(void)
138 {
139 return k_ticks_to_us_floor64(k_uptime_ticks());
140 }
141 #endif
142