ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
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"
53 #include "ruuvi_nrf5_sdk15_error.h"
54 #include "nrf.h"
55 static 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 
70 const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE (NRF5_SDK15_RTC_INSTANCE);
71 static uint64_t ticks = 0;
72 static bool m_is_init = false;
73 
77 static 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 
136 uint64_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
146 #include "ruuvi_interface_timer.h"
148 #define DUMMY_RTC_INTERVAL 1024
149 static ri_timer_id_t counter_timer;
150 static volatile uint64_t m_dummy;
151 static 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 
207 uint64_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.