1 /* USER CODE BEGIN Header */
2 /**
3   ******************************************************************************
4   * @file    log_module.c
5   * @author  MCD Application Team
6   * @brief   Source file of the log module.
7   ******************************************************************************
8   * @attention
9   *
10   * Copyright (c) 2024 STMicroelectronics.
11   * All rights reserved.
12   *
13   * This software is licensed under terms that can be found in the LICENSE file
14   * in the root directory of this software component.
15   * If no LICENSE file comes with this software, it is provided AS-IS.
16   *
17   ******************************************************************************
18   */
19 /* USER CODE END Header */
20 
21 /* Includes ------------------------------------------------------------------*/
22 #include <stdio.h> /* vsnprintf */
23 
24 #include "log_module.h"
25 #include "stm32_adv_trace.h"
26 #include "utilities_conf.h"
27 
28 /* Private includes ----------------------------------------------------------*/
29 /* USER CODE BEGIN Includes */
30 
31 /* USER CODE END Includes */
32 
33 /* Private typedef -----------------------------------------------------------*/
34 /* USER CODE BEGIN PTD */
35 
36 /* USER CODE END PTD */
37 
38 /* Private define ------------------------------------------------------------*/
39 /* Definition of 'End Of Line' */
40 #define ENDOFLINE_SIZE          (0x01u)
41 #define ENDOFLINE_CHAR          '\n'
42 /* USER CODE BEGIN PD */
43 
44 /* USER CODE END PD */
45 
46 /* Private macro -------------------------------------------------------------*/
47 /* USER CODE BEGIN PM */
48 
49 /* USER CODE END PM */
50 
51 /* Exported constants --------------------------------------------------------*/
52 /* Global const struct variables to make the life of the user easier */
53 const Log_Module_t LOG_MODULE_DEFAULT_CONFIGURATION =
54 {
55   .verbose_level = LOG_VERBOSE_ERROR,
56   .region_mask = (LOG_REGION_ALL_REGIONS)
57 };
58 
59 const Log_Verbose_Level_t LOG_VERBOSE_DEFAULT = LOG_VERBOSE_ERROR;
60 const Log_Region_t LOG_REGION_MASK_DEFAULT = LOG_REGION_ALL_REGIONS;
61 const Log_Color_t LOG_COLOR_DEFAULT_CONFIGURATION[] =
62 {
63   LOG_COLOR_CODE_DEFAULT,   // For Region BLE
64   LOG_COLOR_CODE_DEFAULT,   // For Region System
65   LOG_COLOR_CODE_DEFAULT,   // For Region APP
66   LOG_COLOR_CODE_RED,       // For Region LinkLayer
67   LOG_COLOR_CODE_YELLOW,    // For Region MAC
68   LOG_COLOR_CODE_GREEN,     // For Region Zigbee
69   LOG_COLOR_CODE_GREEN,     // For Region Thread
70   LOG_COLOR_CODE_DEFAULT,   // For Region RTOS
71   /* USER CODE BEGIN LOG_COLOR_DEFAULT_CONFIGURATION */
72 
73   /* USER CODE END LOG_COLOR_DEFAULT_CONFIGURATION */
74 };
75 /* USER CODE BEGIN EC */
76 
77 /* USER CODE END EC */
78 
79 /* Private variables ---------------------------------------------------------*/
80 static uint32_t                 current_region_mask;
81 static Log_Verbose_Level_t      current_verbose_level;
82 static Log_Color_t              current_color_list[32];
83 CallBack_TimeStamp *            log_timestamp_function;
84 /* USER CODE BEGIN PV */
85 
86 /* USER CODE END PV */
87 
88 /* Private function prototypes -----------------------------------------------*/
89 static uint32_t Get_Region_Mask(Log_Region_t Region);
90 
91 #if (LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0)
92 static uint16_t RegionToColor(char * TextBuffer, uint16_t SizeMax, Log_Region_t Region);
93 #endif /* LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0  */
94 /* USER CODE BEGIN PFP */
95 
96 /* USER CODE END PFP */
97 
98 /* Functions Definition ------------------------------------------------------*/
99 #if (LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0)
100 /**
101  * @brief Add the color (in function of Region) on the start of Log sentence.
102  *
103  * @param TextBuffer    Pointer on the log buffer
104  * @param SizeMax       The maximum number of bytes that will be written to the buffer.
105  * @param Region        Region of the log to apply its corresponding color.
106  *
107  * @return Length of the new Log.
108  */
RegionToColor(char * TextBuffer,uint16_t SizeMax,Log_Region_t Region)109 static uint16_t RegionToColor(char * TextBuffer, uint16_t SizeMax, Log_Region_t Region)
110 {
111   uint16_t              text_length = 0;
112   Log_Color_t           color;
113   static Log_Color_t    previous_color = LOG_COLOR_NONE;
114 
115   if (Region != LOG_MODULE_ALL_REGION_MASK)
116   {
117     color = current_color_list[Region];
118   }
119   else
120   {
121     color = LOG_COLOR_CODE_DEFAULT;
122   }
123 
124   /* Insert Color code only if previous is not the same */
125   if (color != previous_color)
126   {
127     if (color == LOG_COLOR_CODE_DEFAULT)
128     {
129       snprintf(TextBuffer, SizeMax, "\x1b[0m");
130     }
131     else
132     {
133       snprintf(TextBuffer, SizeMax, "\x1b[0;%02dm", color);
134     }
135 
136     previous_color = color;
137     text_length = strlen(TextBuffer);
138   }
139 
140   return text_length;
141 }
142 #endif /* LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0  */
143 
Log_Module_PrintWithArg(Log_Verbose_Level_t VerboseLevel,Log_Region_t Region,const char * Text,va_list Args)144 void Log_Module_PrintWithArg(Log_Verbose_Level_t VerboseLevel, Log_Region_t Region, const char * Text, va_list Args)
145 {
146   uint16_t tmp_size = 0;
147   uint16_t buffer_size = 0;
148   char full_text[UTIL_ADV_TRACE_TMP_BUF_SIZE + 1u];
149 
150   /* USER CODE BEGIN Log_Module_PrintWithArg_1 */
151 
152   /* USER CODE END Log_Module_PrintWithArg_1 */
153 
154   /* If the verbose level of the given log is not enabled, then we do not print the log */
155   if (VerboseLevel > current_verbose_level)
156   {
157     return;
158   }
159 
160   /* If the region for the given log is not enabled, then we do not print the log */
161   if ((Get_Region_Mask(Region) & current_region_mask) == 0u)
162   {
163     return;
164   }
165 
166 #if (LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0)
167   /* Add to full_text the color matching the region */
168   tmp_size = RegionToColor(&full_text[buffer_size], (UTIL_ADV_TRACE_TMP_BUF_SIZE - buffer_size), Region);
169   buffer_size += tmp_size;
170 #endif /* LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0 */
171 
172 #if (LOG_INSERT_TIME_STAMP_INSIDE_THE_TRACE != 0)
173   if (log_timestamp_function != NULL)
174   {
175      tmp_size = UTIL_ADV_TRACE_TMP_BUF_SIZE - buffer_size;
176      log_timestamp_function(&full_text[buffer_size], tmp_size, &tmp_size);
177      buffer_size += tmp_size;
178   }
179 #endif /* LOG_INSERT_TIME_STAMP_INSIDE_THE_TRACE != 0 */
180 
181   /* Copy the data */
182   tmp_size = (uint16_t)vsnprintf(&full_text[buffer_size], (UTIL_ADV_TRACE_TMP_BUF_SIZE - buffer_size), Text, Args);
183   buffer_size += tmp_size;
184 
185   /* USER CODE BEGIN Log_Module_PrintWithArg_2 */
186 
187   /* USER CODE END Log_Module_PrintWithArg_2 */
188 
189 #if (LOG_INSERT_EOL_INSIDE_THE_TRACE != 0)
190   /* Add End Of Line if needed */
191   if (buffer_size > 1)
192   {
193     if ((full_text[buffer_size - 1] != ENDOFLINE_CHAR) && (full_text[buffer_size - 2] != ENDOFLINE_CHAR))
194     {
195       full_text[buffer_size++] = ENDOFLINE_CHAR;
196       full_text[buffer_size] = 0;
197     }
198   }
199 #endif /* LOG_INSERT_EOL_INSIDE_THE_TRACE != 0 */
200 
201   /* USER CODE BEGIN Log_Module_PrintWithArg_3 */
202 
203   /* USER CODE END Log_Module_PrintWithArg_3 */
204 
205   /* Send full_text to ADV Traces */
206   UTIL_ADV_TRACE_Send((const uint8_t *)full_text, buffer_size);
207 }
208 
Log_Module_Print(Log_Verbose_Level_t VerboseLevel,Log_Region_t Region,const char * Text,...)209 void Log_Module_Print(Log_Verbose_Level_t VerboseLevel, Log_Region_t Region, const char * Text, ...)
210 {
211 #if (CFG_LOG_SUPPORTED != 0)
212   va_list variadic_args;
213 
214   va_start(variadic_args, Text);
215   Log_Module_PrintWithArg(VerboseLevel, Region, Text, variadic_args);
216   va_end(variadic_args);
217 #else /* (CFG_LOG_SUPPORTED != 0) */
218   UNUSED(VerboseLevel);
219   UNUSED(Region);
220   UNUSED(Text);
221 #endif /* (CFG_LOG_SUPPORTED != 0)  */
222 }
223 
Log_Module_Init(Log_Module_t LogConfiguration)224 void Log_Module_Init(Log_Module_t LogConfiguration)
225 {
226   UTIL_ADV_TRACE_Init();
227 
228   memcpy(&current_color_list, &LOG_COLOR_DEFAULT_CONFIGURATION, sizeof(LOG_COLOR_DEFAULT_CONFIGURATION));
229   Log_Module_Set_Verbose_Level(LogConfiguration.verbose_level);
230   Log_Module_Set_Multiple_Regions(LogConfiguration.region_mask);
231   log_timestamp_function = NULL;
232 }
233 
Log_Module_DeInit(void)234 void Log_Module_DeInit(void)
235 {
236   UTIL_ADV_TRACE_DeInit();
237 }
238 
Log_Module_Set_Verbose_Level(Log_Verbose_Level_t NewVerboseLevel)239 void Log_Module_Set_Verbose_Level(Log_Verbose_Level_t NewVerboseLevel)
240 {
241   current_verbose_level = NewVerboseLevel;
242 }
243 
Log_Module_Set_Region(Log_Region_t NewRegion)244 void Log_Module_Set_Region(Log_Region_t NewRegion)
245 {
246   current_region_mask = Get_Region_Mask(NewRegion);
247 }
248 
Log_Module_Add_Region(Log_Region_t NewRegion)249 void Log_Module_Add_Region(Log_Region_t NewRegion)
250 {
251   current_region_mask |= Get_Region_Mask(NewRegion);
252 }
253 
Log_Module_Remove_Region(Log_Region_t Region)254 void Log_Module_Remove_Region(Log_Region_t Region)
255 {
256   current_region_mask &= ~Get_Region_Mask(Region);
257 }
258 
Log_Module_Enable_All_Regions(void)259 void Log_Module_Enable_All_Regions(void)
260 {
261   Log_Module_Set_Region(LOG_REGION_ALL_REGIONS);
262 }
263 
Get_Region_Mask(Log_Region_t Region)264 static uint32_t Get_Region_Mask(Log_Region_t Region)
265 {
266   if (Region == LOG_REGION_ALL_REGIONS)
267   {
268     /* Return the full mask */
269     return ((uint32_t)LOG_MODULE_ALL_REGION_MASK);
270   }
271   else
272   {
273     /* Return the bit matching the region */
274     return ((uint32_t)(1U << ((uint32_t)Region)));
275   }
276 }
277 
Log_Module_Set_Multiple_Regions(uint32_t NewRegionMask)278 void Log_Module_Set_Multiple_Regions(uint32_t NewRegionMask)
279 {
280   current_region_mask = NewRegionMask;
281 }
282 
Log_Module_Set_Color(Log_Region_t Region,Log_Color_t Color)283 void Log_Module_Set_Color(Log_Region_t Region, Log_Color_t Color)
284 {
285   if ( Region != LOG_MODULE_ALL_REGION_MASK )
286   {
287     current_color_list[Region] = Color;
288   }
289 }
290 
Log_Module_RegisterTimeStampFunction(CallBack_TimeStamp * TimeStampFunction)291 void Log_Module_RegisterTimeStampFunction(CallBack_TimeStamp * TimeStampFunction)
292 {
293   log_timestamp_function = TimeStampFunction;
294 }
295 
296 /* USER CODE BEGIN 0 */
297 
298 /* USER CODE END 0 */
299