X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fcommon%2Fvirtual_com.c;h=cc388c704778aa037805d3fb01ffd56428a7f6e9;hb=d41f27c211ac96151e175c4241b6a8d866001bea;hp=abf0a322e9b3625251b7d4e078c986ca217b81f8;hpb=2cc01363b3fbb2e6b9c993aec1ad11c7f340cbf9;p=gps-watch.git diff --git a/src/common/virtual_com.c b/src/common/virtual_com.c index abf0a32..cc388c7 100644 --- a/src/common/virtual_com.c +++ b/src/common/virtual_com.c @@ -35,6 +35,7 @@ #include #include +#include #include "usb_device_config.h" #include "usb.h" @@ -52,9 +53,13 @@ #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 ******************************************************************************/ @@ -62,6 +67,15 @@ extern void USB_DeviceIsrEnable(void); /******************************************************************************* * 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; @@ -89,10 +103,8 @@ static usb_cdc_acm_info_t s_usbCdcAcmInfo = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, /* 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 @@ -152,6 +164,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 +210,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 +229,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 +565,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; @@ -571,72 +600,32 @@ usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t } } -/* 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; @@ -650,6 +639,9 @@ usb_device_handle USB_VcomInit(void) 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; @@ -657,6 +649,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); } @@ -664,25 +660,19 @@ usb_device_handle USB_VcomInit(void) } /* 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 @@ -690,3 +680,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; +}