diff options
| -rw-r--r-- | bsp/raspberry-pico/drivers/drv_uart.c | 291 | ||||
| -rw-r--r-- | bsp/raspberry-pico/drivers/drv_uart.h | 3 |
2 files changed, 122 insertions, 172 deletions
diff --git a/bsp/raspberry-pico/drivers/drv_uart.c b/bsp/raspberry-pico/drivers/drv_uart.c index 6077b60f92..64f572b883 100644 --- a/bsp/raspberry-pico/drivers/drv_uart.c +++ b/bsp/raspberry-pico/drivers/drv_uart.c @@ -5,6 +5,7 @@ * * Change Logs: * Date Author Notes + * 2023-09-26 1ridic Integrate with RT-Thread driver framework. */ #include <rthw.h> @@ -13,183 +14,127 @@ #include "board.h" #include "drv_uart.h" +#ifdef RT_USING_SERIAL + #include "hardware/uart.h" #include "hardware/irq.h" -#define UART_ID uart0 -#define BAUD_RATE 115200 -#define DATA_BITS 8 -#define STOP_BITS 1 -#define PARITY UART_PARITY_NONE - -// 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 UART_TX_PIN 0 -#define UART_RX_PIN 1 +#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) + #error "Please define at least one BSP_USING_UARTx" + /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */ +#endif -#define PICO_UART_DEVICE(uart) (struct pico_uart_dev *)(uart) - -static struct pico_uart_dev uart0_dev; +#ifdef BSP_USING_UART0 + void pico_uart0_isr(void); +#endif +#ifdef BSP_USING_UART1 + void pico_uart1_isr(void); +#endif struct pico_uart_dev { - struct rt_serial_device parent; - rt_uint32_t uart_periph; + rt_serial_t parent; + uart_inst_t *instance; rt_uint32_t irqno; + rt_uint32_t tx_pin; + rt_uint32_t rx_pin; + void (*uart_isr)(void); }; -void pico_uart_isr(void) +static struct pico_uart_dev uart_dev[] = { - rt_interrupt_enter(); - /* read interrupt status and clear it */ - if (uart_is_readable(uart0)) /* rx ind */ +#ifdef BSP_USING_UART0 { - rt_hw_serial_isr(&uart0_dev.parent, RT_SERIAL_EVENT_RX_IND); - } - - rt_interrupt_leave(); -} + .instance = uart0, + .irqno = UART0_IRQ, + .tx_pin = BSP_UART0_TX_PIN, + .rx_pin = BSP_UART0_RX_PIN, + .uart_isr = pico_uart0_isr, + }, +#endif +#ifdef BSP_USING_UART1 + { + .instance = uart1, + .irqno = UART1_IRQ, + .tx_pin = BSP_UART1_TX_PIN, + .rx_pin = BSP_UART1_RX_PIN, + .uart_isr = pico_uart1_isr, + }, +#endif +}; -/* - * UART interface - */ -static rt_err_t pico_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +enum { - return RT_EOK; -} +#ifdef BSP_USING_UART0 + UART0_INDEX, +#endif +#ifdef BSP_USING_UART1 + UART1_INDEX, +#endif +}; -static rt_err_t pico_uart_control(struct rt_serial_device *serial, int cmd, void *arg) +#ifdef BSP_USING_UART0 +void pico_uart0_isr(void) { - // Select correct interrupt for the UART we are using - int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ; - - switch (cmd) + rt_interrupt_enter(); + /* read interrupt status and clear it */ + if (uart_is_readable(uart0)) /* rx ind */ { - /* 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(UART_IRQ, pico_uart_isr); - irq_set_enabled(UART_IRQ, true); - - // Now enable the UART to send interrupts - RX only - uart_set_irq_enables(UART_ID, true, false); - break; + rt_hw_serial_isr(&uart_dev[UART0_INDEX].parent, RT_SERIAL_EVENT_RX_IND); } - return RT_EOK; -} -static int pico_uart_putc(struct rt_serial_device *serial, char c) -{ - uart_putc_raw(uart0, c); - - return 1; + rt_interrupt_leave(); } - -static int pico_uart_getc(struct rt_serial_device *serial) +#endif +#ifdef BSP_USING_UART1 +void pico_uart1_isr(void) { - int ch; - - if (uart_is_readable(uart0)) - { - ch = uart_get_hw(uart0)->dr; - } - else + rt_interrupt_enter(); + /* read interrupt status and clear it */ + if (uart_is_readable(uart1)) /* rx ind */ { - ch =-1; + rt_hw_serial_isr(&uart_dev[UART1_INDEX].parent, RT_SERIAL_EVENT_RX_IND); } - return ch; + rt_interrupt_leave(); } - -const static struct rt_uart_ops _uart_ops = -{ - pico_uart_configure, - pico_uart_control, - pico_uart_putc, - pico_uart_getc, - RT_NULL, -}; +#endif /* - * UART Initiation + * UART interface */ -int rt_hw_uart_init(void) +static rt_err_t pico_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { - rt_err_t ret = RT_EOK; - - struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + struct pico_uart_dev *uart = RT_NULL; + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + uart = rt_container_of(serial, struct pico_uart_dev, parent); - uart_init(UART_ID, 115200); + uart_init(uart->instance, cfg->baud_rate); // 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(UART_TX_PIN, GPIO_FUNC_UART); - gpio_set_function(UART_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(UART_ID, BAUD_RATE); + gpio_set_function(uart->rx_pin, GPIO_FUNC_UART); + gpio_set_function(uart->tx_pin, GPIO_FUNC_UART); // Set UART flow control CTS/RTS, we don't want these, so turn them off - uart_set_hw_flow(UART_ID, false, false); + uart_set_hw_flow(uart->instance, false, false); // Set our data format - uart_set_format(UART_ID, DATA_BITS, STOP_BITS, PARITY); + uart_set_format(uart->instance, cfg->data_bits, cfg->stop_bits, UART_PARITY_NONE); // Turn off FIFO's - we want to do this character by character - uart_set_fifo_enabled(UART_ID, false); - - uart0_dev.parent.ops = &_uart_ops; - uart0_dev.parent.config = config; - - ret = rt_hw_serial_register(&uart0_dev.parent, - "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - &uart0_dev); - - return ret; -} -// INIT_DEVICE_EXPORT(rt_hw_uart_init); + uart_set_fifo_enabled(uart->instance, false); -// 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) +static rt_err_t pico_uart_control(struct rt_serial_device *serial, int cmd, void *arg) { + struct pico_uart_dev *uart = RT_NULL; + RT_ASSERT(serial != RT_NULL); + uart = rt_container_of(serial, struct pico_uart_dev, parent); + switch (cmd) { /* enable interrupt */ @@ -197,86 +142,88 @@ static rt_err_t pico_uart1_control(struct rt_serial_device *serial, int cmd, voi // 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); + irq_set_exclusive_handler(uart->irqno, uart->uart_isr); + irq_set_enabled(uart->irqno, true); // Now enable the UART to send interrupts - RX only - uart_set_irq_enables(uart1, true, false); + uart_set_irq_enables(uart->instance, true, false); break; } return RT_EOK; } -static int pico_uart1_putc(struct rt_serial_device *serial, char c) +static int pico_uart_putc(struct rt_serial_device *serial, char c) { - uart_putc_raw(uart1, c); + struct pico_uart_dev *uart = RT_NULL; + RT_ASSERT(serial != RT_NULL); + uart = rt_container_of(serial, struct pico_uart_dev, parent); + uart_putc_raw(uart->instance, c); return 1; } -static int pico_uart1_getc(struct rt_serial_device *serial) +static int pico_uart_getc(struct rt_serial_device *serial) { + struct pico_uart_dev *uart = RT_NULL; + RT_ASSERT(serial != RT_NULL); + uart = rt_container_of(serial, struct pico_uart_dev, parent); + int ch; - if (uart_is_readable(uart1)) + if (uart_is_readable(uart->instance)) { - ch = uart_get_hw(uart1)->dr; + ch = uart_get_hw(uart->instance)->dr; } else { - ch =-1; + ch = -1; } return ch; } -const static struct rt_uart_ops _uart1_ops = +const static struct rt_uart_ops _uart_ops = { - pico_uart1_configure, - pico_uart1_control, - pico_uart1_putc, - pico_uart1_getc, + pico_uart_configure, + pico_uart_control, + pico_uart_putc, + pico_uart_getc, RT_NULL, }; /* * UART Initiation */ -int rt_hw_uart1_init(void) +int rt_hw_uart_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); +#ifdef BSP_USING_UART0 + uart_dev[UART0_INDEX].parent.ops = &_uart_ops; + uart_dev[UART0_INDEX].parent.config = config; - // 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); + ret = rt_hw_serial_register(&uart_dev[UART0_INDEX].parent, + "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + &uart_dev[UART0_INDEX]); + RT_ASSERT(ret == RT_EOK); +#endif - uart1_dev.parent.ops = &_uart1_ops; - uart1_dev.parent.config = config; +#ifdef BSP_USING_UART1 + uart_dev[UART1_INDEX].parent.ops = &_uart_ops; + uart_dev[UART1_INDEX].parent.config = config; - ret = rt_hw_serial_register(&uart1_dev.parent, + ret = rt_hw_serial_register(&uart_dev[UART1_INDEX].parent, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - &uart1_dev); + &uart_dev[UART1_INDEX]); + RT_ASSERT(ret == RT_EOK); +#endif return ret; } -INIT_DEVICE_EXPORT(rt_hw_uart1_init); + + +#endif /* RT_USING_SERIAL */ diff --git a/bsp/raspberry-pico/drivers/drv_uart.h b/bsp/raspberry-pico/drivers/drv_uart.h index ac49a4c8fc..79bae1f7cc 100644 --- a/bsp/raspberry-pico/drivers/drv_uart.h +++ b/bsp/raspberry-pico/drivers/drv_uart.h @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2021-01-28 flybreak first version + * 2023-09-26 1ridic Integrate with RT-Thread driver framework. */ #ifndef __USART_H__ @@ -14,6 +15,8 @@ #include <rthw.h> #include <rtthread.h> +#ifdef RT_USING_SERIAL int rt_hw_uart_init(void); +#endif #endif |
