Master Thesis  V1.0
Research and Design of Sensor Node for NMSD Treatment
delay.c File Reference

Delay functionality. More...

#include <stdint.h>
#include <stdbool.h>
#include "em_device.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_gpio.h"
#include "em_rtc.h"
#include "delay.h"
#include "debug_dbprint.h"
Include dependency graph for delay.c:

Go to the source code of this file.

Macros

#define ULFRCOFREQ   1000
 
#define ULFRCOFREQ_MS   1.000
 
#define LFXOFREQ   32768
 
#define LFXOFREQ_MS   32.768
 

Functions

void delay (uint32_t msDelay)
 Wait for a certain amount of milliseconds in EM2/3. More...
 
void sleep (uint32_t sSleep)
 Sleep for a certain amount of seconds in EM2/3. More...
 
bool RTC_checkWakeup (void)
 Method to check if the wakeup was caused by the RTC. More...
 
void RTC_clearWakeup (void)
 Method to clear RTC_sleep_wakeup. More...
 
uint32_t RTC_getPassedSleeptime (void)
 Method to get the time spend sleeping (in seconds) in the case of GPIO wake-up. More...
 
void SysTick_Handler (void)
 Interrupt Service Routine for system tick counter. More...
 

Variables

bool sleeping = false
 
bool RTC_initialized = false
 
bool SysTick_initialized = false
 

Detailed Description

Delay functionality.

Version
3.2
Author
Brecht Van Eeckhoudt

Versions

  • v1.0: Moved delay functionality from util.c to this file.
  • v1.1: Changed global variables to be static (~hidden) and added dbprint \ n \ r fixes.
  • v1.2: Removed EM1 delay method (see note in delayRTCC_EM2).
  • v1.3: Cleaned up includes, added option to select SysTick/EM2 delay functionality and moved all of the logic in one delay method. Renamed sleep method.
  • v1.4: Changed names of static variables, made initRTCcomp static.
  • v1.5: Updated documentation.
  • v1.6: Changed RTCcomp names to RTC.
  • v1.7: Moved IRQ handler of RTC to this file.
  • v1.8: Added ULFRCO logic.
  • v1.9: Updated code with new DEFINE checks.
  • v2.0: Added functionality to enable/disable the clocks only when necessary.
  • v2.1: Added functionality to check if a wakeup was caused by the RTC.
  • v2.2: Removed some clock disabling statements.
  • v2.3: Changed error numbering.
  • v2.4: Moved definitions from header to source file.
  • v2.5: Added functionality to the time spend sleeping.
  • v3.0: Disabled peripheral clock before entering an error function, added functionality to exit methods after error call and updated version number.
  • v3.1: Removed static before some local variables (not necessary).
  • v3.2: Moved msTicks variable and systick handler in #if check.

License

Copyright (C) 2019 - Brecht Van Eeckhoudt

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

A copy of the GNU General Public License can be found in the LICENSE file along with this source code.


Some methods use code obtained from examples from Silicon Labs' GitHub. These sections are licensed under the Silabs License Agreement. See the file "Silabs_License_Agreement.txt" for details. Before using this software for any purpose, you must agree to the terms of that agreement.

Definition in file delay.c.

Macro Definition Documentation

◆ LFXOFREQ

#define LFXOFREQ   32768

Definition at line 80 of file delay.c.

◆ LFXOFREQ_MS

#define LFXOFREQ_MS   32.768

Definition at line 81 of file delay.c.

◆ ULFRCOFREQ

#define ULFRCOFREQ   1000

Definition at line 78 of file delay.c.

◆ ULFRCOFREQ_MS

#define ULFRCOFREQ_MS   1.000

Definition at line 79 of file delay.c.

Function Documentation

◆ delay()

void delay ( uint32_t  msDelay)

Wait for a certain amount of milliseconds in EM2/3.

This method also initializes SysTick/RTC if necessary.

Parameters
[in]msDelayThe delay time in milliseconds.

Definition at line 116 of file delay.c.

117 {
118 
119 #if SYSTICKDELAY == 1 /* SysTick delay selected */
120 
121  /* Initialize SysTick if not already the case */
122  if (!SysTick_initialized)
123  {
124  /* Initialize and start SysTick
125  * Number of ticks between interrupt = cmuClock_CORE/1000 */
126  if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1);
127 
128 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
129  dbinfo("SysTick initialized");
130 #endif /* DEBUG_DBPRINT */
131 
132  SysTick_initialized = true;
133  }
134  else
135  {
136  /* Enable SysTick interrupt and counter by setting their bits. */
137  SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
138  }
139 
140  /* Wait a certain amount of ticks */
141  uint32_t curTicks = msTicks;
142  while ((msTicks - curTicks) < msDelay);
143 
144  /* Disable SysTick interrupt and counter (needs to be done before entering EM2/3) by clearing their bits. */
145  SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk & ~SysTick_CTRL_ENABLE_Msk;
146 
147 #else /* EM2/3 RTC delay selected */
148 
149 
150  /* Initialize RTC if not already the case */
151  if (!RTC_initialized) initRTC();
152  else
153  {
154  /* Enable necessary oscillator and clocks */
155 
156 #if ULFRCO == 1 /* ULFRCO selected */
157 
158  /* No specific code here */
159 
160 #else /* LFXO selected */
161 
162  /* Enable the low-frequency crystal oscillator for the RTC */
163  //CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
164 
165 #endif /* ULFRCO/LFXO selection */
166 
167  /* Enable the clock to the interface of the low energy modules
168  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
169  //CMU_ClockEnable(cmuClock_HFLE, true);
170 
171  /* Turn on the RTC clock */
172  CMU_ClockEnable(cmuClock_RTC, true);
173  }
174 
175  /* Set RTC compare value for RTC compare register 0 depending on ULFRCO/LFXO selection */
176 
177 #if ULFRCO == 1 /* ULFRCO selected */
178 
179  if ((ULFRCOFREQ_MS * msDelay) <= 0x00ffffff) RTC_CompareSet(0, (ULFRCOFREQ_MS * msDelay));
180  else
181  {
182 
183 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
184  dbcrit("Delay too long, can't fit in the field!");
185 #endif /* DEBUG_DBPRINT */
186 
187  /* Turn off the RTC clock */
188  CMU_ClockEnable(cmuClock_RTC, false);
189 
190  //error(14);
191 
192  /* Exit function */
193  return;
194  }
195 
196 #else /* LFXO selected */
197 
198  if ((LFXOFREQ_MS * msDelay) <= 0x00ffffff) RTC_CompareSet(0, (LFXOFREQ_MS * msDelay));
199  else
200  {
201 
202 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
203  dbcrit("Delay too long, can't fit in the field!");
204 #endif /* DEBUG_DBPRINT */
205 
206  /* Turn off the RTC clock */
207  CMU_ClockEnable(cmuClock_RTC, false);
208 
209  //error(15);
210 
211  /* Exit function */
212  return;
213  }
214 
215 #endif /* ULFRCO/LFXO selection */
216 
217 
218  /* Start the RTC */
219  RTC_Enable(true);
220 
221  /* Enter EM2/3 depending on ULFRCO/LFXO selection */
222 
223 #if ULFRCO == 1 /* ULFRCO selected */
224  /* In EM3, high and low frequency clocks are disabled. No oscillator (except the ULFRCO) is running.
225  * Furthermore, all unwanted oscillators are disabled in EM3. This means that nothing needs to be
226  * manually disabled before the statement EMU_EnterEM3(true); */
227  EMU_EnterEM3(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
228 #else /* LFXO selected */
229  EMU_EnterEM2(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
230 #endif /* ULFRCO/LFXO selection */
231 
232 
233  /* Disable used oscillator and clocks after wake-up */
234 
235 #if ULFRCO == 1 /* ULFRCO selected */
236 
237  /* No specific code here */
238 
239 #else /* LFXO selected */
240 
241  /* Disable the low-frequency crystal oscillator for the RTC */
242  //CMU_OscillatorEnable(cmuOsc_LFXO, false, true);
243 
244 #endif /* ULFRCO/LFXO selection */
245 
246  /* Disable the clock to the interface of the low energy modules
247  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
248  //CMU_ClockEnable(cmuClock_HFLE, false);
249 
250  /* Turn off the RTC clock */
251  CMU_ClockEnable(cmuClock_RTC, false);
252 
253 #endif /* SysTick/RTC selection */
254 
255 }

References dbinfo(), and SysTick_initialized.

Referenced by blink(), ICM_20948_accelGyroCalibrate(), ICM_20948_gyroCalibrate(), ICM_20948_Init(), ICM_20948_Init2(), ICM_20948_lowPowerModeEnter(), ICM_20948_reset(), ICM_20948_reset_mag(), ICM_20948_wakeOnMotionITEnable(), measure_send(), and waitForSlave4().

◆ RTC_checkWakeup()

bool RTC_checkWakeup ( void  )

Method to check if the wakeup was caused by the RTC.

Returns
The value of RTC_sleep_wakeup.

Definition at line 396 of file delay.c.

397 {
398  return (RTC_sleep_wakeup);
399 }

◆ RTC_clearWakeup()

void RTC_clearWakeup ( void  )

Method to clear RTC_sleep_wakeup.

Definition at line 406 of file delay.c.

407 {
408  RTC_sleep_wakeup = false;
409 }

◆ RTC_getPassedSleeptime()

uint32_t RTC_getPassedSleeptime ( void  )

Method to get the time spend sleeping (in seconds) in the case of GPIO wake-up.

Returns
The time spend sleeping in seconds.

Definition at line 420 of file delay.c.

421 {
422  uint32_t sSleep = RTC_CounterGet();
423 
424  /* Disable the counter */
425  RTC_Enable(false);
426 
427 #if ULFRCO == 1 /* ULFRCO selected */
428  sSleep /= ULFRCOFREQ;
429 #else /* LFXO selected */
430  sSleep /= LFXOFREQ;
431 #endif /* ULFRCO/LFXO selection */
432 
433  return (sSleep);
434 }

References LFXOFREQ, and ULFRCOFREQ.

◆ sleep()

void sleep ( uint32_t  sSleep)

Sleep for a certain amount of seconds in EM2/3.

This method also initializes the RTC if necessary.

Parameters
[in]sSleepThe sleep time in seconds.

Definition at line 268 of file delay.c.

269 {
270  /* Initialize RTC if not already the case */
271  if (!RTC_initialized) initRTC();
272  else
273  {
274  /* Enable necessary oscillator and clocks */
275 
276 #if ULFRCO == 1 /* ULFRCO selected */
277 
278  /* No specific code here */
279 
280 #else /* LFXO selected */
281 
282  /* Enable the low-frequency crystal oscillator for the RTC */
283  //CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
284 
285 #endif /* ULFRCO/LFXO selection */
286 
287  /* Enable the clock to the interface of the low energy modules
288  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
289  //CMU_ClockEnable(cmuClock_HFLE, true);
290 
291  /* Turn on the RTC clock */
292  CMU_ClockEnable(cmuClock_RTC, true);
293  }
294 
295 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
296 #if ULFRCO == 1 /* ULFRCO selected */
297  dbwarnInt("Sleeping in EM3 for ", sSleep, " s\n\r");
298 #else /* LFXO selected */
299  dbwarnInt("Sleeping in EM2 for ", sSleep, " s\n\r");
300 #endif /* ULFRCO/LFXO selection */
301 #endif /* DEBUG_DBPRINT */
302 
303  /* Set RTC compare value for RTC compare register 0 depending on ULFRCO/LFXO selection */
304 
305 #if ULFRCO == 1 /* ULFRCO selected */
306 
307  if ((ULFRCOFREQ * sSleep) <= 0x00ffffff) RTC_CompareSet(0, (ULFRCOFREQ * sSleep));
308  else
309  {
310 
311 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
312  dbcrit("Delay too long, can't fit in the field!");
313 #endif /* DEBUG_DBPRINT */
314 
315  /* Turn off the RTC clock */
316  CMU_ClockEnable(cmuClock_RTC, false);
317 
318  //error(16);
319 
320  /* Exit function */
321  return;
322  }
323 
324 #else /* LFXO selected */
325 
326  if ((LFXOFREQ * sSleep) <= 0x00ffffff) RTC_CompareSet(0, (LFXOFREQ * sSleep));
327  else
328  {
329 
330 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
331  dbcrit("Delay too long, can't fit in the field!");
332 #endif /* DEBUG_DBPRINT */
333 
334  /* Turn off the RTC clock */
335  CMU_ClockEnable(cmuClock_RTC, false);
336 
337  error(17);
338 
339  /* Exit function */
340  return;
341  }
342 
343 #endif /* ULFRCO/LFXO selection */
344 
345  /* Indicate that we're using the sleep method */
346  sleeping = true;
347 
348 
349  /* Start the RTC */
350  RTC_Enable(true);
351 
352  /* Enter EM2/3 depending on ULFRCO/LFXO selection */
353 
354 #if ULFRCO == 1 /* ULFRCO selected */
355  /* In EM3, high and low frequency clocks are disabled. No oscillator (except the ULFRCO) is running.
356  * Furthermore, all unwanted oscillators are disabled in EM3. This means that nothing needs to be
357  * manually disabled before the statement EMU_EnterEM3(true); */
358  EMU_EnterEM3(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
359 #else /* LFXO selected */
360  EMU_EnterEM2(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
361 #endif /* ULFRCO/LFXO selection */
362 
363 
364  /* Indicate that we're no longer sleeping */
365  sleeping = false;
366 
367  /* Disable used oscillator and clocks after wake-up */
368 
369 #if ULFRCO == 1 /* ULFRCO selected */
370 
371  /* No specific code here */
372 
373 #else /* LFXO selected */
374 
375  /* Disable the low-frequency crystal oscillator for the RTC */
376  //CMU_OscillatorEnable(cmuOsc_LFXO, false, true);
377 
378 #endif /* ULFRCO/LFXO selection */
379 
380  /* Disable the clock to the interface of the low energy modules
381  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
382  //CMU_ClockEnable(cmuClock_HFLE, false);
383 
384  /* Turn off the RTC clock */
385  CMU_ClockEnable(cmuClock_RTC, false);
386 }

References RTC_initialized.

◆ SysTick_Handler()

void SysTick_Handler ( void  )

Interrupt Service Routine for system tick counter.

Definition at line 507 of file delay.c.

508 {
509  msTicks++; /* Increment counter necessary by SysTick delay functionality */
510 }

Variable Documentation

◆ RTC_initialized

bool RTC_initialized = false

Definition at line 95 of file delay.c.

Referenced by sleep().

◆ sleeping

bool sleeping = false

Definition at line 94 of file delay.c.

◆ SysTick_initialized

bool SysTick_initialized = false

Definition at line 98 of file delay.c.

Referenced by delay().

LFXOFREQ
#define LFXOFREQ
Definition: delay.c:80
RTC_initialized
bool RTC_initialized
Definition: delay.c:95
sleeping
bool sleeping
Definition: delay.c:94
dbwarnInt
void dbwarnInt(char *message1, int32_t value, char *message2)
ULFRCOFREQ_MS
#define ULFRCOFREQ_MS
Definition: delay.c:79
SysTick_initialized
bool SysTick_initialized
Definition: delay.c:98
LFXOFREQ_MS
#define LFXOFREQ_MS
Definition: delay.c:81
ULFRCOFREQ
#define ULFRCOFREQ
Definition: delay.c:78
dbcrit
void dbcrit(char *message)
dbinfo
void dbinfo(char *message)