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