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>© 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