aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/os/hal/src/usbh/hal_usbh_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/os/hal/src/usbh/hal_usbh_debug.c')
-rw-r--r--lib/chibios-contrib/os/hal/src/usbh/hal_usbh_debug.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/lib/chibios-contrib/os/hal/src/usbh/hal_usbh_debug.c b/lib/chibios-contrib/os/hal/src/usbh/hal_usbh_debug.c
new file mode 100644
index 000000000..225489df8
--- /dev/null
+++ b/lib/chibios-contrib/os/hal/src/usbh/hal_usbh_debug.c
@@ -0,0 +1,219 @@
1/*
2 ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
3 Copyright (C) 2015..2019 Diego Ismirlian, (dismirlian(at)google's mail)
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16*/
17
18#include "hal.h"
19
20#if HAL_USE_USBH && USBH_DEBUG_ENABLE
21
22#include "ch.h"
23#include "usbh/debug.h"
24#include "chprintf.h"
25#include <stdarg.h>
26
27#define TEMP_BUFF_LEN 255
28
29/* ************************ */
30/* Circular queue structure */
31/* ************************ */
32static int dq_append_string(usbh_dq_t *q, const uint8_t *s, int len) {
33 if (len <= 0) return 0;
34 if (len > TEMP_BUFF_LEN) len = TEMP_BUFF_LEN;
35 if (q->rem < len + 1) return -1;
36 q->rem -= len + 1;
37
38 uint8_t *d = q->next;
39 *d++ = len;
40 if (d == q->end) d = q->start;
41 while (len--) {
42 *d++ = *s++;
43 if (d == q->end) d = q->start;
44 }
45 q->next = d;
46 return 0;
47}
48
49static void dq_remove_oldest_string(usbh_dq_t *q) {
50 int len = *q->first;
51 if (len) {
52 ++len;
53 q->rem += len;
54 q->first += len;
55 if (q->first >= q->end) {
56 q->first -= q->sz;
57 }
58 if (q->rem == q->sz) {
59 *q->first = 0;
60 }
61 }
62}
63
64static int dq_read_oldest_string(usbh_dq_t *q, uint8_t *d) {
65 uint8_t *s = q->first;
66 int len;
67 int sz;
68 len = sz = *s++;
69 while (len--) {
70 *d++ = *s++;
71 if (d == q->end) d = q->start;
72 }
73 *d = 0;
74 return sz;
75}
76
77static void dq_init(usbh_dq_t *q, uint8_t *buff, int len) {
78 q->start = q->first = q->next = buff;
79 q->end = q->start + len;
80 q->sz = q->rem = len;
81 *buff = 0;
82}
83
84
85static uint8_t buff[TEMP_BUFF_LEN + 1];
86
87static inline syssts_t _dbg_prologue(struct usbh_debug_helper *debug,
88 uint32_t hfnum, uint16_t hfir, const char *s, int *len) {
89 syssts_t sts = chSysGetStatusAndLockX();
90
91 debug->last = osalOsGetSystemTimeX();
92 if (debug->ena) {
93 debug->first = debug->last;
94 }
95
96 if (((hfnum & 0x3fff) == 0x3fff) && (hfir == (hfnum >> 16))) {
97 *len = chsnprintf((char *)buff, sizeof(buff), "+%08d ", debug->last - debug->first);
98 debug->ena = FALSE;
99 } else {
100 uint32_t f = hfnum & 0xffff;
101 uint32_t p = 1000 - ((hfnum >> 16) / (hfir / 1000));
102 *len = chsnprintf((char *)buff, sizeof(buff), "%05d.%03d %s", f, p, s);
103 debug->ena = TRUE;
104 }
105
106 return sts;
107}
108
109static inline void dbg_epilogue(struct usbh_debug_helper *debug,
110 syssts_t sts, int len) {
111
112 while (dq_append_string(&debug->dq, buff, len) < 0) {
113 dq_remove_oldest_string(&debug->dq);
114 }
115
116 if (debug->on) {
117 chThdResumeI(&debug->tr, MSG_OK);
118 }
119
120 chSysRestoreStatusX(sts);
121}
122
123#if USBH_DEBUG_MULTI_HOST
124void usbDbgPrintf(USBHDriver *host, const char *fmt, ...) {
125 if (!host) return;
126 struct usbh_debug_helper *const debug = &host->debug;
127 uint32_t hfnum = host->otg->HFNUM;
128 uint16_t hfir = host->otg->HFIR;
129#else
130void usbDbgPrintf(const char *fmt, ...) {
131 struct usbh_debug_helper *const debug = &usbh_debug;
132 uint32_t hfnum = USBH_DEBUG_SINGLE_HOST_SELECTION.otg->HFNUM;
133 uint16_t hfir = USBH_DEBUG_SINGLE_HOST_SELECTION.otg->HFIR;
134#endif
135 int len;
136
137 syssts_t sts = _dbg_prologue(debug, hfnum, hfir, "", &len);
138
139 va_list ap;
140 va_start(ap, fmt);
141 len += chvsnprintf((char *)buff + len, sizeof(buff) - len, fmt, ap);
142 va_end(ap);
143
144 dbg_epilogue(debug, sts, len);
145}
146
147#if USBH_DEBUG_MULTI_HOST
148void usbDbgPuts(USBHDriver *host, const char *s) {
149 if (!host) return;
150 struct usbh_debug_helper *const debug = &host->debug;
151 uint32_t hfnum = host->otg->HFNUM;
152 uint16_t hfir = host->otg->HFIR;
153#else
154void usbDbgPuts(const char *s) {
155 struct usbh_debug_helper *const debug = &usbh_debug;
156 uint32_t hfnum = USBH_DEBUG_SINGLE_HOST_SELECTION.otg->HFNUM;
157 uint16_t hfir = USBH_DEBUG_SINGLE_HOST_SELECTION.otg->HFIR;
158#endif
159 int len;
160 syssts_t sts = _dbg_prologue(debug, hfnum, hfir, s, &len);
161 dbg_epilogue(debug, sts, len);
162}
163
164#if USBH_DEBUG_MULTI_HOST
165void usbDbgEnable(USBHDriver *host, bool enable) {
166 struct usbh_debug_helper *const debug = &host->debug;
167#else
168void usbDbgEnable(bool enable) {
169 struct usbh_debug_helper *const debug = &usbh_debug;
170#endif
171 debug->on = enable;
172}
173
174static void usb_debug_thread(void *arg) {
175#if USBH_DEBUG_MULTI_HOST
176 USBHDriver *const host = (USBHDriver *)arg;
177 struct usbh_debug_helper *const debug = &host->debug;
178#else
179 (void)arg;
180 struct usbh_debug_helper *const debug = &usbh_debug;
181#endif
182
183 uint8_t rdbuff[TEMP_BUFF_LEN + 1];
184
185 chRegSetThreadName("USBH_DBG");
186 while (true) {
187 chSysLock();
188 int len = dq_read_oldest_string(&debug->dq, rdbuff);
189 if (!len) {
190 chThdSuspendS(&debug->tr);
191 chSysUnlock();
192 } else {
193 dq_remove_oldest_string(&debug->dq);
194 chSysUnlock();
195#if USBH_DEBUG_MULTI_HOST
196 USBH_DEBUG_OUTPUT_CALLBACK(host, rdbuff, len);
197#else
198 USBH_DEBUG_OUTPUT_CALLBACK(rdbuff, len);
199#endif
200 }
201 }
202}
203
204#if USBH_DEBUG_MULTI_HOST
205void usbDbgInit(USBHDriver *host) {
206 struct usbh_debug_helper *const debug = &host->debug;
207 void *param = host;
208#else
209void usbDbgInit(void) {
210 struct usbh_debug_helper *const debug = &usbh_debug;
211 void *param = NULL;
212#endif
213 dq_init(&debug->dq, debug->buff, sizeof(debug->buff));
214 debug->on = true;
215 chThdCreateStatic(debug->thd_wa, sizeof(debug->thd_wa),
216 NORMALPRIO, usb_debug_thread, param);
217}
218
219#endif