xref: /btstack/port/stm32-wb55xx-nucleo-freertos/Middlewares/STM32_WPAN/utilities/dbg_trace.c (revision 0561b2d8d5dba972c7daa57d5e677f7a1327edfd)
1 /**
2   ******************************************************************************
3   * @file    dbg_trace.c
4   * @author  MCD Application Team
5   * @brief   This file contains the Interface with BLE Drivers functions.
6   ******************************************************************************
7    * @attention
8   *
9   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
10   * All rights reserved.</center></h2>
11   *
12   * This software component is licensed by ST under BSD 3-Clause license,
13   * the "License"; You may not use this file except in compliance with the
14   * License. You may obtain a copy of the License at:
15   *                        opensource.org/licenses/BSD-3-Clause
16   *
17   ******************************************************************************
18  */
19 
20 
21 /* Includes ------------------------------------------------------------------*/
22 #include "utilities_common.h"
23 #include "stm_queue.h"
24 #include "dbg_trace.h"
25 
26 /* Definition of the function */
27 #if !defined(__GNUC__)  /* SW4STM32 */
28 size_t __write(int handle, const unsigned char * buf, size_t bufSize);
29 #endif
30 
31 /** @addtogroup TRACE
32  * @{
33  */
34 
35 
36 /** @defgroup TRACE_LOG
37  * @brief TRACE Logging functions
38  * @{
39  */
40 
41 /* Private typedef -----------------------------------------------------------*/
42 /** @defgroup TRACE Log private typedef
43  * @{
44  */
45 
46 /**
47  * @}
48  */
49 
50 /* Private defines -----------------------------------------------------------*/
51 /** @defgroup TRACE Log private defines
52  * @{
53  */
54 
55 /**
56  * @}
57  */
58 
59 /* Private macros ------------------------------------------------------------*/
60 /** @defgroup TRACE Log private macros
61  * @{
62  */
63 /**
64  * @}
65  */
66 
67 /* Private variables ---------------------------------------------------------*/
68 /** @defgroup TRACE Log private variables
69  * @{
70  */
71 #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 ))
72 #if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0)
73 static queue_t MsgDbgTraceQueue;
74 static uint8_t MsgDbgTraceQueueBuff[DBG_TRACE_MSG_QUEUE_SIZE];
75 #endif
76 __IO ITStatus DbgTracePeripheralReady = SET;
77 #endif
78 /**
79  * @}
80  */
81 
82 /* Global variables ----------------------------------------------------------*/
83 /** @defgroup TRACE Log Global variable
84  * @{
85  */
86 /**
87  * @}
88  */
89 
90 /* Private function prototypes -----------------------------------------------*/
91 /** @defgroup TRACE Log private function prototypes
92  * @{
93  */
94 #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 ))
95 static void DbgTrace_TxCpltCallback(void);
96 #endif
97 
98 
99 /**
100  * @}
101  */
102 
103 
104 /* Private Functions Definition ------------------------------------------------------*/
105 /** @defgroup TRACE Log Private function
106  * @{
107  */
108 
109 
110 /* Functions Definition ------------------------------------------------------*/
111 /** @defgroup TRACE Log APIs
112  * @{
113  */
114 
115 /**
116  * @brief  DbgTraceGetFileName: Return filename string extracted from full path information
117  * @param  *fullPath Fullpath string (path + filename)
118  * @retval char* Pointer on filename string
119  */
120 
DbgTraceGetFileName(const char * fullpath)121 const char *DbgTraceGetFileName(const char *fullpath)
122 {
123   const char *ret = fullpath;
124 
125   if (strrchr(fullpath, '\\') != NULL)
126   {
127     ret = strrchr(fullpath, '\\') + 1;
128   }
129   else if (strrchr(fullpath, '/') != NULL)
130   {
131     ret = strrchr(fullpath, '/') + 1;
132   }
133 
134   return ret;
135 }
136 
137 /**
138  * @brief  DbgTraceBuffer: Output buffer content information to output Stream
139  * @param  *pBuffer  Pointer on buffer to be output
140  * @param  u32Length buffer Size
141  * @paramt strFormat string as expected by "printf" function. Used to desrcibe buffer content information.
142  * @param  ...       Paremeters to be "formatted" in strFormat string (if any)
143  * @retval None
144  */
145 
DbgTraceBuffer(const void * pBuffer,uint32_t u32Length,const char * strFormat,...)146 void DbgTraceBuffer(const void *pBuffer, uint32_t u32Length, const char *strFormat, ...)
147 {
148   va_list vaArgs;
149   uint32_t u32Index;
150   va_start(vaArgs, strFormat);
151   vprintf(strFormat, vaArgs);
152   va_end(vaArgs);
153   for (u32Index = 0; u32Index < u32Length; u32Index ++)
154   {
155     printf(" %02X", ((const uint8_t *) pBuffer)[u32Index]);
156   }
157 }
158 
159 #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 ))
160 /**
161  * @brief  DBG_TRACE USART Tx Transfer completed callback
162  * @param  UartHandle: UART handle.
163  * @note   Indicate the end of the transmission of a DBG_TRACE trace buffer to DBG_TRACE USART. If queue
164  *         contains new trace data to transmit, start a new transmission.
165  * @retval None
166  */
DbgTrace_TxCpltCallback(void)167 static void DbgTrace_TxCpltCallback(void)
168 {
169 #if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0)
170   uint8_t* buf;
171   uint16_t bufSize;
172 
173   BACKUP_PRIMASK();
174 
175   DISABLE_IRQ();			/**< Disable all interrupts by setting PRIMASK bit on Cortex*/
176   /* Remove element just sent to UART */
177   CircularQueue_Remove(&MsgDbgTraceQueue,&bufSize);
178 
179   /* Sense if new data to be sent */
180   buf=CircularQueue_Sense(&MsgDbgTraceQueue,&bufSize);
181 
182 
183   if ( buf != NULL)
184   {
185     RESTORE_PRIMASK();
186     DbgOutputTraces((uint8_t*)buf, bufSize, DbgTrace_TxCpltCallback);
187   }
188   else
189   {
190     DbgTracePeripheralReady = SET;
191     RESTORE_PRIMASK();
192   }
193 
194 #else
195   BACKUP_PRIMASK();
196 
197   DISABLE_IRQ();      /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
198 
199   DbgTracePeripheralReady = SET;
200 
201   RESTORE_PRIMASK();
202 #endif
203 }
204 #endif
205 
DbgTraceInit(void)206 void DbgTraceInit( void )
207 {
208 #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 ))
209   DbgOutputInit();
210 #if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0)
211   CircularQueue_Init(&MsgDbgTraceQueue, MsgDbgTraceQueueBuff, DBG_TRACE_MSG_QUEUE_SIZE, 0, CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG);
212 #endif
213 #endif
214   return;
215 }
216 
217 
218 #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 ))
219 #if defined(__GNUC__)  /* SW4STM32 (GCC) */
220 /**
221  * @brief	_write: override the __write standard lib function to redirect printf to USART.
222  * @param	handle output handle (STDIO, STDERR...)
223  * @param	buf buffer to write
224  * @param	bufsize buffer size
225  * @param	...: arguments to be formatted in format string
226  * @retval none
227  */
_write(int handle,const unsigned char * buf,size_t bufSize)228 size_t _write(int handle, const unsigned char * buf, size_t bufSize)
229 {
230   return ( DbgTraceWrite(handle, buf, bufSize) );
231 }
232 
233 #else
234 /**
235  * @brief __write: override the _write standard lib function to redirect printf to USART.
236  * @param handle output handle (STDIO, STDERR...)
237  * @param buf buffer to write
238  * @param bufsize buffer size
239  * @param ...: arguments to be formatted in format string
240  * @retval none
241  */
__write(int handle,const unsigned char * buf,size_t bufSize)242 size_t __write(int handle, const unsigned char * buf, size_t bufSize)
243 {
244   return ( DbgTraceWrite(handle, buf, bufSize) );
245 }
246 #endif /* #if defined(__GNUC__)  */
247 
248 /**
249  * @brief Override the standard lib function to redirect printf to USART.
250  * @param handle output handle (STDIO, STDERR...)
251  * @param buf buffer to write
252  * @param bufsize buffer size
253  * @retval Number of elements written
254  */
DbgTraceWrite(int handle,const unsigned char * buf,size_t bufSize)255 size_t DbgTraceWrite(int handle, const unsigned char * buf, size_t bufSize)
256 {
257   size_t chars_written = 0;
258   uint8_t* buffer;
259 
260   BACKUP_PRIMASK();
261 
262   /* Ignore flushes */
263   if ( handle == -1 )
264   {
265     chars_written = ( size_t ) 0;
266   }
267   /* Only allow stdout/stderr output */
268   else if ( ( handle != 1 ) && ( handle != 2 ) )
269   {
270     chars_written = ( size_t ) - 1;
271   }
272   /* Parameters OK, call the low-level character output routine */
273   else if (bufSize != 0)
274   {
275     chars_written = bufSize;
276     /* If queue emepty and TX free, send directly */
277     /* CS Start */
278 
279 #if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0)
280     DISABLE_IRQ();      /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
281     buffer=CircularQueue_Add(&MsgDbgTraceQueue,(uint8_t*)buf, bufSize,1);
282     if (buffer && DbgTracePeripheralReady)
283     {
284       DbgTracePeripheralReady = RESET;
285       RESTORE_PRIMASK();
286       DbgOutputTraces((uint8_t*)buffer, bufSize, DbgTrace_TxCpltCallback);
287     }
288     else
289     {
290       RESTORE_PRIMASK();
291     }
292 #else
293     DISABLE_IRQ();      /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
294     DbgTracePeripheralReady = RESET;
295     RESTORE_PRIMASK();
296 
297     DbgOutputTraces((uint8_t*)buf, bufSize, DbgTrace_TxCpltCallback);
298     while (!DbgTracePeripheralReady);
299 #endif
300     /* CS END */
301   }
302   return ( chars_written );
303 }
304 
305 #if   defined ( __CC_ARM )     /* Keil */
306 
307 /* For KEIL re-implement our own version of fputc */
fputc(int ch,FILE * f)308 int fputc(int ch, FILE *f)
309 {
310   /* temp char avoids endianness issue */
311   char tempch = ch;
312   /* Write one character to Debug Circular Queue */
313   DbgTraceWrite(1U, (const unsigned char *) &tempch, 1);
314   return ch;
315 }
316 
317 #endif /* #if   defined ( __CC_ARM )  */
318 
319 #endif /* #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 )) */
320 
321 /**
322  * @}
323  */
324 
325 /**
326  * @}
327  */
328 
329 /**
330  * @}
331  */
332 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
333