diff --git a/CMakeLists.txt b/CMakeLists.txt index e0c286d..40a4b96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.13) +option(FLOW_CONTROL "Enable Hardware Flow-control on the UARTs" FALSE) + include(pico-sdk/pico_sdk_init.cmake) project(pico_uart_bridge) @@ -20,4 +22,12 @@ target_link_libraries(uart_bridge pico_stdlib tinyusb_device) +if(FLOW_CONTROL) +target_compile_definitions(uart_bridge PUBLIC FLOW_CONTROL=1) +endif() + +if(LINE_CONTROL) +target_compile_definitions(uart_bridge PUBLIC LINE_CONTROL=1) +endif() + pico_add_extra_outputs(uart_bridge) diff --git a/README.md b/README.md index c6a3967..e4fae4e 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,45 @@ This software is provided without warranty, according to the MIT License, and sh Raspberry Pi Pico Pinout ------------------------ -| Raspberry Pi Pico GPIO | Function | -|:----------------------:|:--------:| -| GPIO0 (Pin 1) | UART0 TX | -| GPIO1 (Pin 2) | UART0 RX | -| GPIO4 (Pin 6) | UART1 TX | -| GPIO5 (Pin 7) | UART1 RX | +UART0: +| Raspberry Pi Pico GPIO | Function | +|:----------------------:|:---------:| +| GPIO0 (Pin 1) | TX | +| GPIO1 (Pin 2) | RX | +| GPIO2 (Pin 4) | CTS | +| GPIO3 (Pin 5) | RTS | +| GPIO4 (Pin 6) | DTR | +| GPIO5 (Pin 7) | DSR | + +UART1: +| Raspberry Pi Pico GPIO | Function | +|:----------------------:|:---------:| +| GPIO8 (Pin 11) | TX | +| GPIO9 (Pin 12) | RX | +| GPIO10 (Pin 14) | CTS | +| GPIO11 (Pin 15) | RTS | +| GPIO12 (Pin 16) | DTR | +| GPIO13 (Pin 17) | DSR | + +Optional Hardware Flow and Line control +------------------------------ + +Hardware Flow-control (RTS/CTS) is disabled by default, but can be compiled in by running: + +``` bash +cmake -DFLOW_CONTROL . +make +``` + +Line control (DTR/DSR) is disabled by default, but can be compiled in by running: + +``` bash +cmake -DLINE_CONTROL . +make +``` + +To enable both: +``` bash +cmake -DLINE_CONTROL -DFLOW_CONTROL . +make +``` diff --git a/uart-bridge.c b/uart-bridge.c index aebbdf6..913188e 100644 --- a/uart-bridge.c +++ b/uart-bridge.c @@ -28,6 +28,14 @@ typedef struct { uart_inst_t *const inst; uint8_t tx_pin; uint8_t rx_pin; +#ifdef FLOW_CONTROL + uint8_t rts_pin; + uint8_t cts_pin; +#endif +#ifdef LINE_CONTROL + uint8_t dtr_pin; + uint8_t dsr_pin; +#endif } uart_id_t; typedef struct { @@ -47,10 +55,26 @@ const uart_id_t UART_ID[CFG_TUD_CDC] = { .inst = uart0, .tx_pin = 0, .rx_pin = 1, +#ifdef FLOW_CONTROL + .cts_pin = 2, + .rts_pin = 3, +#endif +#ifdef LINE_CONTROL + .dtr_pin = 4, + .dsr_pin = 5, +#endif }, { .inst = uart1, - .tx_pin = 4, - .rx_pin = 5, + .tx_pin = 8, + .rx_pin = 9, +#ifdef FLOW_CONTROL + .cts_pin = 10, + .rts_pin = 11, +#endif +#ifdef LINE_CONTROL + .dtr_pin = 12, + .dsr_pin = 13, +#endif } }; @@ -233,6 +257,17 @@ void init_uart_data(uint8_t itf) { /* Pinmux */ gpio_set_function(ui->tx_pin, GPIO_FUNC_UART); gpio_set_function(ui->rx_pin, GPIO_FUNC_UART); +#ifdef FLOW_CONTROL + gpio_set_function(ui->rts_pin, GPIO_FUNC_UART); + gpio_set_function(ui->cts_pin, GPIO_FUNC_UART); +#endif + +#ifdef LINE_CONTROL + gpio_init(ui->dtr_pin); + gpio_set_dir(ui->dtr_pin, GPIO_OUT); + gpio_init(ui->dsr_pin); + gpio_set_dir(ui->dsr_pin, GPIO_IN); +#endif /* USB CDC LC */ ud->usb_lc.bit_rate = DEF_BIT_RATE; @@ -257,12 +292,26 @@ void init_uart_data(uint8_t itf) { /* UART start */ uart_init(ui->inst, ud->usb_lc.bit_rate); +#ifdef FLOW_CONTROL + uart_set_hw_flow(ui->inst, true, true); +#else uart_set_hw_flow(ui->inst, false, false); +#endif uart_set_format(ui->inst, databits_usb2uart(ud->usb_lc.data_bits), stopbits_usb2uart(ud->usb_lc.stop_bits), parity_usb2uart(ud->usb_lc.parity)); } +#ifdef LINE_CONTROL +/* Invoked when line state has changed */ +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) +{ + const uart_id_t *ui = &UART_ID[itf]; + + gpio_put(ui->dtr_pin, dtr); +} +#endif + int main(void) { int itf;