ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
ruuvi_nrf5_sdk15_rtc_mcu.c
Go to the documentation of this file.
1
47#include "ruuvi_interface_rtc.h"
48#if RUUVI_NRF5_SDK15_RTC_ENABLED
49#include "nrf5_sdk15_config.h"
50#include "ruuvi_driver_error.h"
51#include "ruuvi_driver_sensor.h"
52#include "ruuvi_interface_log.h"
54#include "nrf.h"
55static inline void LOGW (const char * const msg)
56{
58}
59
60#ifdef NRF5_SDK15_RTC_INSTANCE
61#include "nrf_drv_rtc.h"
62#include "nrf_drv_clock.h"
63#include <stdint.h>
64#include <stdbool.h>
65
70const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE (NRF5_SDK15_RTC_INSTANCE);
71static uint64_t ticks = 0;
72static bool m_is_init = false;
73
77static void rtc_handler (nrf_drv_rtc_int_type_t int_type)
78{
79 if (int_type == NRF_DRV_RTC_INT_OVERFLOW)
80 {
81 // nRF RTC is 24 bits wide.
82 ticks += (1 << 24);
83 }
84}
85
92{
93 if (true == m_is_init) { return RD_ERROR_INVALID_STATE; }
94
95 ret_code_t err_code = NRF_SUCCESS;
96
97 // Initialize clock if not already initialized
98 if (false == nrf_drv_clock_init_check()) { err_code |= nrf_drv_clock_init(); }
99
100 // Request LFCLK for RTC
101 nrf_drv_clock_lfclk_request (NULL);
102 nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
103 config.prescaler = 0;
104 ticks = 0;
105 err_code = nrf_drv_rtc_init (&rtc, &config, rtc_handler);
106 //Power on RTC instance before clearing the counter and enabling overflow
107 nrf_drv_rtc_enable (&rtc);
108 nrf_drv_rtc_counter_clear (&rtc);
109 nrf_drv_rtc_overflow_enable (&rtc, true);
110
111 if (NRF_SUCCESS == err_code) { m_is_init = true; }
112
113 return ruuvi_nrf5_sdk15_to_ruuvi_error (err_code);
114}
115
122{
123 if (true == m_is_init)
124 {
125 m_is_init = false;
126 nrf_drv_rtc_uninit (&rtc);
127 nrf_drv_clock_lfclk_release();
128 }
129
130 return RD_SUCCESS;
131}
132
136uint64_t ri_rtc_millis (void)
137{
138 if (false == m_is_init) { return RD_UINT64_INVALID; }
139
140 uint64_t ms = nrf_drv_rtc_counter_get (&rtc) + ticks;
141 return ( (ms * 1000) / 32768);
142}
143
144// If HW-RTC is not available, try timer.
145#elif RUUVI_NRF5_SDK15_TIMER_ENABLED
148#define DUMMY_RTC_INTERVAL 1024
149static ri_timer_id_t counter_timer;
150static volatile uint64_t m_dummy;
151static void counter_handler (void * p_context)
152{
153 uint64_t mask = ~ ( (uint64_t) DUMMY_RTC_INTERVAL - 1);
154 m_dummy &= mask;
155 m_dummy += DUMMY_RTC_INTERVAL;
156}
157
164{
165 m_dummy = 0;
166 LOGW ("Using timer-tick based RTC\r\n");
167 // Use timer interrupts at 1024 ms to increment RTC.
168 rd_status_t err_code = RD_SUCCESS;
169
170 if (!ri_timer_is_init())
171 {
172 err_code = ri_timer_init();
173 }
174
175 if (NULL == counter_timer)
176 {
177 err_code |= ri_timer_create (&counter_timer,
179 counter_handler);
180 }
181
182 err_code |= ri_timer_start (counter_timer, DUMMY_RTC_INTERVAL, NULL);
183 return (RD_SUCCESS == err_code) ? RD_SUCCESS :
185}
186
193{
194 m_dummy = 0;
195
196 if (NULL != counter_timer) { ri_timer_stop (counter_timer); }
197
198 return RD_SUCCESS;
199}
200
207uint64_t ri_rtc_millis (void)
208{
209 return m_dummy++;
210}
211
212// If timer is not available, use plain counter.
213#else
214// TODO
215#endif
216#endif
uint32_t rd_status_t
bitfield for representing errors
rd_status_t ruuvi_nrf5_sdk15_to_ruuvi_error(const ret_code_t error)
convert nrf5 sdk15 error code into Ruuvi error code.
#define RD_ERROR_NOT_SUPPORTED
Not supported.
#define RD_SUCCESS
Internal Error.
#define RD_UINT64_INVALID
Signal that value should not be used.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
void ri_log(const ri_log_severity_t severity, const char *const message)
Queues messages into log.
@ RI_LOG_LEVEL_WARNING
bool ri_timer_is_init(void)
Check if timer is initialized.
rd_status_t ri_timer_start(ri_timer_id_t timer_id, uint32_t ms, void *const context)
Start given timer at a mode defined in ri_timer_create.
rd_status_t ri_timer_create(ri_timer_id_t *p_timer_id, ri_timer_mode_t mode, ruuvi_timer_timeout_handler_t timeout_handler)
rd_status_t ri_timer_init(void)
rd_status_t ri_timer_stop(ri_timer_id_t timer_id)
void * ri_timer_id_t
Pointer to timer data.
@ RI_TIMER_MODE_REPEATED
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Ruuvi sensor interface Lifecycle: Beta
rd_status_t ri_rtc_init(void)
Initializes RTC at 0 ms.
rd_status_t ri_rtc_uninit(void)
Stop RTC if applicable.
uint64_t ri_rtc_millis(void)
Get milliseconds since init.
Interface functions to timer.