#include <stdio.h>
#include <stdlib.h>
+#include <stdalign.h>
#include "usb_device_config.h"
#include "usb.h"
#include "usb_phy.h"
#endif
+#include "ringbuf.h"
+#include "buffer.h"
+
/* Provided by users. */
extern void USB_DeviceClockInit(void);
extern void USB_DeviceIsrEnable(void);
+extern void USB_DeviceIsrDisable(void);
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
+
+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;
/* Data buffer for receiving and sending*/
static uint8_t s_currRecvBuf[DATA_BUFF_SIZE];
-volatile static uint32_t s_recvSize = 0;
-volatile static uint32_t s_sendSize = 0;
-volatile static uint8_t s_sendComplete = 0;
-volatile static uint8_t s_currRecvIndex = 0;
+static volatile uint32_t s_recvSize = 0;
+static volatile uint8_t s_sendComplete = 0;
static uint32_t s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
/*******************************************************************************
* Prototypes
{
/* 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)
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) && \
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
{
s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
}
+
+ USB_DeviceRecvRequest (handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize);
}
}
break;
}
}
-/* See virtual_com.h for documentation of this function. */
-void USB_VcomWriteBlocking(usb_device_handle baseAddr, const uint8_t *buf, size_t count)
+static ssize_t
+flush_tx_buffer (void *user_data, void *vbuf, size_t bufsiz, size_t count)
{
- while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
- {
- };
- USB_DeviceSendRequest((usb_device_handle)baseAddr, USB_CDC_VCOM_BULK_IN_ENDPOINT, (uint8_t *)buf, count);
- while (!s_sendComplete)
- {
- };
- s_sendComplete = 0;
-}
+ (void) bufsiz;
-/* See virtual_com.h for documentation of this function. */
-status_t USB_VcomReadBlocking(usb_device_handle baseAddr, uint8_t *buf, size_t count)
-{
- status_t error = kStatus_Success;
- size_t bufIndex = 0U, bytesToReceive = 0U;
- assert(count != 0U);
+ /* Don't write data unless link is open. */
+ if (s_cdcVcom.attach != 1 || s_cdcVcom.startTransactions != 1)
+ return count;
- /* Waiting for the USB ready. */
- while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
- {
- };
+ USB_DeviceSendRequest (user_data, USB_CDC_VCOM_BULK_IN_ENDPOINT,
+ vbuf, count);
- do
- {
- /* If no receive request. */
- if (s_recvSize <= 0)
- {
- if (kStatus_USB_Success !=
- USB_DeviceRecvRequest(baseAddr, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize))
- {
- return kStatus_Fail;
- }
- s_currRecvIndex = 0;
- }
- /* Waiting for data received by virtual com. */
- while (s_recvSize <= 0)
- {
- };
+ /* Wait for USB_DeviceCdcAcmBulkIn() to set s_sendComplete. */
+ while (!s_sendComplete)
+ {
+ }
- /* When receive request is error. */
- if (0xFFFFFFFFU == s_recvSize)
- {
- /* Waiting for the USB ready and transfer started. */
- while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
- {
- };
- s_recvSize = 0;
- }
- else
- {
- bytesToReceive = MIN(count, s_recvSize);
- memcpy((void *)&buf[bufIndex], s_currRecvBuf + s_currRecvIndex, bytesToReceive);
- count -= bytesToReceive;
- s_recvSize -= bytesToReceive;
- bufIndex += bytesToReceive;
- s_currRecvIndex += bytesToReceive;
- }
- } while (0U != count);
- return error;
+ /* Reset for the next write. */
+ s_sendComplete = 0;
+
+ return count;
}
/* See virtual_com.h for documentation of this function. */
-usb_device_handle USB_VcomInit(void)
+usb_device_handle
+USB_VcomInit (uint16_t vid, uint16_t pid)
{
usb_device_handle deviceHandle = NULL;
s_cdcVcom.attach = 0;
s_cdcVcom.deviceHandle = NULL;
+ USB_DeviceSetVendorId(vid);
+ USB_DeviceSetProductId(pid);
+
if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &s_cdcVcom.deviceHandle))
{
deviceHandle = NULL;
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);
}
}
/* See virtual_com.h for documentation of this function. */
-void USB_VcomDeinit(usb_device_handle deviceHandle)
+void
+USB_VcomDeinit (void)
{
- USB_DeviceStop(deviceHandle);
- USB_DeviceDeinit(deviceHandle);
+ if (s_cdcVcom.deviceHandle == NULL)
+ return;
+
+ USB_DeviceStop (s_cdcVcom.deviceHandle);
+ USB_DeviceDeinit (s_cdcVcom.deviceHandle);
s_cdcVcom.deviceHandle = NULL;
-#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
- USB_EhciPhyDeinit(CONTROLLER_ID);
-#endif
-#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
- CLOCK_DisableUsbfs0Clock();
-#endif
-#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
- /* enable USB IP clock, user code. */
- CLOCK_DisableClock(kCLOCK_Usbd0);
-#endif /* USB_DEVICE_CONFIG_LPCIP3511FS */
-
-#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
-/* enable USB IP clock,user code. */
-#endif /* USB_DEVICE_CONFIG_LPCIP3511HS */
+
+ USB_DeviceIsrDisable();
+
+ /* XXX: We are not stopping the USBOTG clock yet. */
}
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;
+}