2 * Debugging Utilities for STM32
4 * (c) 2018--2019 Martin Mareš <mj@ucw.cz>
9 #include <libopencm3/stm32/usart.h>
14 /*** Configuration ***/
16 // You should set the following parameters in config.h
18 // Use the semi-hosting interface for debugging messages
19 // #define DEBUG_SEMIHOSTING
21 // Use this USART for debugging messages
22 // #define DEBUG_USART USART1
24 /*** Implementation ***/
26 #ifdef DEBUG_SEMIHOSTING
28 void semi_put_char(char c)
30 // This is tricky, we need to work around GCC bugs
33 "mov r0, #0x03\n" /* SYS_WRITEC */
42 void semi_write_string(char *c)
45 "mov r0, #0x04\n" /* SYS_WRITE0 */
56 void debug_putc(int c)
58 #ifdef DEBUG_SEMIHOSTING
59 static char debug_buf[128];
61 debug_buf[debug_i++] = c;
62 if (c == '\n' || debug_i >= sizeof(debug_buf) - 1) {
63 debug_buf[debug_i] = 0;
64 semi_write_string(debug_buf);
70 usart_send_blocking(DEBUG_USART, '\r');
71 usart_send_blocking(DEBUG_USART, c);
75 void debug_puts(const char *s)
89 static void printf_string(const char *s, uint width, uint flags)
92 uint pad = (len < width) ? width - len : 0;
93 char pad_char = (flags & PF_ZERO_PAD) ? '0' : ' ';
99 if (!(flags & PF_LEFT))
103 static void printf_number(uint i, uint width, uint flags, uint base)
106 char *w = buf + sizeof(buf);
108 if (flags & PF_SIGNED) {
111 flags |= PF_NEGATIVE;
117 uint digit = i % base;
121 *--w = ((flags & PF_UPPERCASE) ? 'A' : 'a') + digit - 10;
126 if (flags & PF_NEGATIVE)
129 printf_string(w, width, flags);
132 void debug_printf(const char *fmt, ...)
154 flags |= PF_ZERO_PAD;
157 while (*fmt >= '0' && *fmt <= '9')
158 width = 10*width + *fmt++ - '0';
163 printf_number(va_arg(args, int), width, flags | PF_SIGNED, 10);
166 printf_number(va_arg(args, int), width, flags, 10);
169 flags |= PF_UPPERCASE;
172 printf_number(va_arg(args, int), width, flags, 16);
175 printf_string(va_arg(args, char *), width, flags);