From 5e6c43a884b780e6f6b4bee5ded8e8d391b3bc94 Mon Sep 17 00:00:00 2001 From: Manuel Odendahl Date: Thu, 17 Jan 2013 17:40:50 +0100 Subject: Move endpoint definitions to include files (they are now needed outside in usb_serial.cpp) Signed-off-by: Manuel Odendahl --- libmaple/include/libmaple/usb_cdcacm.h | 21 +++++++++++++++++++++ libmaple/usb/stm32f1/usb_cdcacm.c | 21 --------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/libmaple/include/libmaple/usb_cdcacm.h b/libmaple/include/libmaple/usb_cdcacm.h index 8b3c1fe..5a2779e 100644 --- a/libmaple/include/libmaple/usb_cdcacm.h +++ b/libmaple/include/libmaple/usb_cdcacm.h @@ -72,6 +72,27 @@ extern "C" { #define USB_INTERFACE_SUBCLASS_CDC_ACM 0x02 #define USB_INTERFACE_CLASS_DIC 0x0A +/* + * Endpoint configuration + */ + +#define USB_CDCACM_CTRL_ENDP 0 +#define USB_CDCACM_CTRL_RX_ADDR 0x40 +#define USB_CDCACM_CTRL_TX_ADDR 0x80 +#define USB_CDCACM_CTRL_EPSIZE 0x40 + +#define USB_CDCACM_TX_ENDP 1 +#define USB_CDCACM_TX_ADDR 0xC0 +#define USB_CDCACM_TX_EPSIZE 0x40 + +#define USB_CDCACM_MANAGEMENT_ENDP 2 +#define USB_CDCACM_MANAGEMENT_ADDR 0x100 +#define USB_CDCACM_MANAGEMENT_EPSIZE 0x40 + +#define USB_CDCACM_RX_ENDP 3 +#define USB_CDCACM_RX_ADDR 0x110 +#define USB_CDCACM_RX_EPSIZE 0x40 + #ifndef __cplusplus #define USB_CDCACM_DECLARE_DEV_DESC(vid, pid) \ { \ diff --git a/libmaple/usb/stm32f1/usb_cdcacm.c b/libmaple/usb/stm32f1/usb_cdcacm.c index addab3c..cdcba9c 100644 --- a/libmaple/usb/stm32f1/usb_cdcacm.c +++ b/libmaple/usb/stm32f1/usb_cdcacm.c @@ -81,27 +81,6 @@ static uint8* usbGetStringDescriptor(uint16 length); static void usbSetConfiguration(void); static void usbSetDeviceAddress(void); -/* - * Endpoint configuration - */ - -#define USB_CDCACM_CTRL_ENDP 0 -#define USB_CDCACM_CTRL_RX_ADDR 0x40 -#define USB_CDCACM_CTRL_TX_ADDR 0x80 -#define USB_CDCACM_CTRL_EPSIZE 0x40 - -#define USB_CDCACM_TX_ENDP 1 -#define USB_CDCACM_TX_ADDR 0xC0 -#define USB_CDCACM_TX_EPSIZE 0x40 - -#define USB_CDCACM_MANAGEMENT_ENDP 2 -#define USB_CDCACM_MANAGEMENT_ADDR 0x100 -#define USB_CDCACM_MANAGEMENT_EPSIZE 0x40 - -#define USB_CDCACM_RX_ENDP 3 -#define USB_CDCACM_RX_ADDR 0x110 -#define USB_CDCACM_RX_EPSIZE 0x40 - /* * Descriptors */ -- cgit v1.2.3 From b1389732c350b2dcc4c158a149dcdc038a4b6537 Mon Sep 17 00:00:00 2001 From: Manuel Odendahl Date: Thu, 17 Jan 2013 17:41:02 +0100 Subject: Handle sending 0 byte packets. Added a flag to see if we are currently waiting on an interrupt to acknowledge the sending of the current IN packet. Added a method usb_cdcacm_is_transmitting() to check for that flag. Signed-off-by: Manuel Odendahl --- libmaple/include/libmaple/usb_cdcacm.h | 1 + libmaple/usb/stm32f1/usb_cdcacm.c | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/libmaple/include/libmaple/usb_cdcacm.h b/libmaple/include/libmaple/usb_cdcacm.h index 5a2779e..5fe832c 100644 --- a/libmaple/include/libmaple/usb_cdcacm.h +++ b/libmaple/include/libmaple/usb_cdcacm.h @@ -127,6 +127,7 @@ uint32 usb_cdcacm_peek(uint8* buf, uint32 len); uint32 usb_cdcacm_data_available(void); /* in RX buffer */ uint16 usb_cdcacm_get_pending(void); +uint8 usb_cdcacm_is_transmitting(void); uint8 usb_cdcacm_get_dtr(void); uint8 usb_cdcacm_get_rts(void); diff --git a/libmaple/usb/stm32f1/usb_cdcacm.c b/libmaple/usb/stm32f1/usb_cdcacm.c index cdcba9c..3f3a493 100644 --- a/libmaple/usb/stm32f1/usb_cdcacm.c +++ b/libmaple/usb/stm32f1/usb_cdcacm.c @@ -267,6 +267,8 @@ static volatile uint8 vcomBufferRx[USB_CDCACM_RX_EPSIZE]; static volatile uint32 rx_offset = 0; /* Number of bytes left to transmit */ static volatile uint32 n_unsent_bytes = 0; +/* Are we currently sending an IN packet? */ +static volatile uint8 transmitting = 0; /* Number of unread bytes */ static volatile uint32 n_unread_bytes = 0; @@ -407,6 +409,13 @@ uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) { usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, len); n_unsent_bytes = len; usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID); + transmitting = 1; + } else { + usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, 0); + usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID); + // actually block here waiting for interrupt, even though we sent 0 bytes + n_unsent_bytes = 0; + transmitting = 1; } return len; @@ -416,7 +425,11 @@ uint32 usb_cdcacm_data_available(void) { return n_unread_bytes; } -uint16 usb_cdcacm_get_pending() { +uint8 usb_cdcacm_is_transmitting(void) { + return transmitting; +} + +uint16 usb_cdcacm_get_pending(void) { return n_unsent_bytes; } @@ -497,12 +510,8 @@ int usb_cdcacm_get_n_data_bits(void) { */ static void vcomDataTxCb(void) { - /* The following assumes that all of the bytes we copied during - * the last call to usb_cdcacm_tx were sent during the IN - * transaction (this seems to be the case). */ - /* TODO find out why this is broken: - * n_unsent_bytes = usb_get_ep_tx_count(USB_CDCACM_TX_ENDP); */ n_unsent_bytes = 0; + transmitting = 0; } static void vcomDataRxCb(void) { -- cgit v1.2.3 From 419a6796c2d444762e2ae5b7ae8b846690add839 Mon Sep 17 00:00:00 2001 From: Manuel Odendahl Date: Thu, 17 Jan 2013 17:42:41 +0100 Subject: Check if the last packet sent was the full endpoint size, in this case flush the host buffers by sending a 0 byte packet Signed-off-by: Manuel Odendahl --- wirish/usb_serial.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/wirish/usb_serial.cpp b/wirish/usb_serial.cpp index 380f197..d21766f 100644 --- a/wirish/usb_serial.cpp +++ b/wirish/usb_serial.cpp @@ -92,13 +92,24 @@ void USBSerial::write(const void *buf, uint32 len) { uint32 old_txed = 0; uint32 start = millis(); + uint32 sent = 0; + while (txed < len && (millis() - start < USB_TIMEOUT)) { - txed += usb_cdcacm_tx((const uint8*)buf + txed, len - txed); + sent = usb_cdcacm_tx((const uint8*)buf + txed, len - txed); + txed += sent; if (old_txed != txed) { start = millis(); } old_txed = txed; } + + + if (sent == USB_CDCACM_TX_EPSIZE) { + while (usb_cdcacm_is_transmitting() != 0) { + } + /* flush out to avoid having the pc wait for more data */ + usb_cdcacm_tx(NULL, 0); + } } uint32 USBSerial::available(void) { -- cgit v1.2.3 From afb4199070e464c317b86741e107692120e05097 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Thu, 17 Jan 2013 18:08:39 -0500 Subject: usb_cdcacm.c: Fixups for usb_cdcacm_tx(). - Check if we're transmitting (instead of how many bytes are left untransmitted) before bailing, in case we're transmitting a zero-length packet. - Set transmitting=1 before setting the endpoint valid to avoid races with the USB interrupt. - Eliminate some duplicated code. Signed-off-by: Marti Bolivar --- libmaple/usb/stm32f1/usb_cdcacm.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/libmaple/usb/stm32f1/usb_cdcacm.c b/libmaple/usb/stm32f1/usb_cdcacm.c index 3f3a493..ecb9397 100644 --- a/libmaple/usb/stm32f1/usb_cdcacm.c +++ b/libmaple/usb/stm32f1/usb_cdcacm.c @@ -394,7 +394,7 @@ void usb_cdcacm_putc(char ch) { * buffer, and returns the number of bytes copied. */ uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) { /* Last transmission hasn't finished, so abort. */ - if (n_unsent_bytes) { + if (usb_cdcacm_is_transmitting()) { return 0; } @@ -406,17 +406,14 @@ uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) { /* Queue bytes for sending. */ if (len) { usb_copy_to_pma(buf, len, USB_CDCACM_TX_ADDR); - usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, len); - n_unsent_bytes = len; - usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID); - transmitting = 1; - } else { - usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, 0); - usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID); - // actually block here waiting for interrupt, even though we sent 0 bytes - n_unsent_bytes = 0; - transmitting = 1; } + // We still need to wait for the interrupt, even if we're sending + // zero bytes. (Sending zero-size packets is useful for flushing + // host-side buffers.) + usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, len); + n_unsent_bytes = len; + transmitting = 1; + usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID); return len; } -- cgit v1.2.3