From afc635a0532499fedfded6122f006f8ac3f8f50c Mon Sep 17 00:00:00 2001 From: Carsten Schmiemann Date: Sun, 31 Dec 2023 21:43:58 +0100 Subject: [PATCH] Add hardware handshake --- uart-bridge.c | 138 +++++++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 62 deletions(-) diff --git a/uart-bridge.c b/uart-bridge.c index 9791df6..f540cfc 100644 --- a/uart-bridge.c +++ b/uart-bridge.c @@ -17,7 +17,7 @@ #define LED_PIN 25 -#define BUFFER_SIZE 2560 +#define BUFFER_SIZE 256 #define DEF_BIT_RATE 115200 #define DEF_STOP_BITS 1 @@ -26,10 +26,16 @@ typedef struct { uart_inst_t *const inst; - uint irq; - void *irq_fn; 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 { @@ -44,22 +50,31 @@ typedef struct { mutex_t usb_mtx; } uart_data_t; -void uart0_irq_fn(void); -void uart1_irq_fn(void); - const uart_id_t UART_ID[CFG_TUD_CDC] = { { .inst = uart0, - .irq = UART0_IRQ, - .irq_fn = &uart0_irq_fn, - .tx_pin = 16, - .rx_pin = 17, + .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, - .irq = UART1_IRQ, - .irq_fn = &uart1_irq_fn, - .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 } }; @@ -128,13 +143,14 @@ void update_uart_cfg(uint8_t itf) mutex_exit(&ud->lc_mtx); } -void usb_read_bytes(uint8_t itf) -{ - uart_data_t *ud = &UART_DATA[itf]; +void usb_read_bytes(uint8_t itf) { uint32_t len = tud_cdc_n_available(itf); - if (len && - mutex_try_enter(&ud->usb_mtx, NULL)) { + if (len) { + uart_data_t *ud = &UART_DATA[itf]; + + mutex_enter_blocking(&ud->usb_mtx); + len = MIN(len, BUFFER_SIZE - ud->usb_pos); if (len) { uint32_t count; @@ -147,17 +163,17 @@ void usb_read_bytes(uint8_t itf) } } -void usb_write_bytes(uint8_t itf) -{ +void usb_write_bytes(uint8_t itf) { uart_data_t *ud = &UART_DATA[itf]; - if (ud->uart_pos && - mutex_try_enter(&ud->uart_mtx, NULL)) { + if (ud->uart_pos) { uint32_t count; + mutex_enter_blocking(&ud->uart_mtx); + count = tud_cdc_n_write(itf, ud->uart_buffer, ud->uart_pos); if (count < ud->uart_pos) - memmove(ud->uart_buffer, &ud->uart_buffer[count], + memcpy(ud->uart_buffer, &ud->uart_buffer[count], ud->uart_pos - count); ud->uart_pos -= count; @@ -201,16 +217,16 @@ void core1_entry(void) } } -static inline void uart_read_bytes(uint8_t itf) -{ - uart_data_t *ud = &UART_DATA[itf]; +void uart_read_bytes(uint8_t itf) { const uart_id_t *ui = &UART_ID[itf]; if (uart_is_readable(ui->inst)) { + uart_data_t *ud = &UART_DATA[itf]; + mutex_enter_blocking(&ud->uart_mtx); while (uart_is_readable(ui->inst) && - (ud->uart_pos < BUFFER_SIZE)) { + ud->uart_pos < BUFFER_SIZE) { ud->uart_buffer[ud->uart_pos] = uart_getc(ui->inst); ud->uart_pos++; } @@ -219,48 +235,39 @@ static inline void uart_read_bytes(uint8_t itf) } } -void uart0_irq_fn(void) -{ - uart_read_bytes(0); -} - -void uart1_irq_fn(void) -{ - uart_read_bytes(1); -} - -void uart_write_bytes(uint8_t itf) -{ +void uart_write_bytes(uint8_t itf) { uart_data_t *ud = &UART_DATA[itf]; - if (ud->usb_pos && - mutex_try_enter(&ud->usb_mtx, NULL)) { + if (ud->usb_pos) { const uart_id_t *ui = &UART_ID[itf]; - uint32_t count = 0; - while (uart_is_writable(ui->inst) && - count < ud->usb_pos) { - uart_putc_raw(ui->inst, ud->usb_buffer[count]); - count++; - } + mutex_enter_blocking(&ud->usb_mtx); - if (count < ud->usb_pos) - memmove(ud->usb_buffer, &ud->usb_buffer[count], - ud->usb_pos - count); - ud->usb_pos -= count; + uart_write_blocking(ui->inst, ud->usb_buffer, ud->usb_pos); + ud->usb_pos = 0; mutex_exit(&ud->usb_mtx); } } -void init_uart_data(uint8_t itf) -{ +void init_uart_data(uint8_t itf) { const uart_id_t *ui = &UART_ID[itf]; uart_data_t *ud = &UART_DATA[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; @@ -285,26 +292,32 @@ 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)); - uart_set_fifo_enabled(ui->inst, false); - - /* UART RX Interrupt */ - irq_set_exclusive_handler(ui->irq, ui->irq_fn); - irq_set_enabled(ui->irq, true); - uart_set_irq_enables(ui->inst, true, false); } +#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; set_sys_clock_khz(250000, false); - usbd_serial_init(); - for (itf = 0; itf < CFG_TUD_CDC; itf++) init_uart_data(itf); @@ -316,6 +329,7 @@ int main(void) while (1) { for (itf = 0; itf < CFG_TUD_CDC; itf++) { update_uart_cfg(itf); + uart_read_bytes(itf); uart_write_bytes(itf); } }