Embedded System Design 2 - Project
util.c
Go to the documentation of this file.
1 /***************************************************************************//**
2  * @file util.c
3  * @brief Utility functionality.
4  * @version 3.1
5  * @author Brecht Van Eeckhoudt
6  *
7  * ******************************************************************************
8  *
9  * @section Versions
10  *
11  * @li v1.0: Started with the code from https://github.com/Fescron/Project-LabEmbeddedDesign1/tree/master/code/SLSTK3400A_ADXL362
12  * @li v1.1: Changed PinModeSet DOUT value to 0 in initLED.
13  * @li v1.2: Removed unnecessary `GPIO_PinOutClear` line in initLED.
14  * @li v1.3: Moved initRTCcomp method from `main.c` to here, added delay functionality which goes into EM1 or EM2.
15  * @li v1.4: Moved delay functionality to specific header and source files.
16  * @li v2.0: Changed `Error()` to `error()`, added a global variable to keep the error number and initialize the pin of the LED automatically.
17  * @li v2.1: Changed initLED to be a static (~hidden) method and also made the global variables static.
18  * @li v2.2: Added peripheral clock enable/disable functionality for energy saving purposes, only added necessary includes in header file,
19  * moved the others to the source file, updated documentation, replaced SysTick delay with RTCC delay, changed error delay length.
20  * @li v2.3: Changed name of static variable, simplified some logic.
21  * @li v2.4: Stopped disabling the GPIO clock.
22  * @li v2.5: Moved documentation.
23  * @li v2.6: Updated code with new DEFINE checks.
24  * @li v2.7: Added functionality to send error values using LoRaWAN.
25  * @li v2.8: Added the ability to enable/disable error forwarding to the cloud using a public definition and changed UART error color.
26  * @li v3.0: Updated version number.
27  * @li v3.1: Removed `static` before the local variables (not necessary).
28  *
29  * ******************************************************************************
30  *
31  * @todo
32  * **Future improvements:**@n
33  * - Only send a maximum amount of errors to the could using LoRaWAN according to a defined value.
34  * - Reset the counter in the MEASURE/SEND state?
35  * - Go back to INIT state on an error call?
36  * - `GOTO` is supported in C but is dangerous to use (nested loops, ...)
37  * - Check if the clock functionality doesn't break when this is implemented ...
38  *
39  * ******************************************************************************
40  *
41  * @section License
42  *
43  * **Copyright (C) 2019 - Brecht Van Eeckhoudt**
44  *
45  * This program is free software: you can redistribute it and/or modify
46  * it under the terms of the **GNU General Public License** as published by
47  * the Free Software Foundation, either **version 3** of the License, or
48  * (at your option) any later version.
49  *
50  * This program is distributed in the hope that it will be useful,
51  * but WITHOUT ANY WARRANTY; without even the implied warranty of
52  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53  * GNU General Public License for more details.
54  *
55  * *A copy of the GNU General Public License can be found in the `LICENSE`
56  * file along with this source code.*
57  *
58  * @n
59  *
60  * Some methods use code obtained from examples from [Silicon Labs' GitHub](https://github.com/SiliconLabs/peripheral_examples).
61  * These sections are licensed under the Silabs License Agreement. See the file
62  * "Silabs_License_Agreement.txt" for details. Before using this software for
63  * any purpose, you must agree to the terms of that agreement.
64  *
65  ******************************************************************************/
66 
67 
68 #include <stdint.h> /* (u)intXX_t */
69 #include <stdbool.h> /* "bool", "true", "false" */
70 #include "em_cmu.h" /* Clock Management Unit */
71 #include "em_gpio.h" /* General Purpose IO */
72 
73 #include "util.h" /* Corresponding header file */
74 #include "pin_mapping.h" /* PORT and PIN definitions */
75 #include "debug_dbprint.h" /* Enable or disable printing to UART */
76 #include "delay.h" /* Delay functionality */
77 
78 #if ERROR_FORWARDING == 1 /* ERROR_FORWARDING */
79 #include "lora_wrappers.h" /* LoRaWAN functionality */
80 #endif /* ERROR_FORWARDING */
81 
82 
83 /* Local variables */
84 uint8_t errorNumber = 0;
85 bool LED_initialized = false;
86 
87 
88 /* Local prototype */
89 static void initLED (void);
90 
91 
92 /**************************************************************************//**
93  * @brief
94  * Enable or disable the LED.
95  *
96  * @details
97  * This method also initializes the pin-mode if necessary.
98  *
99  * @param[in] enabled
100  * @li `true` - Enable LED.
101  * @li `false` - Disable LED.
102  *****************************************************************************/
103 void led (bool enabled)
104 {
105  /* Initialize LED if not already the case */
106  if (!LED_initialized) initLED();
107 
108  /* Set the selected state */
109  if (enabled) GPIO_PinOutSet(LED_PORT, LED_PIN);
110  else GPIO_PinOutClear(LED_PORT, LED_PIN);
111 }
112 
113 
114 /**************************************************************************//**
115  * @brief
116  * Error method.
117  *
118  * @details
119  * **ERROR_FORWARDING == 0**@n
120  * The method flashes the LED, displays a UART message and holds the MCU
121  * forever in a loop until it gets reset. The error value gets stored in
122  * a global variable.
123  *
124  * **ERROR_FORWARDING == 1**@n
125  * The method sends the error value to the cloud using LoRaWAN if the error
126  * number doesn't correspond to LoRaWAN-related functionality (numbers 30 - 55).
127  *
128  * @param[in] number
129  * The number to indicate where in the code the error was thrown.
130  *****************************************************************************/
131 void error (uint8_t number)
132 {
133  /* Initialize LED if not already the case */
134  if (!LED_initialized) initLED();
135 
136  /* Save the given number in the global variable */
137  errorNumber = number;
138 
139 #if ERROR_FORWARDING == 0 /* ERROR_FORWARDING */
140 
141 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
142  dbprint_color(">>> Error (", 5);
143  dbprintInt(number);
144  dbprintln_color(")! Please reset MCU. <<<", 5);
145 #endif /* DEBUG_DBPRINT */
146 
147  while (1)
148  {
149  delay(100);
150  GPIO_PinOutToggle(LED_PORT, LED_PIN); /* Toggle LED */
151  }
152 
153 #else /* ERROR_FORWARDING */
154 
155  /* Check if the error number isn't called in LoRaWAN functionality */
156  if ((number < 30) || (number > 55))
157  {
158 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
159  dbprint_color(">>> Error (", 5);
160  dbprintInt(number);
161  dbprintln_color(")! Sending the message to the cloud. <<<", 5);
162 #endif /* DEBUG_DBPRINT */
163 
164  initLoRaWAN(); /* Initialize LoRaWAN functionality */
165 
166  sendStatus(number); /* Send the status value */
167 
168  disableLoRaWAN(); /* Disable RN2483 */
169  }
170  else
171  {
172 
173 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
174  dbprint_color(">>> Error in LoRaWAN functionality (", 5);
175  dbprintInt(number);
176  dbprintln_color(")! <<<", 5);
177 #endif /* DEBUG_DBPRINT */
178 
179  }
180 
181 #endif /* ERROR_FORWARDING */
182 
183 }
184 
185 
186 /**************************************************************************//**
187  * @brief
188  * Initialize the LED.
189  *
190  * @note
191  * This is a static method because it's only internally used in this file
192  * and called by other methods if necessary.
193  *****************************************************************************/
194 static void initLED (void)
195 {
196  /* Enable necessary clocks (just in case) */
197  CMU_ClockEnable(cmuClock_HFPER, true); /* GPIO is a High Frequency Peripheral */
198  CMU_ClockEnable(cmuClock_GPIO, true);
199 
200  /* In the case of gpioModePushPull, the last argument directly sets the pin state */
201  GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0);
202 
203 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
204  dbinfo("LED pin initialized");
205 #endif /* DEBUG_DBPRINT */
206 
207  LED_initialized = true;
208 }
void error(uint8_t number)
Error method.
Definition: util.c:131
void dbinfo(char *message)
Print an info string (char array) to USARTx and go to the next line.
Definition: dbprint.c:503
Utility functionality.
void disableLoRaWAN(void)
Disable LoRaWAN functionality.
The pin definitions for the regular and custom Happy Gecko board.
Delay functionality.
void initLoRaWAN(void)
Initialize LoRaWAN functionality.
Definition: lora_wrappers.c:92
#define LED_PORT
Definition: pin_mapping.h:85
void sendStatus(uint8_t status)
Send a packet to indicate a status.
bool LED_initialized
Definition: util.c:85
LoRa wrapper methods.
Enable or disable printing to UART with dbprint.
void delay(uint32_t msDelay)
Wait for a certain amount of milliseconds in EM2/3.
Definition: delay.c:124
#define LED_PIN
Definition: pin_mapping.h:86
void dbprintInt(int32_t value)
Print a number in decimal notation to USARTx.
Definition: dbprint.c:738
void led(bool enabled)
Enable or disable the LED.
Definition: util.c:103
void dbprintln_color(char *message, dbprint_color_t color)
Print a string (char array) to USARTx in a given color and go to the next line.
Definition: dbprint.c:480
uint8_t errorNumber
Definition: util.c:84
static void initLED(void)
Initialize the LED.
Definition: util.c:194
void dbprint_color(char *message, dbprint_color_t color)
Print a string (char array) to USARTx in a given color.
Definition: dbprint.c:421