From cf6fdbdca0e32b98074843803e5760cd6fa9fbde Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Wed, 3 Jul 2019 06:04:02 +0200 Subject: [PATCH] common: Implement the receive path for the USB serial module. This sets up a ringbuffer for data received from the USB host. When we try to read from the empty ringbuffer, another receive-data request is sent. Other modules can read from this ringbuffer via the new usb_serial_read() function. --- src/common/virtual_com.c | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/common/virtual_com.c b/src/common/virtual_com.c index abf0a32..faa3b67 100644 --- a/src/common/virtual_com.c +++ b/src/common/virtual_com.c @@ -52,6 +52,8 @@ #include "usb_phy.h" #endif +#include "ringbuf.h" + /* Provided by users. */ extern void USB_DeviceClockInit(void); extern void USB_DeviceIsrEnable(void); @@ -62,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; @@ -152,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) @@ -197,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) && \ @@ -204,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 @@ -538,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; @@ -690,3 +715,20 @@ 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; +} -- 2.30.2