2 * Debugging Utilities for STM32
4 * (c) 2018--2019 Martin Mareš <mj@ucw.cz>
9 #include <libopencm3/stm32/gpio.h>
10 #include <libopencm3/stm32/usart.h>
15 /*** Configuration ***/
17 // You should set the following parameters in config.h
19 // Use the semi-hosting interface for debugging messages
20 // #define DEBUG_SEMIHOSTING
22 // Use this USART for debugging messages
23 // #define DEBUG_USART USART1
25 // Use this LED for debugging
26 #ifdef DEBUG_LED_BLUEPILL
27 #define DEBUG_LED_GPIO GPIOC
28 #define DEBUG_LED_PIN GPIO13
29 #define DEBUG_LED_INVERSE
32 /*** Implementation ***/
34 #ifdef DEBUG_SEMIHOSTING
36 void semi_put_char(char c)
38 // This is tricky, we need to work around GCC bugs
41 "mov r0, #0x03\n" /* SYS_WRITEC */
50 void semi_write_string(char *c)
53 "mov r0, #0x04\n" /* SYS_WRITE0 */
64 void debug_putc(int c)
66 #ifdef DEBUG_SEMIHOSTING
67 static char debug_buf[128];
69 debug_buf[debug_i++] = c;
70 if (c == '\n' || debug_i >= sizeof(debug_buf) - 1) {
71 debug_buf[debug_i] = 0;
72 semi_write_string(debug_buf);
78 usart_send_blocking(DEBUG_USART, '\r');
79 usart_send_blocking(DEBUG_USART, c);
83 void debug_flush(void)
86 while (!usart_get_flag(DEBUG_USART, USART_FLAG_TC))
91 void debug_puts(const char *s)
105 static void printf_string(const char *s, uint width, uint flags)
107 uint len = strlen(s);
108 uint pad = (len < width) ? width - len : 0;
109 char pad_char = (flags & PF_ZERO_PAD) ? '0' : ' ';
114 debug_putc(pad_char);
115 if (!(flags & PF_LEFT))
119 static void printf_number(uint i, uint width, uint flags, uint base)
122 char *w = buf + sizeof(buf);
124 if (flags & PF_SIGNED) {
127 flags |= PF_NEGATIVE;
133 uint digit = i % base;
137 *--w = ((flags & PF_UPPERCASE) ? 'A' : 'a') + digit - 10;
142 if (flags & PF_NEGATIVE)
145 printf_string(w, width, flags);
148 void debug_printf(const char *fmt, ...)
170 flags |= PF_ZERO_PAD;
173 while (*fmt >= '0' && *fmt <= '9')
174 width = 10*width + *fmt++ - '0';
179 debug_putc(va_arg(args, int));
182 printf_number(va_arg(args, int), width, flags | PF_SIGNED, 10);
185 printf_number(va_arg(args, int), width, flags, 10);
188 flags |= PF_UPPERCASE;
191 printf_number(va_arg(args, int), width, flags, 16);
194 printf_string(va_arg(args, char *), width, flags);
205 void debug_led(bool light)
207 #ifdef DEBUG_LED_GPIO
208 #ifdef DEBUG_LED_INVERSE
212 gpio_set(DEBUG_LED_GPIO, DEBUG_LED_PIN);
214 gpio_clear(DEBUG_LED_GPIO, DEBUG_LED_PIN);
218 void debug_led_toggle(void)
220 #ifdef DEBUG_LED_GPIO
221 gpio_toggle(DEBUG_LED_GPIO, DEBUG_LED_PIN);