diff --git a/bsp/raspberry-pico/README.md b/bsp/raspberry-pico/README.md index c238850b9b27607083733b8dff39b4381fc8defa..eaac07017bf6839ec453015518e4d1c2e8677752 100644 --- a/bsp/raspberry-pico/README.md +++ b/bsp/raspberry-pico/README.md @@ -64,14 +64,14 @@ msh > ## Peripheral Condition -| Drive | Support | Remark | -| ----- | ------- | ------ | -| UART | Support | UART0 | -| GPIO | Support | 0-29 | -| I2C | - | - | -| RTC | - | - | -| SDIO | - | - | -| SPI | - | - | -| TIMER | - | - | -| WDT | - | - | +| Drive | Support | Remark | +| ----- | ------- | ------- | +| UART | Support | UART0/1 | +| GPIO | Support | 0-29 | +| I2C | - | - | +| RTC | - | - | +| SDIO | - | - | +| SPI | - | - | +| TIMER | - | - | +| WDT | - | - | diff --git a/bsp/raspberry-pico/drivers/drv_uart.c b/bsp/raspberry-pico/drivers/drv_uart.c index 925968f6d70321dd68fc785baf7a3a41c1e317bb..6077b60f924de1facf8e44df6e756a39cf6eca90 100644 --- a/bsp/raspberry-pico/drivers/drv_uart.c +++ b/bsp/raspberry-pico/drivers/drv_uart.c @@ -153,3 +153,130 @@ int rt_hw_uart_init(void) return ret; } // INIT_DEVICE_EXPORT(rt_hw_uart_init); + +// We are using pins 0 and 1, but see the GPIO function select table in the +// datasheet for information on which other pins can be used. +#define UART1_TX_PIN 4 +#define UART1_RX_PIN 5 + +static struct pico_uart1_dev uart1_dev; + +struct pico_uart1_dev +{ + struct rt_serial_device parent; + rt_uint32_t uart_periph; + rt_uint32_t irqno; +}; + +void pico_uart1_isr(void) +{ + rt_interrupt_enter(); + /* read interrupt status and clear it */ + if (uart_is_readable(uart1)) /* rx ind */ + { + rt_hw_serial_isr(&uart1_dev.parent, RT_SERIAL_EVENT_RX_IND); + } + + rt_interrupt_leave(); +} + +/* + * UART interface + */ +static rt_err_t pico_uart1_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + return RT_EOK; +} + +static rt_err_t pico_uart1_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + switch (cmd) + { + /* enable interrupt */ + case RT_DEVICE_CTRL_SET_INT: + // Set up a RX interrupt + // We need to set up the handler first + // And set up and enable the interrupt handlers + irq_set_exclusive_handler(UART1_IRQ, pico_uart1_isr); + irq_set_enabled(UART1_IRQ, true); + + // Now enable the UART to send interrupts - RX only + uart_set_irq_enables(uart1, true, false); + break; + } + return RT_EOK; +} + +static int pico_uart1_putc(struct rt_serial_device *serial, char c) +{ + uart_putc_raw(uart1, c); + + return 1; +} + +static int pico_uart1_getc(struct rt_serial_device *serial) +{ + int ch; + + if (uart_is_readable(uart1)) + { + ch = uart_get_hw(uart1)->dr; + } + else + { + ch =-1; + } + + return ch; +} + +const static struct rt_uart_ops _uart1_ops = +{ + pico_uart1_configure, + pico_uart1_control, + pico_uart1_putc, + pico_uart1_getc, + RT_NULL, +}; + +/* + * UART Initiation + */ +int rt_hw_uart1_init(void) +{ + rt_err_t ret = RT_EOK; + + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + uart_init(uart1, 115200); + + // Set the TX and RX pins by using the function select on the GPIO + // Set datasheet for more information on function select + gpio_set_function(UART1_TX_PIN, GPIO_FUNC_UART); + gpio_set_function(UART1_RX_PIN, GPIO_FUNC_UART); + + // Actually, we want a different speed + // The call will return the actual baud rate selected, which will be as close as + // possible to that requested + uart_set_baudrate(uart1, BAUD_RATE); + + // Set UART flow control CTS/RTS, we don't want these, so turn them off + uart_set_hw_flow(uart1, false, false); + + // Set our data format + uart_set_format(uart1, DATA_BITS, STOP_BITS, PARITY); + + // Turn off FIFO's - we want to do this character by character + uart_set_fifo_enabled(uart1, false); + + uart1_dev.parent.ops = &_uart1_ops; + uart1_dev.parent.config = config; + + ret = rt_hw_serial_register(&uart1_dev.parent, + "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &uart1_dev); + + return ret; +} +INIT_DEVICE_EXPORT(rt_hw_uart1_init);