Embedded System Design 2 - Project
delay.h File Reference

Delay functionality. More...

#include <stdint.h>

Go to the source code of this file.

Macros

#define SYSTICKDELAY   0
 
#define ULFRCO   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.2
Author
Brecht Van Eeckhoudt

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

Macro Definition Documentation

◆ SYSTICKDELAY

#define SYSTICKDELAY   0

Public definition to select which delay to use

  • 1 - Use SysTick delays.
  • 0 - Use EM2/3 RTC compare delays.

Definition at line 48 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 55 of file delay.h.

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 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  /* Enable SysTick interrupt and counter by setting their bits. */
145  SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
146  }
147 
148  /* Wait a certain amount of ticks */
149  uint32_t curTicks = msTicks;
150  while ((msTicks - curTicks) < msDelay);
151 
152  /* Disable SysTick interrupt and counter (needs to be done before entering EM2/3) by clearing their bits. */
153  SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk & ~SysTick_CTRL_ENABLE_Msk;
154 
155 #else /* EM2/3 RTC delay selected */
156 
157 
158  /* Initialize RTC if not already the case */
159  if (!RTC_initialized) initRTC();
160  else
161  {
162  /* Enable necessary oscillator and clocks */
163 
164 #if ULFRCO == 1 /* ULFRCO selected */
165 
166  /* No specific code here */
167 
168 #else /* LFXO selected */
169 
170  /* Enable the low-frequency crystal oscillator for the RTC */
171  //CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
172 
173 #endif /* ULFRCO/LFXO selection */
174 
175  /* Enable the clock to the interface of the low energy modules
176  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
177  //CMU_ClockEnable(cmuClock_HFLE, true);
178 
179  /* Turn on the RTC clock */
180  CMU_ClockEnable(cmuClock_RTC, true);
181  }
182 
183  /* Set RTC compare value for RTC compare register 0 depending on ULFRCO/LFXO selection */
184 
185 #if ULFRCO == 1 /* ULFRCO selected */
186 
187  if ((ULFRCOFREQ_MS * msDelay) <= 0x00ffffff) RTC_CompareSet(0, (ULFRCOFREQ_MS * msDelay));
188  else
189  {
190 
191 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
192  dbcrit("Delay too long, can't fit in the field!");
193 #endif /* DEBUG_DBPRINT */
194 
195  /* Turn off the RTC clock */
196  CMU_ClockEnable(cmuClock_RTC, false);
197 
198  error(14);
199 
200  /* Exit function */
201  return;
202  }
203 
204 #else /* LFXO selected */
205 
206  if ((LFXOFREQ_MS * msDelay) <= 0x00ffffff) RTC_CompareSet(0, (LFXOFREQ_MS * msDelay));
207  else
208  {
209 
210 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
211  dbcrit("Delay too long, can't fit in the field!");
212 #endif /* DEBUG_DBPRINT */
213 
214  /* Turn off the RTC clock */
215  CMU_ClockEnable(cmuClock_RTC, false);
216 
217  error(15);
218 
219  /* Exit function */
220  return;
221  }
222 
223 #endif /* ULFRCO/LFXO selection */
224 
225 
226  /* Start the RTC */
227  RTC_Enable(true);
228 
229  /* Enter EM2/3 depending on ULFRCO/LFXO selection */
230 
231 #if ULFRCO == 1 /* ULFRCO selected */
232  /* In EM3, high and low frequency clocks are disabled. No oscillator (except the ULFRCO) is running.
233  * Furthermore, all unwanted oscillators are disabled in EM3. This means that nothing needs to be
234  * manually disabled before the statement EMU_EnterEM3(true); */
235  EMU_EnterEM3(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
236 #else /* LFXO selected */
237  EMU_EnterEM2(true); /* "true" - Save and restore oscillators, clocks and voltage scaling */
238 #endif /* ULFRCO/LFXO selection */
239 
240 
241  /* Disable used oscillator and clocks after wake-up */
242 
243 #if ULFRCO == 1 /* ULFRCO selected */
244 
245  /* No specific code here */
246 
247 #else /* LFXO selected */
248 
249  /* Disable the low-frequency crystal oscillator for the RTC */
250  //CMU_OscillatorEnable(cmuOsc_LFXO, false, true);
251 
252 #endif /* ULFRCO/LFXO selection */
253 
254  /* Disable the clock to the interface of the low energy modules
255  * cmuClock_CORELE = cmuClock_HFLE (deprecated) */
256  //CMU_ClockEnable(cmuClock_HFLE, false);
257 
258  /* Turn off the RTC clock */
259  CMU_ClockEnable(cmuClock_RTC, false);
260 
261 #endif /* SysTick/RTC selection */
262 
263 }
static void initRTC(void)
RTC initialization.
Definition: delay.c:453
bool RTC_initialized
Definition: delay.c:103
void dbinfo(char *message)
Print an info string (char array) to USARTx and go to the next line.
Definition: dbprint.c:503
void error(uint8_t number)
Error method.
Definition: util.c:131
#define LFXOFREQ_MS
Definition: delay.c:89
#define ULFRCOFREQ_MS
Definition: delay.c:87
void dbcrit(char *message)
Print a critical error string (char array) in red to USARTx and go to the next line.
Definition: dbprint.c:539

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

405 {
406  return (RTC_sleep_wakeup);
407 }
static volatile bool RTC_sleep_wakeup
Definition: delay.c:95

◆ RTC_clearWakeup()

void RTC_clearWakeup ( void  )

Method to clear RTC_sleep_wakeup.

Definition at line 414 of file delay.c.

415 {
416  RTC_sleep_wakeup = false;
417 }
static volatile bool RTC_sleep_wakeup
Definition: delay.c:95

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

429 {
430  uint32_t sSleep = RTC_CounterGet();
431 
432  /* Disable the counter */
433  RTC_Enable(false);
434 
435 #if ULFRCO == 1 /* ULFRCO selected */
436  sSleep /= ULFRCOFREQ;
437 #else /* LFXO selected */
438  sSleep /= LFXOFREQ;
439 #endif /* ULFRCO/LFXO selection */
440 
441  return (sSleep);
442 }
#define ULFRCOFREQ
Definition: delay.c:86
#define LFXOFREQ
Definition: delay.c:88

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

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