21 #include "nrf_assert.h" 24 #include "isr_manager.h" 30 #define RTC_ID CONCAT_2(NRF_RTC,MS_TIMER_RTC_USED) 31 #define RTC_IRQN CONCAT_3(RTC, MS_TIMER_RTC_USED, _IRQn) 32 #define RTC_IRQ_Handler CONCAT_3(RTC, MS_TIMER_RTC_USED, _IRQHandler) 37 #define RTC_MAX_COUNT 0xFFFFFF 42 static struct ms_timer_t
44 volatile uint64_t timer_mode;
45 volatile uint32_t timer_over_flow_num;
46 void (*timer_handler)(void);
50 static volatile uint32_t ms_timers_status;
53 static volatile uint32_t overflow_req_status;
62 static void cal_overflow_ticks_req (uint32_t counter_val, uint64_t ticks, uint32_t
id)
65 if(ticks < RTC_MAX_COUNT)
68 ms_timer[id].timer_over_flow_num = 0;
69 RTC_ID->CC[id] = (ticks + counter_val) & (0xFFFFFF);
70 RTC_ID->EVTENSET = 1 << (RTC_INTENSET_COMPARE0_Pos + id);
71 RTC_ID->INTENSET = 1 << (RTC_INTENSET_COMPARE0_Pos + id);
72 overflow_req_status &= 0<<id;
76 ms_timer[id].timer_over_flow_num = (ticks -
77 (RTC_MAX_COUNT - counter_val)) / (1<<24) + 1;
78 RTC_ID->CC[id] = (ticks - (RTC_MAX_COUNT - counter_val)) % (0x1 << 24);
79 overflow_req_status |= 1<<id;
80 RTC_ID->INTENSET = RTC_INTENSET_OVRFLW_Msk;
81 RTC_ID->EVTENSET = RTC_EVTENSET_OVRFLW_Msk;
88 void rtc_overflow_handler ()
92 if(ms_timer[
id].timer_over_flow_num != 0)
94 if(ms_timer[
id].timer_over_flow_num == 1)
96 RTC_ID->EVTENSET = 1 << (RTC_INTENSET_COMPARE0_Pos + id);
97 RTC_ID->INTENSET = 1 << (RTC_INTENSET_COMPARE0_Pos + id);
98 overflow_req_status &= 0<<id;
100 ms_timer[id].timer_over_flow_num--;
103 if(overflow_req_status == 0)
105 RTC_ID->INTENCLR = RTC_INTENSET_OVRFLW_Msk;
106 RTC_ID->EVTENCLR = RTC_EVTENSET_OVRFLW_Msk;
113 RTC_ID->TASKS_STOP = 1;
118 ms_timer[i].timer_over_flow_num = -1;
119 ms_timer[i].timer_handler = NULL;
122 ms_timers_status = 0;
125 NVIC_SetPriority(RTC_IRQN, irq_priority);
126 NVIC_EnableIRQ(RTC_IRQN);
137 ticks = ticks & 0x00FFFFFFFFFFFFFF;
148 ticks = (ticks < 2) ? 2 : ticks;
149 uint32_t counter_val = RTC_ID->COUNTER;
151 ms_timer[id].timer_handler = handler;
158 ms_timer[id].timer_mode = ticks;
161 cal_overflow_ticks_req (counter_val, ticks,
id);
163 RTC_ID->EVENTS_COMPARE[id] = 0;
165 if (ms_timers_status == 0)
167 RTC_ID->EVENTS_OVRFLW = 0;
168 RTC_ID->TASKS_START = 1;
170 ms_timers_status |= 1 << id;
176 ms_timers_status &= ~(1 << id);
177 RTC_ID->EVTENCLR = 1 << (RTC_INTENSET_COMPARE0_Pos + id);
178 RTC_ID->INTENCLR = 1 << (RTC_INTENSET_COMPARE0_Pos + id);
180 if (ms_timers_status == 0)
182 RTC_ID->TASKS_STOP = 1;
188 return ((ms_timers_status & (1 <<
id)) != 0);
196 void ms_timer_rtc_Handler ()
198 void RTC_IRQ_Handler()
201 uint32_t counter_val = RTC_ID->COUNTER;
202 if(RTC_ID->EVENTS_OVRFLW)
205 RTC_ID->EVENTS_OVRFLW = 0;
207 rtc_overflow_handler ();
211 if (RTC_ID->EVENTS_COMPARE[
id])
213 RTC_ID->EVTENCLR = 1 << (RTC_INTENSET_COMPARE0_Pos + id);
214 RTC_ID->INTENCLR = 1 << (RTC_INTENSET_COMPARE0_Pos + id);
216 RTC_ID->EVENTS_COMPARE[id] = 0;
217 (void)RTC_ID->EVENTS_COMPARE[
id];
220 void (*cb_handler)(void) = NULL;
221 if (ms_timer[
id].timer_handler != NULL)
223 cb_handler = ms_timer[id].timer_handler;
232 cal_overflow_ticks_req (counter_val, ms_timer[
id].timer_mode,
id);
235 if(cb_handler != NULL)
Strcture for Operation time.
Repeated call of the timer.
bool ms_timer_get_on_status(ms_timer_num id)
#define ASSERT(expression)
Macro for runtime assertion of an expression. If the expression is false the assert_nrf_callback func...
Not a timer, just used to find the number of timers.
void ms_timer_init(uint32_t irq_priority)
ms_timer_mode
Enumeration to specify the mode of operation of the timer.
void ms_timer_start(ms_timer_num id, ms_timer_mode mode, uint64_t ticks, void(*handler)(void))
ms_timer_num
Enumeration used for specifying the timers that can be used with a RTC peripheral.
#define LFCLK_FREQ
Frequency of the low frequency clock is 32.768 kHz.
#define ROUNDED_DIV(A, B)
Rounded integer division where the result is the integer closest to the answer instead of flooring th...
void ms_timer_stop(ms_timer_num id)
One shot call of the timer.