Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get USB serial working #13

Merged
merged 1 commit into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion config
4 changes: 2 additions & 2 deletions local/configs/project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ format: false

version:
major: 0
minor: 2
patch: 3
minor: 3
patch: 0
92 changes: 49 additions & 43 deletions src/UartManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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;
};
49 changes: 12 additions & 37 deletions src/apps/test_file.cc
Original file line number Diff line number Diff line change
@@ -1,63 +1,38 @@
/* 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)
{
// 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();
Expand Down
54 changes: 54 additions & 0 deletions src/cli.cc
Original file line number Diff line number Diff line change
@@ -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);
}
9 changes: 9 additions & 0 deletions src/cli.h
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 2 additions & 0 deletions src/pico_headers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
20 changes: 0 additions & 20 deletions src/system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
2 changes: 0 additions & 2 deletions src/system.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#pragma once

__attribute__((noreturn)) void reset(bool bootloader);

void dump_clocks(void);
11 changes: 8 additions & 3 deletions src/uart_stdio.cc
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions yambs.yaml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down