From 33145489964e09f3e5a7efa2ee2c399994c11f94 Mon Sep 17 00:00:00 2001 From: Vaughn Kottler Date: Sun, 29 Oct 2023 20:54:02 -0500 Subject: [PATCH] Get USB serial working --- README.md | 4 +- config | 2 +- local/configs/project.yaml | 4 +- src/UartManager.h | 92 ++++++++++++++++++++------------------ src/apps/test_file.cc | 49 +++++--------------- src/cli.cc | 54 ++++++++++++++++++++++ src/cli.h | 9 ++++ src/pico_headers.h | 2 + src/system.cc | 20 --------- src/system.h | 2 - src/uart_stdio.cc | 11 +++-- yambs.yaml | 4 +- 12 files changed, 141 insertions(+), 112 deletions(-) create mode 100644 src/cli.cc create mode 100644 src/cli.h diff --git a/README.md b/README.md index 31cfc3a..76b5dc4 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ ===================================== generator=datazen version=3.1.4 - hash=cd35154414b30ab13a11e07eb0a27c70 + hash=2a8aa648496efabc77f79bc15d2f8dc7 ===================================== --> -# pico ([0.2.3](https://github.com/vkottler/pico/releases/tag/0.2.3)) +# pico ([0.3.0](https://github.com/vkottler/pico/releases/tag/0.3.0)) [![codecov](https://codecov.io/gh/vkottler/pico/branch/master/graph/badge.svg)](https://codecov.io/gh/vkottler/pico) ![Build Status](https://github.com/vkottler/pico/actions/workflows/yambs-project.yml/badge.svg) diff --git a/config b/config index 52d8435..82fcf8f 160000 --- a/config +++ b/config @@ -1 +1 @@ -Subproject commit 52d84357ffe4bf2bc3579603d7840bdff4bcda50 +Subproject commit 82fcf8f5e1cf0e58d67fd270126201d640df668d diff --git a/local/configs/project.yaml b/local/configs/project.yaml index 99f33a9..1ee02b9 100644 --- a/local/configs/project.yaml +++ b/local/configs/project.yaml @@ -8,5 +8,5 @@ format: false version: major: 0 - minor: 2 - patch: 3 + minor: 3 + patch: 0 diff --git a/src/UartManager.h b/src/UartManager.h index adb3a12..b951b03 100644 --- a/src/UartManager.h +++ b/src/UartManager.h @@ -15,26 +15,13 @@ class UartManager tx_depth, rx_depth, char>; public: - UartManager(uart_inst_t *_uart, bool _echo = true, - bool _add_carriage_return = true) - : FdBuffer(), uart(_uart), echo(_echo), - add_carriage_return(_add_carriage_return) + UartManager(uart_inst_t *_uart = nullptr, bool _echo = true) + : FdBuffer(), uart(_uart), echo(_echo) { } void putc_block(uint8_t data) { - switch (data) - { - case '\n': - /* If we should add carriage returns, add it first. */ - if (add_carriage_return) - { - putc_block('\r'); - } - break; - } - this->tx.push_blocking(data); } @@ -43,53 +30,72 @@ class UartManager this->tx.flush(); /* Wait for UART to be completely empty. */ - uart_tx_wait_blocking(uart); + if (uart) + { + uart_tx_wait_blocking(uart); + } + + stdio_flush(); } inline void service_tx_impl(FdBuffer::TxBuffer *buf) { char data; - while (uart_is_writable(uart) and !buf->empty()) + + while (!buf->empty() and + (not uart or (uart and uart_is_writable(uart)))) { assert(buf->pop(data)); - uart_get_hw(uart)->dr = data; + + /* Write UART. */ + if (uart) + { + uart_get_hw(uart)->dr = data; + } + + /* Write via pico-sdk stdio. */ + putchar_raw(data); } } - inline void service_rx_impl(FdBuffer::RxBuffer *buf) + inline void receive_byte(FdBuffer::RxBuffer *buf, uint8_t data) { - uint8_t data; - while (uart_is_readable(uart) and !buf->full()) + assert(buf->push(data)); + + if (echo) { - data = uart_getc(uart); - assert(buf->push(data)); + switch (data) + { + case '\r': + putc_block('\n'); + [[fallthrough]]; + default: + putc_block(data); + } + } + } - if (echo) + inline void service_rx_impl(FdBuffer::RxBuffer *buf) + { + /* Check hardware UART. */ + if (uart) + { + while (!buf->full() and uart_is_readable(uart)) { - switch (data) - { - case '\r': - putc_block('\n'); - - /* - * If carriage returns are getting added automatically, - * the '\n' put will already add one. - */ - if (add_carriage_return) - { - break; - } - - [[fallthrough]]; - default: - putc_block(data); - } + receive_byte(buf, uart_getc(uart)); } } + + /* Check pico-sdk stdio. */ + int stdio_data; + while (!buf->full() and + ((stdio_data = getchar_timeout_us(0)) != PICO_ERROR_TIMEOUT)) + { + receive_byte(buf, stdio_data); + } } protected: uart_inst_t *uart; bool echo; - bool add_carriage_return; }; diff --git a/src/apps/test_file.cc b/src/apps/test_file.cc index 8c2908d..474a3b5 100644 --- a/src/apps/test_file.cc +++ b/src/apps/test_file.cc @@ -1,35 +1,7 @@ /* internal */ -#include "pico_headers.h" -#include "picolibc-semihost/App.h" -#include "system.h" +#include "cli.h" #include "uart_stdio.h" -static constexpr uint led_pin = 25; - -static inline void gpio_toggle(uint gpio) -{ - gpio_xor_mask(1u << gpio); -} - -void do_led(CommandLine &cli) -{ - (void)cli; - gpio_toggle(led_pin); - printf("Toggling LED.\n"); -} - -void do_exit(CommandLine &cli) -{ - (void)cli; - reset(true); -} - -void register_commands(CommandLineApp &app) -{ - app.add_handler("led", do_led, "toggle the LED on or off"); - app.add_handler("exit", do_exit, "exit the application"); -} - void core1_app(void) { while (true) @@ -37,27 +9,30 @@ void core1_app(void) // some kind of state machine thing? /* LED heartbeat. */ - gpio_toggle(led_pin); + gpio_xor_mask(1u << led_pin); sleep_until(delayed_by_us(get_absolute_time(), 100 * 1000)); } } -void init(uint led_pin) +void init(void) { + stdio_usb_init(); + gpio_init(led_pin); gpio_set_dir(led_pin, GPIO_OUT); /* Initialize UART pins and peripheral. */ - gpio_set_function(0, GPIO_FUNC_UART); - gpio_set_function(1, GPIO_FUNC_UART); - uart_init(stdio_uart, 115200); - - dump_clocks(); + if (stdio_uart) + { + gpio_set_function(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART); + gpio_set_function(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART); + uart_init(stdio_uart, 115200); + } } int main(void) { - init(led_pin); + init(); /* Start other processor. */ multicore_reset_core1(); diff --git a/src/cli.cc b/src/cli.cc new file mode 100644 index 0000000..6fd6f21 --- /dev/null +++ b/src/cli.cc @@ -0,0 +1,54 @@ +#include "cli.h" +#include "system.h" + +static inline void gpio_toggle(uint gpio) +{ + gpio_xor_mask(1u << gpio); +} + +void do_led(CommandLine &cli) +{ + (void)cli; + + gpio_toggle(led_pin); + printf("Toggling LED.\n"); +} + +void do_exit(CommandLine &cli) +{ + /* could control app vs. bootloader at some point */ + (void)cli; + bool bootloader = true; + + printf("Resetting to %s.\n", bootloader ? "bootloader" : "application"); + reset(bootloader); +} + +void do_clocks(CommandLine &cli) +{ + (void)cli; + + printf("pll_sys = %lu kHz\n", + frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY)); + printf("pll_usb = %lu kHz\n", + frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY)); + printf("rosc = %lu kHz\n", + frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC)); + printf("clk_sys = %lu kHz\n", + frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS)); + printf("clk_peri = %lu kHz\n", + frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI)); + printf("clk_usb = %lu kHz\n", + frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB)); + printf("clk_adc = %lu kHz\n", + frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC)); + printf("clk_rtc = %lu kHz\n", + frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC)); +} + +void register_commands(CommandLineApp &app) +{ + app.add_handler("led", do_led, "toggle the LED on or off"); + app.add_handler("exit", do_exit, "exit the application"); + app.add_handler("clocks", do_clocks); +} diff --git a/src/cli.h b/src/cli.h new file mode 100644 index 0000000..484e052 --- /dev/null +++ b/src/cli.h @@ -0,0 +1,9 @@ +#pragma once + +#include "boards/pico.h" +#include "pico_headers.h" +#include "picolibc-semihost/App.h" + +static constexpr uint led_pin = PICO_DEFAULT_LED_PIN; + +void register_commands(CommandLineApp &app); diff --git a/src/pico_headers.h b/src/pico_headers.h index fa7055a..e8073b2 100644 --- a/src/pico_headers.h +++ b/src/pico_headers.h @@ -12,7 +12,9 @@ #include "hardware/structs/scb.h" #include "hardware/uart.h" #include "pico/bootrom.h" +#include "pico/critical_section.h" #include "pico/multicore.h" +#include "pico/stdio_usb.h" #include "pico/time.h" #pragma GCC diagnostic pop diff --git a/src/system.cc b/src/system.cc index c34c54c..397503d 100644 --- a/src/system.cc +++ b/src/system.cc @@ -32,23 +32,3 @@ extern "C" void __attribute__((noreturn)) _exit(int status) printf("Exiting %d.\n", status); reset(true); } - -void dump_clocks(void) -{ - printf("pll_sys = %lu kHz\n", - frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY)); - printf("pll_usb = %lu kHz\n", - frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY)); - printf("rosc = %lu kHz\n", - frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC)); - printf("clk_sys = %lu kHz\n", - frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS)); - printf("clk_peri = %lu kHz\n", - frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI)); - printf("clk_usb = %lu kHz\n", - frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB)); - printf("clk_adc = %lu kHz\n", - frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC)); - printf("clk_rtc = %lu kHz\n", - frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC)); -} diff --git a/src/system.h b/src/system.h index 6e4cdea..a82cfb2 100644 --- a/src/system.h +++ b/src/system.h @@ -1,5 +1,3 @@ #pragma once __attribute__((noreturn)) void reset(bool bootloader); - -void dump_clocks(void); diff --git a/src/uart_stdio.cc b/src/uart_stdio.cc index 32c22b9..ff26966 100644 --- a/src/uart_stdio.cc +++ b/src/uart_stdio.cc @@ -1,8 +1,8 @@ /* internal */ #include "uart_stdio.h" -uart_inst_t *const stdio_uart = uart0; - +// uart_inst_t *const stdio_uart = uart0; +uart_inst_t *const stdio_uart = nullptr; static UartInterface uart(stdio_uart); UartInterface &get_stdio_uart() @@ -15,8 +15,13 @@ extern "C" int putc_extra(char c, FILE *file, bool semihosting_enabled) (void)file; (void)semihosting_enabled; - uart.putc_block(c); + /* Handle newlines automatically. */ + if (c == '\n') + { + uart.putc_block('\r'); + } + uart.putc_block(c); return 0; } diff --git a/yambs.yaml b/yambs.yaml index c85b50b..7e282a3 100644 --- a/yambs.yaml +++ b/yambs.yaml @@ -1,14 +1,14 @@ # ===================================== # generator=datazen # version=3.1.4 -# hash=ab377c00f5dd2a34c28d9032f22d626d +# hash=5806cfad300fa90e7f5f6bcaffbf210a # ===================================== --- project: name: pico github: {owner: &self vkottler} - version: {major: 0, minor: 2, patch: 3} + version: {major: 0, minor: 3, patch: 0} variants: clang: suffix: &clang_version "-17"