IoT-MBBR (masterthesis)
Masterthesis upgrading a Moving Bed BioReactor with extra sensors and cloud connectivity.
delay.h File Reference

Delay functionality. More...

#include <stdint.h>
#include <stdbool.h>

Go to the source code of this file.

Macros

#define SYSTICKDELAY   0
 
#define ULFRCO   1
 
#define ANNOUNCE_SLEEPING   1
 

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...
 

Detailed Description

Delay functionality.

Version
3.4
Author
Brecht Van Eeckhoudt

License

Copyright (C) 2020 - 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.h.

Macro Definition Documentation

◆ ANNOUNCE_SLEEPING

#define ANNOUNCE_SLEEPING   1

Public definition to select if the sleep time should be announced using dbprint or not

  • 0 - Don't announce sleeping/
  • 1 - Announce sleeping.

Definition at line 62 of file delay.h.

◆ SYSTICKDELAY

#define SYSTICKDELAY   0

Public definition to select which delay to use

  • 1 - Use SysTick delays (don't to to sleep when calling delay)
  • 0 - Use EM2/3 RTC compare for both delay and sleep.

Definition at line 49 of file delay.h.

◆ ULFRCO

#define ULFRCO   1

Public definition to select the use of the crystal or the oscillator

  • 0 - Use the low-frequency crystal oscillator (LFXO), EM2 sleep is used.
  • 1 - Use the ultra low-frequency RC oscillator (ULFRCO), EM3 sleep is used but delays are less precise timing-wise. ** EM3: All unwanted oscillators are disabled, they don't need to manually disabled before EMU_EnterEM3.**

Definition at line 56 of file delay.h.

Function Documentation

◆ delay()

void delay ( uint32_t  msDelay)

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

This method can be called with the argument 0 to force initialization.
This method also initializes SysTick/RTC if necessary.

Parameters
[in]msDelayThe delay time in milliseconds.

Definition at line 124 of file delay.c.

125 {
126 
127 #if SYSTICKDELAY == 1 /* SysTick delay selected */
128 
129  /* Initialize SysTick if not already the case */
130  if (!SysTick_initialized)
131  {
132  /* Initialize and start SysTick
133  * Number of ticks between interrupt = cmuClock_CORE/1000 */
134  if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1);
135 
136 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
137  dbinfo("SysTick initialized");
138 #endif /* DEBUG_DBPRINT */
139 
140  SysTick_initialized = true;
141  }
142  else
143  {
144  /* Only execute if we're not initializing */
145  if (msDelay > 0)
146  {
147  /* Enable SysTick interrupt and counter by setting their bits. */
148  SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
149  }
150  }
151 
152  /* Only execute if we're not initializing */
153  if (msDelay > 0)
154  {
155  /* Wait a certain amount of ticks */
156  uint32_t curTicks = msTicks;
157  while ((msTicks - curTicks) < msDelay);
158 
159  /* Disable SysTick interrupt and counter (needs to be done before entering EM2/3) by clearing their bits. */
160  SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk & ~SysTick_CTRL_ENABLE_Msk;
161  }
162 
163 #else /* EM2/3 RTC delay selected */
164 
165 
166  /* Initialize RTC if not already the case */
167  if (!RTC_initialized) initRTC();
168  else
169  {
170  /* Only execute if we're not initializing */
171  if (msDelay > 0)
172  {
173  /* Enable necessary oscillator and clocks */
174 
175 #if ULFRCO == 1 /* ULFRCO selected */
176 
177  /* No specific code here */
178 
179 #else /* LFXO selected */
180 
181  /* Enable the low-frequency crystal oscillator for the RTC */
182  //CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
183 
184 #endif /* ULFRCO/LFXO selection */
185 
186  /* Enable the clock to the interface of the low energy modules
187  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
188  //CMU_ClockEnable(cmuClock_HFLE, true);
189 
190  /* Turn on the RTC clock */
191  CMU_ClockEnable(cmuClock_RTC, true);
192  }
193  }
194 
195  /* Only execute if we're not initializing */
196  if (msDelay > 0)
197  {
198 
199  /* Set RTC compare value for RTC compare register 0 depending on ULFRCO/LFXO selection */
200 
201 #if ULFRCO == 1 /* ULFRCO selected */
202 
203  if ((ULFRCOFREQ_MS * msDelay) <= 0x00ffffff) RTC_CompareSet(0, (ULFRCOFREQ_MS * msDelay));
204  else
205  {
206 
207 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
208  dbcrit("Delay too long, can't fit in the field!");
209 #endif /* DEBUG_DBPRINT */
210 
211  /* Turn off the RTC clock */
212  CMU_ClockEnable(cmuClock_RTC, false);
213 
214 // error(14);
215 
216  /* Exit function */
217  return;
218  }
219 
220 #else /* LFXO selected */
221 
222  if ((LFXOFREQ_MS * msDelay) <= 0x00ffffff) RTC_CompareSet(0, (LFXOFREQ_MS * msDelay));
223  else
224  {
225 
226 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
227  dbcrit("Delay too long, can't fit in the field!");
228 #endif /* DEBUG_DBPRINT */
229 
230  /* Turn off the RTC clock */
231  CMU_ClockEnable(cmuClock_RTC, false);
232 
233 // error(15);
234 
235  /* Exit function */
236  return;
237  }
238 
239 #endif /* ULFRCO/LFXO selection */
240 
241 
242  /* Start the RTC */
243  RTC_Enable(true);
244 
245  /* Enter EM2/3 depending on ULFRCO/LFXO selection */
246 
247 #if ULFRCO == 1 /* ULFRCO selected */
248  /* In EM3, high and low frequency clocks are disabled. No oscillator (except the ULFRCO) is running.
249  * Furthermore, all unwanted oscillators are disabled in EM3. This means that nothing needs to be
250  * manually disabled before the statement EMU_EnterEM3(true); */
251  EMU_EnterEM3(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
252 #else /* LFXO selected */
253  EMU_EnterEM2(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
254 #endif /* ULFRCO/LFXO selection */
255 
256 
257  /* Disable used oscillator and clocks after wake-up */
258 
259 #if ULFRCO == 1 /* ULFRCO selected */
260 
261  /* No specific code here */
262 
263 #else /* LFXO selected */
264 
265  /* Disable the low-frequency crystal oscillator for the RTC */
266  //CMU_OscillatorEnable(cmuOsc_LFXO, false, true);
267 
268 #endif /* ULFRCO/LFXO selection */
269 
270  /* Disable the clock to the interface of the low energy modules
271  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
272  //CMU_ClockEnable(cmuClock_HFLE, false);
273 
274  /* Turn off the RTC clock */
275  CMU_ClockEnable(cmuClock_RTC, false);
276  }
277 
278 #endif /* SysTick/RTC selection */
279 
280 }
static void initRTC(void)
RTC initialization.
Definition: delay.c:481
bool RTC_initialized
Definition: delay.c:102
void dbinfo(char *message)
Print an info string (char array) to USARTx and go to the next line.
Definition: dbprint.c:505
#define LFXOFREQ_MS
Definition: delay.c:88
#define ULFRCOFREQ_MS
Definition: delay.c:86
void dbcrit(char *message)
Print a critical error string (char array) in red to USARTx and go to the next line.
Definition: dbprint.c:541
unsigned int uint32_t
Typedef defining 32 bit unsigned int type. The developer should modify this to suit the platform bein...
Definition: vl53l1_types.h:78

◆ 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 432 of file delay.c.

433 {
434  return (RTC_sleep_wakeup);
435 }
static volatile bool RTC_sleep_wakeup
Definition: delay.c:94

◆ RTC_clearWakeup()

void RTC_clearWakeup ( void  )

Method to clear RTC_sleep_wakeup.

Definition at line 442 of file delay.c.

443 {
444  RTC_sleep_wakeup = false;
445 }
static volatile bool RTC_sleep_wakeup
Definition: delay.c:94

◆ 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 456 of file delay.c.

457 {
458  uint32_t sSleep = RTC_CounterGet();
459 
460  /* Disable the counter */
461  RTC_Enable(false);
462 
463 #if ULFRCO == 1 /* ULFRCO selected */
464  sSleep /= ULFRCOFREQ;
465 #else /* LFXO selected */
466  sSleep /= LFXOFREQ;
467 #endif /* ULFRCO/LFXO selection */
468 
469  return (sSleep);
470 }
#define ULFRCOFREQ
Definition: delay.c:85
#define LFXOFREQ
Definition: delay.c:87
unsigned int uint32_t
Typedef defining 32 bit unsigned int type. The developer should modify this to suit the platform bein...
Definition: vl53l1_types.h:78

◆ 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 293 of file delay.c.

294 {
295  /* Initialize RTC if not already the case */
296  if (!RTC_initialized) initRTC();
297  else
298  {
299  /* Only execute if we're not initializing */
300  if (sSleep > 0)
301  {
302 
303  /* Enable necessary oscillator and clocks */
304 
305 #if ULFRCO == 1 /* ULFRCO selected */
306 
307  /* No specific code here */
308 
309 #else /* LFXO selected */
310 
311  /* Enable the low-frequency crystal oscillator for the RTC */
312  //CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
313 
314 #endif /* ULFRCO/LFXO selection */
315 
316  /* Enable the clock to the interface of the low energy modules
317  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
318  //CMU_ClockEnable(cmuClock_HFLE, true);
319 
320  /* Turn on the RTC clock */
321  CMU_ClockEnable(cmuClock_RTC, true);
322  }
323  }
324 
325  /* Only execute if we're not initializing */
326  if (sSleep > 0)
327  {
328 
329 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
330 #if ANNOUNCE_SLEEPING == 1 /* Announce sleeping enabled */
331 #if ULFRCO == 1 /* ULFRCO selected */
332  dbinfoInt("Sleeping in EM3 for ", sSleep, " s\n\r\n\r");
333 #else /* LFXO selected */
334  dbinfoInt("Sleeping in EM2 for ", sSleep, " s\n\r\n\r");
335 #endif /* ULFRCO/LFXO selection */
336 #endif /* Announce sleeping */
337 #endif /* DEBUG_DBPRINT */
338 
339  /* Set RTC compare value for RTC compare register 0 depending on ULFRCO/LFXO selection */
340 
341 #if ULFRCO == 1 /* ULFRCO selected */
342 
343  if ((ULFRCOFREQ * sSleep) <= 0x00ffffff) RTC_CompareSet(0, (ULFRCOFREQ * sSleep));
344  else
345  {
346 
347 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
348  dbcrit("Delay too long, can't fit in the field!");
349 #endif /* DEBUG_DBPRINT */
350 
351  /* Turn off the RTC clock */
352  CMU_ClockEnable(cmuClock_RTC, false);
353 
354 // error(16);
355 
356  /* Exit function */
357  return;
358  }
359 
360 #else /* LFXO selected */
361 
362  if ((LFXOFREQ * sSleep) <= 0x00ffffff) RTC_CompareSet(0, (LFXOFREQ * sSleep));
363  else
364  {
365 
366 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
367  dbcrit("Delay too long, can't fit in the field!");
368 #endif /* DEBUG_DBPRINT */
369 
370  /* Turn off the RTC clock */
371  CMU_ClockEnable(cmuClock_RTC, false);
372 
373 // error(17);
374 
375  /* Exit function */
376  return;
377  }
378 
379 #endif /* ULFRCO/LFXO selection */
380 
381  /* Indicate that we're using the sleep method */
382  sleeping = true;
383 
384 
385  /* Start the RTC */
386  RTC_Enable(true);
387 
388  /* Enter EM2/3 depending on ULFRCO/LFXO selection */
389 
390 #if ULFRCO == 1 /* ULFRCO selected */
391  /* In EM3, high and low frequency clocks are disabled. No oscillator (except the ULFRCO) is running.
392  * Furthermore, all unwanted oscillators are disabled in EM3. This means that nothing needs to be
393  * manually disabled before the statement EMU_EnterEM3(true); */
394  EMU_EnterEM3(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
395 #else /* LFXO selected */
396  EMU_EnterEM2(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
397 #endif /* ULFRCO/LFXO selection */
398 
399  /* Indicate that we're no longer sleeping */
400  sleeping = false;
401 
402  /* Disable used oscillator and clocks after wake-up */
403 
404 #if ULFRCO == 1 /* ULFRCO selected */
405 
406  /* No specific code here */
407 
408 #else /* LFXO selected */
409 
410  /* Disable the low-frequency crystal oscillator for the RTC */
411  //CMU_OscillatorEnable(cmuOsc_LFXO, false, true);
412 
413 #endif /* ULFRCO/LFXO selection */
414 
415  /* Disable the clock to the interface of the low energy modules
416  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
417  //CMU_ClockEnable(cmuClock_HFLE, false);
418 
419  /* Turn off the RTC clock */
420  CMU_ClockEnable(cmuClock_RTC, false);
421  }
422 }
#define ULFRCOFREQ
Definition: delay.c:85
void dbinfoInt(char *message1, int32_t value, char *message2)
Print an info value surrounded by two strings (char array) to USARTx.
Definition: dbprint.c:569
static void initRTC(void)
RTC initialization.
Definition: delay.c:481
bool RTC_initialized
Definition: delay.c:102
void dbcrit(char *message)
Print a critical error string (char array) in red to USARTx and go to the next line.
Definition: dbprint.c:541
#define LFXOFREQ
Definition: delay.c:87
bool sleeping
Definition: delay.c:101