From 13709919c2186b923d9c3a3c99773a6b73169f18 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 30 Jun 2019 18:59:54 +0200 Subject: [PATCH] ocm3 test: debugging utilities --- test-opencm3/Makefile | 2 +- test-opencm3/test.c | 34 +++++--- test-opencm3/util-debug.c | 166 ++++++++++++++++++++++++++++++++++++++ test-opencm3/util.h | 69 ++++++++++++++++ 4 files changed, 261 insertions(+), 10 deletions(-) create mode 100644 test-opencm3/util-debug.c create mode 100644 test-opencm3/util.h diff --git a/test-opencm3/Makefile b/test-opencm3/Makefile index 11acf15..afae346 100644 --- a/test-opencm3/Makefile +++ b/test-opencm3/Makefile @@ -1,5 +1,5 @@ BINARY=test -OBJS=test.o +OBJS=test.o util-debug.o OPENCM3_DIR=/home/mj/stm/libopencm3 DEVICE=stm32f103x8 diff --git a/test-opencm3/test.c b/test-opencm3/test.c index a38394c..f02195d 100644 --- a/test-opencm3/test.c +++ b/test-opencm3/test.c @@ -1,20 +1,18 @@ -#include +#include "util.h" #include #include #include #include - -typedef uint8_t byte; -typedef uint16_t u16; -typedef uint32_t u32; -typedef unsigned int uint; +#include static void clock_setup(void) { rcc_clock_setup_in_hse_8mhz_out_72mhz(); + rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOC); + rcc_periph_clock_enable(RCC_USART1); } static void gpio_setup(void) @@ -43,16 +41,34 @@ static void delay_ms(uint ms) ; } +static void usart_setup(void) +{ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX); + + usart_set_baudrate(USART1, 115200); + usart_set_databits(USART1, 8); + usart_set_stopbits(USART1, USART_STOPBITS_1); + usart_set_mode(USART1, USART_MODE_TX); + usart_set_parity(USART1, USART_PARITY_NONE); + usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); + + usart_enable(USART1); +} + int main(void) { clock_setup(); gpio_setup(); tick_setup(); + usart_setup(); - /* Blink the LED (PC13) on the board. */ + int cc = 32; for (;;) { - gpio_toggle(GPIOC, GPIO13); /* LED on/off */ - delay_ms(1000); + gpio_toggle(GPIOC, GPIO13); + debug_putc(cc); + cc++; + if (cc >= 126) cc = 32; + delay_ms(100); } return 0; diff --git a/test-opencm3/util-debug.c b/test-opencm3/util-debug.c new file mode 100644 index 0000000..a1698cf --- /dev/null +++ b/test-opencm3/util-debug.c @@ -0,0 +1,166 @@ +#include "util.h" + +#include + +#include +#include + +#ifdef DEBUG_SEMIHOSTING + +void semi_put_char(char c) +{ + // This is tricky, we need to work around GCC bugs + volatile char cc = c; + asm volatile ( + "mov r0, #0x03\n" /* SYS_WRITEC */ + "mov r1, %[msg]\n" + "bkpt #0xAB\n" + : + : [msg] "r" (&cc) + : "r0", "r1" + ); +} + +void semi_write_string(char *c) +{ + asm volatile ( + "mov r0, #0x04\n" /* SYS_WRITE0 */ + "mov r1, %[msg]\n" + "bkpt #0xAB\n" + : + : [msg] "r" (c) + : "r0", "r1" + ); +} + +#endif + +void debug_putc(int c) +{ +#ifdef DEBUG_SEMIHOSTING + static char debug_buf[128]; + static int debug_i; + debug_buf[debug_i++] = c; + if (c == '\n' || debug_i >= sizeof(debug_buf) - 1) { + debug_buf[debug_i] = 0; + semi_write_string(debug_buf); + debug_i = 0; + } +#endif +#ifdef DEBUG_USART + if (c == '\n') + usart_send_blocking(USART1, '\r'); + usart_send_blocking(USART1, c); +#endif +} + +void debug_puts(const char *s) +{ + while (*s) + debug_putc(*s++); +} + +enum printf_flags { + PF_ZERO_PAD = 1, + PF_SIGNED = 2, + PF_NEGATIVE = 4, + PF_UPPERCASE = 8, + PF_LEFT = 16, +}; + +static void printf_string(const char *s, uint width, uint flags) +{ + uint len = strlen(s); + uint pad = (len < width) ? width - len : 0; + char pad_char = (flags & PF_ZERO_PAD) ? '0' : ' '; + + if (flags & PF_LEFT) + debug_puts(s); + while (pad--) + debug_putc(pad_char); + if (!(flags & PF_LEFT)) + debug_puts(s); +} + +static void printf_number(uint i, uint width, uint flags, uint base) +{ + char buf[16]; + char *w = buf + sizeof(buf); + + if (flags & PF_SIGNED) { + if ((int) i < 0) { + i = - (int) i; + flags |= PF_NEGATIVE; + } + } + + *--w = 0; + do { + uint digit = i % base; + if (digit < 10) + *--w = '0' + digit; + else + *--w = ((flags & PF_UPPERCASE) ? 'A' : 'a') + digit - 10; + i /= base; + } + while (i); + + if (flags & PF_NEGATIVE) + *--w = '-'; + + printf_string(w, width, flags); +} + +void debug_printf(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + while (*fmt) { + int c = *fmt++; + if (c != '%') { + debug_putc(c); + continue; + } + + uint width = 0; + uint flags = 0; + + if (*fmt == '-') { + fmt++; + flags |= PF_LEFT; + } + + if (*fmt == '0') { + fmt++; + flags |= PF_ZERO_PAD; + } + + while (*fmt >= '0' && *fmt <= '9') + width = 10*width + *fmt++ - '0'; + + c = *fmt++; + switch (c) { + case 'd': + printf_number(va_arg(args, int), width, flags | PF_SIGNED, 10); + break; + case 'u': + printf_number(va_arg(args, int), width, flags, 10); + break; + case 'X': + flags |= PF_UPPERCASE; + // fall-thru + case 'x': + printf_number(va_arg(args, int), width, flags, 16); + break; + case 's': + printf_string(va_arg(args, char *), width, flags); + break; + default: + debug_putc(c); + continue; + } + } + + va_end(args); +} diff --git a/test-opencm3/util.h b/test-opencm3/util.h new file mode 100644 index 0000000..6d8c9cc --- /dev/null +++ b/test-opencm3/util.h @@ -0,0 +1,69 @@ +#include +#include + +typedef unsigned int uint; +typedef uint8_t byte; +typedef uint16_t u16; +typedef int16_t s16; +typedef uint32_t u32; +typedef int32_t s32; + +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#define MAX(x,y) ((x) > (y) ? (x) : (y)) + +static inline uint get_u16_le(byte *p) +{ + return (p[1] << 8) | p[0]; +} + +static inline uint get_u16_be(byte *p) +{ + return (p[0] << 8) | p[1]; +} + +static inline uint get_u32_le(byte *p) +{ + return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]; +} + +static inline uint get_u32_be(byte *p) +{ + return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; +} + +static inline void put_u16_le(byte *p, u16 x) +{ + p[0] = x; + p[1] = x >> 8; +} + +static inline void put_u16_be(byte *p, u16 x) +{ + p[0] = x >> 8; + p[1] = x; +} + +static inline void put_u32_be(byte *p, u32 x) +{ + p[0] = x >> 24; + p[1] = (x >> 16) & 0xff; + p[2] = (x >> 8) & 0xff; + p[3] = x & 0xff; +} + +static inline void put_u32_le(byte *p, u32 x) +{ + p[3] = x >> 24; + p[2] = (x >> 16) & 0xff; + p[1] = (x >> 8) & 0xff; + p[0] = x & 0xff; +} + +// debug.c + +// #define DEBUG_SEMIHOSTING +#define DEBUG_USART USART1 + +void debug_printf(const char *fmt, ...); +void debug_puts(const char *s); +void debug_putc(int c); -- 2.39.2