common: Implement the receive path for the USB serial module.
[gps-watch.git] / src / common / virtual_com.c
index d9e507fbc617df4c2b330ffc3147826b5b7d21ac..faa3b67e0ac4c3a4171833e45d649c65e8363091 100644 (file)
@@ -32,8 +32,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "fsl_device_registers.h"
-#include "clock_config.h"
-#include "board.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -54,6 +52,8 @@
 #include "usb_phy.h"
 #endif
 
+#include "ringbuf.h"
+
 /* Provided by users. */
 extern void USB_DeviceClockInit(void);
 extern void USB_DeviceIsrEnable(void);
@@ -64,6 +64,12 @@ extern void USB_DeviceIsrEnable(void);
 /*******************************************************************************
 * Variables
 ******************************************************************************/
+
+static uint8_t cdc_rx_buf_space[1024];
+
+static struct ringbuf cdc_rx_buf =
+       RINGBUF_INIT (cdc_rx_buf_space, sizeof (cdc_rx_buf_space));
+
 /* Data structure of virtual com device */
 usb_cdc_vcom_struct_t s_cdcVcom;
 
@@ -154,6 +160,7 @@ usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle,
         {
             /* User: add your own code for send complete event */
             s_sendComplete = 1;
+                       USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
@@ -199,6 +206,18 @@ usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle,
     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
         USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK;
 #endif
+
+               if (s_recvSize) {
+                       for (uint32_t offset = 0; s_recvSize-- > 0; offset++) {
+                               if (ringbuf_is_full (&cdc_rx_buf))
+                                       break;
+
+                               ringbuf_write (&cdc_rx_buf, s_currRecvBuf[offset]);
+                       }
+
+                       s_recvSize = 0;
+               } else
+
         if (!s_recvSize)
         {
 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
@@ -206,6 +225,8 @@ usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle,
     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
             USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
 #endif
+
+                       USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
         }
     }
     else
@@ -540,6 +561,8 @@ usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *
                     {
                         s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
                     }
+
+                                       USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
                 }
             }
             break;
@@ -578,12 +601,10 @@ void USB_VcomWriteBlocking(usb_device_handle baseAddr, const uint8_t *buf, size_
 {
     while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
     {
-        __NOP();
     };
     USB_DeviceSendRequest((usb_device_handle)baseAddr, USB_CDC_VCOM_BULK_IN_ENDPOINT, (uint8_t *)buf, count);
     while (!s_sendComplete)
     {
-        __NOP();
     };
     s_sendComplete = 0;
 }
@@ -598,7 +619,6 @@ status_t USB_VcomReadBlocking(usb_device_handle baseAddr, uint8_t *buf, size_t c
     /* Waiting for the USB ready. */
     while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
     {
-        __NOP();
     };
 
     do
@@ -616,7 +636,6 @@ status_t USB_VcomReadBlocking(usb_device_handle baseAddr, uint8_t *buf, size_t c
         /* Waiting for data received by virtual com. */
         while (s_recvSize <= 0)
         {
-            __NOP();
         };
 
         /* When receive request is error. */
@@ -625,7 +644,6 @@ status_t USB_VcomReadBlocking(usb_device_handle baseAddr, uint8_t *buf, size_t c
             /* Waiting for the USB ready and transfer started. */
             while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
             {
-                __NOP();
             };
             s_recvSize = 0;
         }
@@ -691,3 +709,26 @@ void USB_VcomDeinit(usb_device_handle deviceHandle)
 /* enable USB IP clock,user code. */
 #endif /* USB_DEVICE_CONFIG_LPCIP3511HS */
 }
+
+void
+USB0_IRQHandler (void)
+{
+       USB_DeviceKhciIsrFunction (s_cdcVcom.deviceHandle);
+}
+
+bool usb_serial_read (char *c)
+{
+       if (ringbuf_is_empty (&cdc_rx_buf)) {
+               if (!s_recvSize || s_recvSize == (uint32_t) -1)
+                       USB_DeviceRecvRequest (s_cdcVcom.deviceHandle,
+                                              USB_CDC_VCOM_BULK_OUT_ENDPOINT,
+                                              s_currRecvBuf,
+                                              s_usbBulkMaxPacketSize);
+
+               return false;
+       }
+
+       *c = ringbuf_read (&cdc_rx_buf);
+
+       return true;
+}