diff options
Diffstat (limited to 'src/class/cdc')
| -rw-r--r-- | src/class/cdc/cdc_device.c | 154 | ||||
| -rw-r--r-- | src/class/cdc/cdc_device.h | 25 | ||||
| -rw-r--r-- | src/class/cdc/cdc_host.c | 62 | ||||
| -rw-r--r-- | src/class/cdc/cdc_host.h | 11 |
4 files changed, 152 insertions, 100 deletions
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index ebc408f5a..4d19adeb4 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -67,22 +67,27 @@ typedef struct { OSAL_MUTEX_DEF(rx_ff_mutex); OSAL_MUTEX_DEF(tx_ff_mutex); - - // Endpoint Transfer buffer - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE]; } cdcd_interface_t; #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char) +typedef struct { + TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE); +} cdcd_epbuf_t; + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; +static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { - uint8_t const rhport = 0; +static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); + +static bool _prep_out_transaction(uint8_t itf) { + const uint8_t rhport = 0; + cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; // Skip if usb is not ready yet TU_VERIFY(tud_ready() && p_cdc->ep_out); @@ -93,7 +98,7 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { // TODO Actually we can still carry out the transfer, keeping count of received bytes // and slowly move it to the FIFO when read(). // This pre-check reduces endpoint claiming - TU_VERIFY(available >= sizeof(p_cdc->epout_buf)); + TU_VERIFY(available >= CFG_TUD_CDC_EP_BUFSIZE); // claim endpoint TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_out)); @@ -101,9 +106,9 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { // fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&p_cdc->rx_ff); - if ( available >= sizeof(p_cdc->epout_buf) ) { - return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf)); - }else { + if (available >= CFG_TUD_CDC_EP_BUFSIZE) { + return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); + } else { // Release endpoint since we don't make any transfer usbd_edpt_release(rhport, p_cdc->ep_out); return false; @@ -114,9 +119,9 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { // APPLICATION API //--------------------------------------------------------------------+ -bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg) { - TU_VERIFY(cfg); - _cdcd_fifo_cfg = (*cfg); +bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg) { + TU_VERIFY(driver_cfg); + _cdcd_cfg = *driver_cfg; return true; } @@ -151,7 +156,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(p_cdc); + _prep_out_transaction(itf); return num_read; } @@ -162,15 +167,15 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(p_cdc); + _prep_out_transaction(itf); } //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ -uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { +uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); + uint16_t wr_count = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); // flush if queue more than packet size if (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE @@ -181,28 +186,31 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { tud_cdc_n_write_flush(itf); } - return ret; + return wr_count; } uint32_t tud_cdc_n_write_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; // Skip if usb is not ready yet TU_VERIFY(tud_ready(), 0); // No data to send - if (!tu_fifo_count(&p_cdc->tx_ff)) return 0; + if (!tu_fifo_count(&p_cdc->tx_ff)) { + return 0; + } - uint8_t const rhport = 0; + const uint8_t rhport = 0; // Claim the endpoint TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_in), 0); // Pull data from FIFO - uint16_t const count = tu_fifo_read_n(&p_cdc->tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf)); + const uint16_t count = tu_fifo_read_n(&p_cdc->tx_ff, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); if (count) { - TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0); + TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, p_epbuf->epin, count), 0); return count; } else { // Release endpoint since we don't make any transfer @@ -225,8 +233,6 @@ bool tud_cdc_n_write_clear(uint8_t itf) { //--------------------------------------------------------------------+ void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); - tu_memclr(&_cdcd_fifo_cfg, sizeof(_cdcd_fifo_cfg)); - for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; @@ -241,10 +247,10 @@ void cdcd_init(void) { // Config RX fifo tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, TU_ARRAY_SIZE(p_cdc->rx_ff_buf), 1, false); - // Config TX fifo as overwritable at initialization and will be changed to non-overwritable - // if terminal supports DTR bit. Without DTR we do not know if data is actually polled by terminal. - // In this way, the most current data is prioritized. - tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true); + // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not + // know if data is actually polled by terminal. This way the most current data is prioritized. + // Default: is overwritable + tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, _cdcd_cfg.tx_overwritabe_if_not_connected); #if OSAL_MUTEX_REQUIRED osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex); @@ -286,32 +292,37 @@ void cdcd_reset(uint8_t rhport) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); - if (!_cdcd_fifo_cfg.rx_persistent) tu_fifo_clear(&p_cdc->rx_ff); - if (!_cdcd_fifo_cfg.tx_persistent) tu_fifo_clear(&p_cdc->tx_ff); - tu_fifo_set_overwritable(&p_cdc->tx_ff, true); + if (!_cdcd_cfg.rx_persistent) { + tu_fifo_clear(&p_cdc->rx_ff); + } + if (!_cdcd_cfg.tx_persistent) { + tu_fifo_clear(&p_cdc->tx_ff); + } + tu_fifo_set_overwritable(&p_cdc->tx_ff, _cdcd_cfg.tx_overwritabe_if_not_connected); } } -uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { +uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16_t max_len) { // Only support ACM subclass TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); // Find available interface - cdcd_interface_t* p_cdc = NULL; - for (uint8_t cdc_id = 0; cdc_id < CFG_TUD_CDC; cdc_id++) { - if (_cdcd_itf[cdc_id].ep_in == 0) { - p_cdc = &_cdcd_itf[cdc_id]; + cdcd_interface_t* p_cdc; + uint8_t cdc_id; + for (cdc_id = 0; cdc_id < CFG_TUD_CDC; cdc_id++) { + p_cdc = &_cdcd_itf[cdc_id]; + if (p_cdc->ep_in == 0) { break; } } - TU_ASSERT(p_cdc, 0); + TU_ASSERT(cdc_id < CFG_TUD_CDC, 0); //------------- Control Interface -------------// p_cdc->itf_num = itf_desc->bInterfaceNumber; uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const* p_desc = tu_desc_next(itf_desc); + const uint8_t* p_desc = tu_desc_next(itf_desc); // Communication Functional Descriptors while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { @@ -321,7 +332,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { // notification endpoint - tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc; + const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; @@ -332,7 +343,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 //------------- Data Interface (if any) -------------// if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const*) p_desc)->bInterfaceClass)) { + (TUSB_CLASS_CDC_DATA == ((const tusb_desc_interface_t*) p_desc)->bInterfaceClass)) { // next to endpoint descriptor drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); @@ -344,7 +355,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 } // Prepare for incoming data - _prep_out_transaction(p_cdc); + _prep_out_transaction(cdc_id); return drv_len; } @@ -352,19 +363,21 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { +bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) { // Handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); - uint8_t itf = 0; - cdcd_interface_t* p_cdc = _cdcd_itf; + uint8_t itf; + cdcd_interface_t* p_cdc; // Identify which interface to use - for (;; itf++, p_cdc++) { - if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false; - - if (p_cdc->itf_num == request->wIndex) break; + for (itf = 0; itf < CFG_TUD_CDC; itf++) { + p_cdc = &_cdcd_itf[itf]; + if (p_cdc->itf_num == request->wIndex) { + break; + } } + TU_VERIFY(itf < CFG_TUD_CDC); switch (request->bRequest) { case CDC_REQUEST_SET_LINE_CODING: @@ -372,7 +385,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_LOG_DRV(" Set Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } else if (stage == CONTROL_STAGE_ACK) { - if (tud_cdc_line_coding_cb) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); + if (tud_cdc_line_coding_cb) { + tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); + } } break; @@ -397,13 +412,19 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t p_cdc->line_state = (uint8_t) request->wValue; - // Disable fifo overwriting if DTR bit is set - tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr); + // If enabled: fifo overwriting is disabled if DTR bit is set and vice versa + if (_cdcd_cfg.tx_overwritabe_if_not_connected) { + tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr); + } else { + tu_fifo_set_overwritable(&p_cdc->tx_ff, false); + } TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); // Invoke callback - if (tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, dtr, rts); + if (tud_cdc_line_state_cb) { + tud_cdc_line_state_cb(itf, dtr, rts); + } } break; @@ -412,7 +433,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t tud_control_status(rhport, request); } else if (stage == CONTROL_STAGE_ACK) { TU_LOG_DRV(" Send Break\r\n"); - if (tud_cdc_send_break_cb) tud_cdc_send_break_cb(itf, request->wValue); + if (tud_cdc_send_break_cb) { + tud_cdc_send_break_cb(itf, request->wValue); + } } break; @@ -432,28 +455,33 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Identify which interface to use for (itf = 0; itf < CFG_TUD_CDC; itf++) { p_cdc = &_cdcd_itf[itf]; - if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in)) break; + if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in)) { + break; + } } TU_ASSERT(itf < CFG_TUD_CDC); + cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; // Received new data if (ep_addr == p_cdc->ep_out) { - tu_fifo_write_n(&p_cdc->rx_ff, p_cdc->epout_buf, (uint16_t) xferred_bytes); + tu_fifo_write_n(&p_cdc->rx_ff, p_epbuf->epout, (uint16_t) xferred_bytes); // Check for wanted char and invoke callback if needed if (tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1)) { for (uint32_t i = 0; i < xferred_bytes; i++) { - if ((p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { + if ((p_cdc->wanted_char == p_epbuf->epout[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } } // invoke receive callback (if there is still data) - if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); + if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) { + tud_cdc_rx_cb(itf); + } // prepare for OUT transaction - _prep_out_transaction(p_cdc); + _prep_out_transaction(itf); } // Data sent to host, we continue to fetch from tx fifo to send. @@ -461,14 +489,16 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Though maybe the baudrate is not really important !!! if (ep_addr == p_cdc->ep_in) { // invoke transmit callback to possibly refill tx fifo - if (tud_cdc_tx_complete_cb) tud_cdc_tx_complete_cb(itf); + if (tud_cdc_tx_complete_cb) { + tud_cdc_tx_complete_cb(itf); + } if (0 == tud_cdc_n_write_flush(itf)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP Packet size and not zero if (!tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { - usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0); + TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0)); } } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 3ad7c8baf..b653ebd74 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -48,14 +48,24 @@ //--------------------------------------------------------------------+ // Driver Configuration //--------------------------------------------------------------------+ - typedef struct TU_ATTR_PACKED { - uint8_t rx_persistent : 1; // keep rx fifo on bus reset or disconnect - uint8_t tx_persistent : 1; // keep tx fifo on bus reset or disconnect -} tud_cdc_configure_fifo_t; + uint8_t rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect + uint8_t tx_persistent : 1; // keep tx fifo data even with reset or disconnect + uint8_t tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten +} tud_cdc_configure_t; + +#define TUD_CDC_CONFIGURE_DEFAULT() { \ + .rx_persistent = 0, \ + .tx_persistent = 0, \ + .tx_overwritabe_if_not_connected = 1, \ +} + +// Configure CDC driver behavior +bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg); -// Configure CDC FIFOs behavior -bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); +// Backward compatible +#define tud_cdc_configure_fifo_t tud_cdc_configure_t +#define tud_cdc_configure_fifo tud_cdc_configure //--------------------------------------------------------------------+ // Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 @@ -204,6 +214,9 @@ TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); // Invoked when received send break +// \param[in] itf interface for which send break was received. +// \param[in] duration_ms the length of time, in milliseconds, of the break signal. If a value of FFFFh, then the +// device will send a break until another SendBreak request is received with value 0000h. TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 133a10f6e..4058857c5 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -73,15 +73,17 @@ typedef struct { tu_edpt_stream_t rx; uint8_t tx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; - CFG_TUH_MEM_ALIGN uint8_t tx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; - uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; - CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; } cdch_interface_t; -CFG_TUH_MEM_SECTION +typedef struct { + TUH_EPBUF_DEF(tx, CFG_TUH_CDC_TX_EPSIZE); + TUH_EPBUF_DEF(rx, CFG_TUH_CDC_TX_EPSIZE); +} cdch_epbuf_t; + static cdch_interface_t cdch_data[CFG_TUH_CDC]; +CFG_TUH_MEM_SECTION static cdch_epbuf_t cdch_epbuf[CFG_TUH_CDC]; //--------------------------------------------------------------------+ // Serial Driver @@ -341,14 +343,14 @@ uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize); + return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize); } uint32_t tuh_cdc_write_flush(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); } bool tuh_cdc_write_clear(uint8_t idx) { @@ -362,7 +364,7 @@ uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_available(&p_cdc->stream.tx); + return tu_edpt_stream_write_available(p_cdc->daddr, &p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -373,7 +375,7 @@ uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize); } uint32_t tuh_cdc_read_available(uint8_t idx) { @@ -395,7 +397,7 @@ bool tuh_cdc_read_clear (uint8_t idx) { TU_VERIFY(p_cdc); bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx); - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); return ret; } @@ -626,13 +628,14 @@ bool cdch_init(void) { tu_memclr(cdch_data, sizeof(cdch_data)); for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t* p_cdc = &cdch_data[i]; + cdch_epbuf_t* epbuf = &cdch_epbuf[i]; tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + epbuf->tx, CFG_TUH_CDC_TX_EPSIZE); tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); + epbuf->rx, CFG_TUH_CDC_RX_EPSIZE); } return true; @@ -654,7 +657,9 @@ void cdch_close(uint8_t daddr) { TU_LOG_DRV(" CDCh close addr = %u index = %u\r\n", daddr, idx); // Invoke application callback - if (tuh_cdc_umount_cb) tuh_cdc_umount_cb(idx); + if (tuh_cdc_umount_cb) { + tuh_cdc_umount_cb(idx); + } p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; @@ -675,19 +680,21 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if ( ep_addr == p_cdc->stream.tx.ep_addr ) { // invoke tx complete callback to possibly refill tx fifo - if (tuh_cdc_tx_complete_cb) tuh_cdc_tx_complete_cb(idx); + if (tuh_cdc_tx_complete_cb) { + tuh_cdc_tx_complete_cb(idx); + } - if ( 0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx) ) { + if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) { // If there is no data left, a ZLP should be sent if: // - xferred_bytes is multiple of EP Packet size and not zero - tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); } } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { #if CFG_TUH_CDC_FTDI - if (p_cdc->serial_drid == SERIAL_DRIVER_FTDI) { + if (p_cdc->serial_drid == SERIAL_DRIVER_FTDI && xferred_bytes > 2) { // FTDI reserve 2 bytes for status // uint8_t status[2] = {p_cdc->stream.rx.ep_buf[0], p_cdc->stream.rx.ep_buf[1]}; - tu_edpt_stream_read_xfer_complete_offset(&p_cdc->stream.rx, xferred_bytes, 2); + tu_edpt_stream_read_xfer_complete_with_buf(&p_cdc->stream.rx, p_cdc->stream.rx.ep_buf+2, xferred_bytes-2); }else #endif { @@ -695,10 +702,12 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } // invoke receive callback - if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(idx); + if (tuh_cdc_rx_cb) { + tuh_cdc_rx_cb(idx); + } // prepare for next transfer if needed - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); }else if ( ep_addr == p_cdc->ep_notif ) { // TODO handle notification endpoint }else { @@ -719,9 +728,9 @@ static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t co TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_cdc->stream.rx, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(&p_cdc->stream.rx, desc_ep); } else { - tu_edpt_stream_open(&p_cdc->stream.tx, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(&p_cdc->stream.tx, desc_ep); } desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(desc_ep); @@ -738,9 +747,8 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d if (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) { return acm_open(daddr, itf_desc, max_len); - } - else if (SERIAL_DRIVER_COUNT > 1 && - TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { + } else if (SERIAL_DRIVER_COUNT > 1 && + TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { uint16_t vid, pid; TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid)); @@ -760,10 +768,12 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t itf_num) { TU_LOG_DRV("CDCh Set Configure complete\r\n"); p_cdc->mounted = true; - if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); + if (tuh_cdc_mount_cb) { + tuh_cdc_mount_cb(idx); + } // Prepare for incoming data - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); // notify usbh that driver enumeration is complete usbh_driver_set_config_complete(p_cdc->daddr, itf_num); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index b63dd1530..8c5399534 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -49,22 +49,22 @@ // RX FIFO size #ifndef CFG_TUH_CDC_RX_BUFSIZE -#define CFG_TUH_CDC_RX_BUFSIZE USBH_EPSIZE_BULK_MAX +#define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MPS #endif // RX Endpoint size #ifndef CFG_TUH_CDC_RX_EPSIZE -#define CFG_TUH_CDC_RX_EPSIZE USBH_EPSIZE_BULK_MAX +#define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MPS #endif // TX FIFO size #ifndef CFG_TUH_CDC_TX_BUFSIZE -#define CFG_TUH_CDC_TX_BUFSIZE USBH_EPSIZE_BULK_MAX +#define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MPS #endif // TX Endpoint size #ifndef CFG_TUH_CDC_TX_EPSIZE -#define CFG_TUH_CDC_TX_EPSIZE USBH_EPSIZE_BULK_MAX +#define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MPS #endif //--------------------------------------------------------------------+ @@ -89,8 +89,7 @@ bool tuh_cdc_get_dtr(uint8_t idx); bool tuh_cdc_get_rts(uint8_t idx); // Check if interface is connected (DTR active) -TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) { return tuh_cdc_get_dtr(idx); } |
