common: Implement the transmit path for the USB serial module.
authorTilman Sauerbeck <tilman@code-monkey.de>
Wed, 3 Jul 2019 05:17:16 +0000 (07:17 +0200)
committerTilman Sauerbeck <tilman@code-monkey.de>
Sun, 5 Jan 2020 19:38:11 +0000 (20:38 +0100)
This adds the global variable cdc_tx_buf, which buffers data
to be written to USB.

src/common/virtual_com.c

index faa3b67e0ac4c3a4171833e45d649c65e8363091..933b8fd08a95b78872d1f8ab1d4bb2bf09e8041b 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdalign.h>
 
 #include "usb_device_config.h"
 #include "usb.h"
@@ -53,6 +54,7 @@
 #endif
 
 #include "ringbuf.h"
+#include "buffer.h"
 
 /* Provided by users. */
 extern void USB_DeviceClockInit(void);
@@ -66,10 +68,13 @@ extern void USB_DeviceIsrEnable(void);
 ******************************************************************************/
 
 static uint8_t cdc_rx_buf_space[1024];
+static uint8_t cdc_tx_buf_space[1024] alignas(4);
 
 static struct ringbuf cdc_rx_buf =
        RINGBUF_INIT (cdc_rx_buf_space, sizeof (cdc_rx_buf_space));
 
+struct buffer cdc_tx_buf;
+
 /* Data structure of virtual com device */
 usb_cdc_vcom_struct_t s_cdcVcom;
 
@@ -609,6 +614,29 @@ void USB_VcomWriteBlocking(usb_device_handle baseAddr, const uint8_t *buf, size_
     s_sendComplete = 0;
 }
 
+static ssize_t
+flush_tx_buffer (void *user_data, void *vbuf, size_t bufsiz, size_t count)
+{
+       (void) bufsiz;
+
+       /* Don't write data unless link is open. */
+       if (s_cdcVcom.attach != 1 || s_cdcVcom.startTransactions != 1)
+               return count;
+
+       USB_DeviceSendRequest (user_data, USB_CDC_VCOM_BULK_IN_ENDPOINT,
+                              vbuf, count);
+
+       /* Wait for USB_DeviceCdcAcmBulkIn() to set s_sendComplete. */
+       while (!s_sendComplete)
+       {
+       }
+
+       /* Reset for the next write. */
+       s_sendComplete = 0;
+
+       return count;
+}
+
 /* See virtual_com.h for documentation of this function. */
 status_t USB_VcomReadBlocking(usb_device_handle baseAddr, uint8_t *buf, size_t count)
 {
@@ -682,6 +710,10 @@ usb_device_handle USB_VcomInit(void)
     else
     {
         deviceHandle = s_cdcVcom.deviceHandle;
+
+               buffer_init (&cdc_tx_buf, cdc_tx_buf_space, sizeof (cdc_tx_buf_space),
+                            flush_tx_buffer, deviceHandle);
+
         USB_DeviceIsrEnable();
         USB_DeviceRun(s_cdcVcom.deviceHandle);
     }