Skip to content

Commit

Permalink
Merge pull request #1100 from veremenko-y/rpipico-uart-fixes
Browse files Browse the repository at this point in the history
rpipico: better uart init/deinit. fixed interrupt handling
  • Loading branch information
EtchedPixels authored Oct 20, 2024
2 parents ff1d023 + 1a957f4 commit 0028558
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 70 deletions.
2 changes: 1 addition & 1 deletion Kernel/platform/platform-rpipico/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Partition SD card on your computer using MBR partition scheme then create 32MB p
If using Linux or MacOS you can then copy `filesystem.img` onto the SD card using `dd` command.

```
dd if=filesystem.img of=/dev/sdN bs=512 seek=2048
dd if=filesystem.img of=/dev/sdXn oflag=direct bs=8192
```

The first thing you probably want to do is `stty erase '^?'` to make the DELETE
Expand Down
10 changes: 6 additions & 4 deletions Kernel/platform/platform-rpipico/devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,23 @@ bool validdev(uint16_t dev)

static void timer_tick_cb(unsigned alarm)
{
irqflags_t irq = di();
udata.u_ininterrupt = 1;

absolute_time_t next;
update_us_since_boot(&next, to_us_since_boot(now) + (1000000 / TICKSPERSEC));

irqflags_t irq = di();
udata.u_ininterrupt = 1;
tty_interrupt();
timer_interrupt();
udata.u_ininterrupt = 0;
irqrestore(irq);

if (hardware_alarm_set_target(0, next))
{
update_us_since_boot(&next, time_us_64() + (1000000 / TICKSPERSEC));
hardware_alarm_set_target(0, next);
}

udata.u_ininterrupt = 0;
irqrestore(irq);
}

void device_init(void)
Expand Down
2 changes: 1 addition & 1 deletion Kernel/platform/platform-rpipico/devtty.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static void devtty_defconfig(uint8_t drv, int count, int minor)
/* To be called right after startup to be able to print boot messages */
void devtty_early_init(void)
{
rawuart_init();
rawuart_early_init();
core1_init();
devtty_init();
}
Expand Down
145 changes: 82 additions & 63 deletions Kernel/platform/platform-rpipico/rawuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,60 +14,87 @@
#error "Only two UARTs are supported"
#endif

#ifndef DEV_UART_0_CTS_PIN
#define DEV_UART_0_CTS_PIN 0
#endif
#ifndef DEV_UART_0_RTS_PIN
#define DEV_UART_0_RTS_PIN 0
#endif

#ifndef DEV_UART_1_CTS_PIN
#define DEV_UART_1_CTS_PIN 0
#endif
#ifndef DEV_UART_1_RTS_PIN
#define DEV_UART_1_RTS_PIN 0
#endif

static uint clocks[] = {
0, /* B0 */
50, /* B50 */
75, /* B75 */
110, /* B110 */
134, /* B134 */
150, /* B150 */
300, /* B300 */
600, /* B600 */
1200, /* B1200 */
2400, /* B2400 */
4800, /* B4800 */
9600, /* B9600 */
19200, /* B19200 */
38400, /* B38400 */
57600, /* B57600 */
0, /* B0 */
50, /* B50 */
75, /* B75 */
110, /* B110 */
134, /* B134 */
150, /* B150 */
300, /* B300 */
600, /* B600 */
1200, /* B1200 */
2400, /* B2400 */
4800, /* B4800 */
9600, /* B9600 */
19200, /* B19200 */
38400, /* B38400 */
57600, /* B57600 */
115200, /* B115200 */
};

void rawuart_init(void)
static uart_inst_t * rawuart_init_one(int num, int tx, int rx, int cts, int rts)
{
bool cts = false;
bool rts = false;
uart_init(uart0, PICO_DEFAULT_UART_BAUD_RATE);
gpio_set_function(DEV_UART_0_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(DEV_UART_0_RX_PIN, GPIO_FUNC_UART);
uart_set_translate_crlf(uart0, false);
uart_set_fifo_enabled(uart0, true);
#ifdef DEV_UART_0_CTS_PIN
gpio_set_function(DEV_UART_0_CTS_PIN, GPIO_FUNC_UART);
cts = true;
#endif
#ifdef DEV_UART_0_RTS_PIN
gpio_set_function(DEV_UART_0_RTS_PIN, GPIO_FUNC_UART);
rts = true;
#endif
uart_set_hw_flow(uart1, cts, rts);

#if NUM_DEV_TTY_UART >= 2
uart_init(uart1, PICO_DEFAULT_UART_BAUD_RATE);
gpio_set_function(DEV_UART_1_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(DEV_UART_1_RX_PIN, GPIO_FUNC_UART);
uart_set_translate_crlf(uart1, false);
uart_set_fifo_enabled(uart1, true);
#ifdef DEV_UART_1_CTS_PIN
gpio_set_function(DEV_UART_1_CTS_PIN, GPIO_FUNC_UART);
cts = true;
#endif
#ifdef DEV_UART_1_RTS_PIN
gpio_set_function(DEV_UART_1_RTS_PIN, GPIO_FUNC_UART);
rts = true;
#endif
uart_set_hw_flow(uart1, cts, rts);
#endif
uart_inst_t *uart = uart_get_instance(num);
uart_init(uart, PICO_DEFAULT_UART_BAUD_RATE);
gpio_set_function(tx, GPIO_FUNC_UART);
gpio_set_function(rx, GPIO_FUNC_UART);
uart_set_translate_crlf(uart, false);
uart_set_fifo_enabled(uart, true);
if (cts > 0)
{
gpio_set_function(DEV_UART_0_CTS_PIN, GPIO_FUNC_UART);
}
if (rts > 0)
{
gpio_set_function(DEV_UART_0_RTS_PIN, GPIO_FUNC_UART);
}
uart_set_hw_flow(uart, cts > 0, rts > 0);
return uart;
}

static uart_inst_t * rawuart_init(uint_fast8_t uart)
{
if (uart == 0)
{
return rawuart_init_one(0,
DEV_UART_0_TX_PIN,
DEV_UART_0_RX_PIN,
DEV_UART_0_CTS_PIN,
DEV_UART_0_RTS_PIN);
}
else
{
return rawuart_init_one(1,
DEV_UART_1_TX_PIN,
DEV_UART_1_RX_PIN,
DEV_UART_1_CTS_PIN,
DEV_UART_1_RTS_PIN);
}
}

static void rawuart_deinit(uart_inst_t * uart){
uart_deinit(uart);
}

void rawuart_early_init()
{
// init first uart for kprint
rawuart_init(0);
}

void rawuart_putc(uint8_t devn, uint8_t c)
Expand All @@ -80,7 +107,7 @@ void rawuart_putc(uint8_t devn, uint8_t c)
uart_putc(uart, c);
}

void rawuart_sleeping(uint8_t devn){}
void rawuart_sleeping(uint8_t devn) {}

ttyready_t rawuart_ready(uint8_t devn)
{
Expand All @@ -107,17 +134,12 @@ void rawuart_setup(uint_fast8_t minor, uint_fast8_t devn, uint_fast8_t flags)
{
struct termios *t = &ttydata[minor].termios;

#ifdef DEBUG
kprintf("rawuart_setup %d %d %d\n", minor, devn, flags);
kprintf("\ttermios %x\n", t->c_cflag);
#endif

uart_inst_t *uart = uart_get_instance(devn - 1);
uart_inst_t *uart = rawuart_init(devn - 1);

/* Wait for output to finish */
if (flags)
{
while(!uart_tx_is_empty(uart))
while (!uart_tx_is_empty(uart))
_sched_yield();
}
uint baud_rate;
Expand All @@ -127,9 +149,10 @@ void rawuart_setup(uint_fast8_t minor, uint_fast8_t devn, uint_fast8_t flags)

speed_t speed = t->c_cflag & CBAUD;
baud_rate = clocks[speed];
if (baud_rate == 0)
if (baud_rate == 0) // Hangup if speed is B0 as per stty.1
{
baud_rate = PICO_DEFAULT_UART_BAUD_RATE;
rawuart_deinit(uart);
return;
}

if (t->c_cflag & CSTOPB)
Expand All @@ -146,10 +169,6 @@ void rawuart_setup(uint_fast8_t minor, uint_fast8_t devn, uint_fast8_t flags)
{
parity = UART_PARITY_ODD;
}
#if DEBUG
kprintf("uart baud %d\n", baud_rate);
kprintf("bits %d stop %d parity %d\n", data_bits, stop_bits, parity);
#endif
uart_set_baudrate(uart, baud_rate);
uart_set_format(uart, data_bits, stop_bits, parity);
}
2 changes: 1 addition & 1 deletion Kernel/platform/platform-rpipico/rawuart.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <tty.h>

extern void rawuart_init(void);
extern void rawuart_early_init();
extern void rawuart_putc(uint8_t devn, uint8_t c);
extern ttyready_t rawuart_ready(uint8_t devn);
extern void rawuart_sleeping(uint8_t devn);
Expand Down

0 comments on commit 0028558

Please sign in to comment.