From d6f7bab1b2119a43b7897941b867e6fc593ddd5c Mon Sep 17 00:00:00 2001 From: sys64738 Date: Wed, 21 Jul 2021 19:59:59 +0200 Subject: [PATCH] proper line coding & baudrate setting thru usb-cdc interface --- bsp/rp2040/m_default/cdc_uart.c | 22 +++++++++++++++++-- src/m_default/_default.c | 38 ++++++++++++++++++++++++++++++++- src/m_default/cdc.h | 3 +++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/bsp/rp2040/m_default/cdc_uart.c b/bsp/rp2040/m_default/cdc_uart.c index 913f6d0..500477d 100644 --- a/bsp/rp2040/m_default/cdc_uart.c +++ b/bsp/rp2040/m_default/cdc_uart.c @@ -71,9 +71,27 @@ void cdc_uart_task(void) { } } -void cdc_uart_set_hwflow(bool enable) { uart_set_hw_flow(PINOUT_UART_INTERFACE, enable, enable); } +bool cdc_uart_set_hwflow(bool enable) { + uart_set_hw_flow(PINOUT_UART_INTERFACE, enable, enable); + return true; +} -void cdc_uart_set_baudrate(uint32_t brate) { uart_init(PINOUT_UART_INTERFACE, brate); } +uint32_t cdc_uart_set_coding(uint32_t brate, + uint8_t stop, uint8_t parity, uint8_t data) { + // tusb: parity: 0=none 1=odd 2=even 3=mark 4=space + // pîco: parity: 0=none 1=even 2=odd + int picopar = 0; + switch (parity) { + case 0: break; + case 1: picopar = 2; break; + case 2: picopar = 1; break; + default: picopar = -1; break; + } + + if (picopar >= 0) + uart_set_format(PINOUT_UART_INTERFACE, data, stop, picopar); + return uart_set_baudrate(PINOUT_UART_INTERFACE, brate); +} // idk where to put this otherwise diff --git a/src/m_default/_default.c b/src/m_default/_default.c index e329426..c67a551 100644 --- a/src/m_default/_default.c +++ b/src/m_default/_default.c @@ -24,7 +24,8 @@ enum m_default_cmds { mdef_cmd_spi = mode_cmd__specific, mdef_cmd_i2c, - mdef_cmd_tempsense + mdef_cmd_tempsense, + mdef_cmd_uart_flowcnt, }; enum m_default_feature { mdef_feat_uart = 1<<0, @@ -146,6 +147,16 @@ static void handle_cmd_cb(uint8_t cmd) { tempsense_bulk_cmd(); #else vnd_cfg_write_str(cfg_resp_illcmd, "temperature sensor not implemented on this device"); +#endif + break; + case mdef_cmd_uart_flowcnt: +#ifdef DBOARD_HAS_UART + if (cdc_uart_set_hwflow(vnd_cfg_read_byte() != 0)) + vnd_cfg_write_resp(cfg_resp_ok, 0, NULL); + else + vnd_cfg_write_str(cfg_resp_illcmd, "UART flow control setting not supported on this device"); +#else + vnd_cfg_write_str(cfg_resp_illcmd, "UART not implemented on this device"); #endif break; default: @@ -338,6 +349,27 @@ static void my_hid_set_report_cb(uint8_t instance, uint8_t report_id, } #endif +#if CFG_TUD_CDC > 0 +static void my_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding) { + switch (itf) { +#ifdef DBOARD_HAS_UART + case CDC_N_UART: + cdc_uart_set_coding(line_coding->bit_rate, line_coding->stop_bits, + line_coding->parity, line_coding->data_bits); + break; +#endif +#ifdef DBOARD_HAS_SPI + case CDC_N_SERPROG: + break; +#endif +#ifdef USE_USBCDC_FOR_STDIO + case CDC_N_STDIO: + break; +#endif + } +} +#endif + #if defined(DBOARD_HAS_I2C) && defined(MODE_ENABLE_I2CTINYUSB) static bool my_vendor_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_control_request_t const* req) { @@ -368,6 +400,10 @@ struct mode m_01_default = { .tud_hid_descriptor_report_cb = my_hid_descriptor_report_cb, #endif +#if CFG_TUD_CDC > 0 + .tud_cdc_line_coding_cb = my_cdc_line_coding_cb, +#endif + #if defined(DBOARD_HAS_I2C) && defined(MODE_ENABLE_I2CTINYUSB) .tud_vendor_control_xfer_cb = i2ctu_ctl_req, #endif diff --git a/src/m_default/cdc.h b/src/m_default/cdc.h index 17a8d7e..469e784 100644 --- a/src/m_default/cdc.h +++ b/src/m_default/cdc.h @@ -9,6 +9,9 @@ void cdc_uart_init(void); void cdc_uart_deinit(void); void cdc_uart_task(void); +bool cdc_uart_set_hwflow(bool enable); +uint32_t cdc_uart_set_coding(uint32_t brate, + uint8_t stop, uint8_t parity, uint8_t data); #endif #endif