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