Files
TX/source/USB/virtual_com.c

684 lines
24 KiB
C
Raw Normal View History

/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_class.h"
#include "usb_device_cdc_acm.h"
#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"
#include "virtual_com.h"
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
#include "fsl_sysmpu.h"
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
#include "usb_phy.h"
#endif
#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)
extern uint8_t USB_EnterLowpowerMode(void);
#endif
#include "fsl_power.h"
//Application Includes
#include "flashUpdate.h"
#include "usbComms.h"
#include "System/system.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define CR '\r' //carriage return
#define LF '\n' //line feed
#define null 0 //NULL is defined at (void *)0 so it causes errors
/*******************************************************************************
* Prototypes
******************************************************************************/
void BOARD_InitHardware(void);
void USB_DeviceClockInit(void);
void USB_DeviceIsrEnable(void);
#if USB_DEVICE_CONFIG_USE_TASK
void USB_DeviceTaskFn(void *deviceHandle);
#endif
void BOARD_DbgConsole_Deinit(void);
void BOARD_DbgConsole_Init(void);
usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param);
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param);
#if 0 //Trying to fix project after adding, then removing FLASHIAP driver. Makes no difference
extern usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length);
extern usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length);
#endif
/*******************************************************************************
* Variables
******************************************************************************/
//Application
extern USB_t usb;
extern usb_device_endpoint_struct_t g_UsbDeviceCdcVcomDicEndpoints[];
extern usb_device_class_struct_t g_UsbDeviceCdcVcomConfig;
/* Data structure of virtual com device */
usb_cdc_vcom_struct_t s_cdcVcom;
/* Line coding of cdc device */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t s_lineCoding[LINE_CODING_SIZE] = {
/* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */
(LINE_CODING_DTERATE >> 0U) & 0x000000FFU,
(LINE_CODING_DTERATE >> 8U) & 0x000000FFU,
(LINE_CODING_DTERATE >> 16U) & 0x000000FFU,
(LINE_CODING_DTERATE >> 24U) & 0x000000FFU,
LINE_CODING_CHARFORMAT,
LINE_CODING_PARITYTYPE,
LINE_CODING_DATABITS};
/* Abstract state of cdc device */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU,
(STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU};
/* Country code of cdc device */
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU,
(COUNTRY_SETTING >> 8U) & 0x00FFU};
/* CDC ACM information */
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static usb_cdc_acm_info_t s_usbCdcAcmInfo;
/* Data buffer for receiving and sending*/
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t rxBuffer[USB_BUFFER_SIZE];
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t txBuffer[USB_BUFFER_SIZE];
volatile static uint32_t rxDataSize = 0;
volatile static uint32_t txDataSize = 0;
/* USB device class information */
static usb_device_class_config_struct_t s_cdcAcmConfig[1] = {{
USB_DeviceCdcVcomCallback,
0,
&g_UsbDeviceCdcVcomConfig,
}};
/* USB device class configuration information */
static usb_device_class_config_list_struct_t s_cdcAcmConfigList = {
s_cdcAcmConfig,
USB_DeviceCallback,
1,
};
#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)
volatile static uint8_t s_waitForDataReceive = 0;
volatile static uint8_t s_comOpen = 0;
#endif
/*******************************************************************************
* Code
******************************************************************************/
void USB0_IRQHandler(void)
{
USB_DeviceLpcIp3511IsrFunction(s_cdcVcom.deviceHandle);
}
void USB_DeviceClockInit(void)
{
/* enable USB IP clock */
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcFro, CLOCK_GetFreq(kCLOCK_FroHf));
}
void USB_DeviceIsrEnable(void)
{
uint8_t irqNumber;
uint8_t usbDeviceIP3511Irq[] = USB_IRQS;
irqNumber = usbDeviceIP3511Irq[CONTROLLER_ID - kUSB_ControllerLpcIp3511Fs0];
/* Install isr, set priority, and enable IRQ. */
NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
EnableIRQ((IRQn_Type)irqNumber);
}
#if USB_DEVICE_CONFIG_USE_TASK
void USB_DeviceTaskFn(void *deviceHandle)
{
USB_DeviceLpcIp3511TaskFunction(deviceHandle);
}
#endif
/*!
* @brief CDC class specific callback function.
*
* This function handles the CDC class specific requests.
*
* @param handle The CDC ACM class handle.
* @param event The CDC ACM class event type.
* @param param The parameter of the class specific request.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param)
{
uint32_t len;
uint8_t *uartBitmap;
usb_device_cdc_acm_request_param_struct_t *acmReqParam;
usb_device_endpoint_callback_message_struct_t *epCbParam;
usb_status_t error = kStatus_USB_Error;
usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
acmReqParam = (usb_device_cdc_acm_request_param_struct_t *)param;
epCbParam = (usb_device_endpoint_callback_message_struct_t *)param;
switch (event)
{
case kUSB_DeviceCdcEventSendResponse:
{
if ((epCbParam->length != 0) && (!(epCbParam->length % g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize)))
{
/* If the last packet is the size of endpoint, then send also zero-ended packet,
** meaning that we want to inform the host that we do not have any additional
** data, so it can flush the output.
*/
error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0);
}
else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
{
if ((epCbParam->buffer != NULL) || ((epCbParam->buffer == NULL) && (epCbParam->length == 0)))
{
/* User: add your own code for send complete event */
/* Schedule buffer for next receive event */
error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer,
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
#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)
s_waitForDataReceive = 1;
USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
#endif
}
}
else
{
}
}
break;
case kUSB_DeviceCdcEventRecvResponse:
{
if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
{
rxDataSize = epCbParam->length;
#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)
s_waitForDataReceive = 0;
USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK;
#endif
if (!rxDataSize)
{
/* Schedule buffer for next receive event */
error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer,
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
#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)
s_waitForDataReceive = 1;
USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
#endif
}
}
}
break;
case kUSB_DeviceCdcEventSerialStateNotif:
((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 0;
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventSendEncapsulatedCommand:
break;
case kUSB_DeviceCdcEventGetEncapsulatedResponse:
break;
case kUSB_DeviceCdcEventSetCommFeature:
if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = s_abstractState;
}
else
{
*(acmReqParam->length) = 0;
}
}
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = s_countryCode;
}
else
{
*(acmReqParam->length) = 0;
}
}
else
{
}
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventGetCommFeature:
if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
{
*(acmReqParam->buffer) = s_abstractState;
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
}
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
{
*(acmReqParam->buffer) = s_countryCode;
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
}
else
{
}
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventClearCommFeature:
break;
case kUSB_DeviceCdcEventGetLineCoding:
*(acmReqParam->buffer) = s_lineCoding;
*(acmReqParam->length) = LINE_CODING_SIZE;
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventSetLineCoding:
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = s_lineCoding;
}
else
{
*(acmReqParam->length) = 0;
}
}
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventSetControlLineState:
{
s_usbCdcAcmInfo.dteStatus = acmReqParam->setupValue;
/* activate/deactivate Tx carrier */
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
{
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
}
else
{
acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
}
/* activate carrier and DTE. Com port of terminal tool running on PC is open now */
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
{
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
}
/* Com port of terminal tool running on PC is closed now */
else
{
acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
}
/* Indicates to DCE if DTE is present or not */
acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? 1 : 0;
/* Initialize the serial state buffer */
acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */
acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_NOTIF_SERIAL_STATE; /* bNotification */
acmInfo->serialStateBuf[2] = 0x00; /* wValue */
acmInfo->serialStateBuf[3] = 0x00;
acmInfo->serialStateBuf[4] = 0x00; /* wIndex */
acmInfo->serialStateBuf[5] = 0x00;
acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */
acmInfo->serialStateBuf[7] = 0x00;
/* Notify to host the line state */
acmInfo->serialStateBuf[4] = acmReqParam->interfaceIndex;
/* Lower byte of UART BITMAP */
uartBitmap = (uint8_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
uartBitmap[0] = acmInfo->uartState & 0xFFu;
uartBitmap[1] = (acmInfo->uartState >> 8) & 0xFFu;
len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
if (0 == ((usb_device_cdc_acm_struct_t *)handle)->hasSentState)
{
error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len);
if (kStatus_USB_Success != error)
{
//usb_echo("kUSB_DeviceCdcEventSetControlLineState error!");
}
((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 1;
}
/* Update status */
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
{
/* To do: CARRIER_ACTIVATED */
}
else
{
/* To do: CARRIER_DEACTIVATED */
}
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
{
/* DTE_ACTIVATED */
if (1 == s_cdcVcom.attach)
{
s_cdcVcom.startTransactions = 1;
#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)
s_waitForDataReceive = 1;
USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
s_comOpen = 1;
usb_echo("USB_APP_CDC_DTE_ACTIVATED\r\n");
#endif
}
}
else
{
/* DTE_DEACTIVATED */
if (1 == s_cdcVcom.attach)
{
s_cdcVcom.startTransactions = 0;
}
}
}
break;
case kUSB_DeviceCdcEventSendBreak:
break;
default:
break;
}
return error;
}
/*!
* @brief USB device callback function.
*
* This function handles the usb device specific requests.
*
* @param handle The USB device handle.
* @param event The USB device event type.
* @param param The parameter of the device specific request.
*
* @return A USB error code or kStatus_USB_Success.
*/
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_Error;
uint16_t *temp16 = (uint16_t *)param;
uint8_t *temp8 = (uint8_t *)param;
switch (event)
{
case kUSB_DeviceEventBusReset:
{
s_cdcVcom.attach = 0;
s_cdcVcom.currentConfiguration = 0U;
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
/* Get USB speed to configure the device, including max packet size and interval of the endpoints. */
if (kStatus_USB_Success == USB_DeviceClassGetSpeed(CONTROLLER_ID, &s_cdcVcom.speed))
{
USB_DeviceSetSpeed(handle, s_cdcVcom.speed);
}
#endif
}
break;
case kUSB_DeviceEventSetConfiguration:
if (0U == (*temp8))
{
s_cdcVcom.attach = 0;
s_cdcVcom.currentConfiguration = 0U;
}
else if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
{
s_cdcVcom.attach = 1;
s_cdcVcom.currentConfiguration = *temp8;
/* Schedule buffer for receive */
USB_DeviceCdcAcmRecv(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer,
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
}
else
{
error = kStatus_USB_InvalidRequest;
}
break;
case kUSB_DeviceEventSetInterface:
if (s_cdcVcom.attach)
{
uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);
uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU);
if (interface < USB_CDC_VCOM_INTERFACE_COUNT)
{
s_cdcVcom.currentInterfaceAlternateSetting[interface] = alternateSetting;
}
}
break;
case kUSB_DeviceEventGetConfiguration:
break;
case kUSB_DeviceEventGetInterface:
break;
case kUSB_DeviceEventGetDeviceDescriptor:
if (param)
{
error = USB_DeviceGetDeviceDescriptor(handle, (usb_device_get_device_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetConfigurationDescriptor:
if (param)
{
error = USB_DeviceGetConfigurationDescriptor(handle,
(usb_device_get_configuration_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetStringDescriptor:
if (param)
{
/* Get device string descriptor request */
error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param);
}
break;
default:
break;
}
return error;
}
/*!
* @brief Application initialization function.
*
* This function initializes the application.
*
* @return None.
*/
void USB_Init(void)
{
if(usb.initialized)
{
return;
}
usb.initialized = true;
USB_DeviceClockInit();
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
SYSMPU_Enable(SYSMPU, 0);
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
usb.rxDataIndex = 0;
s_cdcVcom.speed = USB_SPEED_FULL;
s_cdcVcom.attach = 0;
s_cdcVcom.cdcAcmHandle = (class_handle_t)NULL;
s_cdcVcom.deviceHandle = NULL;
if (kStatus_USB_Success != USB_DeviceClassInit(CONTROLLER_ID, &s_cdcAcmConfigList, &s_cdcVcom.deviceHandle))
{
//usb_echo("USB device init failed\r\n");
}
else
{
usb_echo("USB device CDC virtual com demo\r\n");
s_cdcVcom.cdcAcmHandle = s_cdcAcmConfigList.config->classHandle;
}
USB_DeviceIsrEnable();
/*Add one delay here to make the DP pull down long enough to allow host to detect the previous disconnection.*/
SDK_DelayAtLeastUs(5000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
USB_DeviceRun(s_cdcVcom.deviceHandle);
}
/*!
* @brief Application task function.
*
* This function runs the task for application.
*
* @return None.
*/
void USB_Update(void)
{
usb_status_t error = kStatus_USB_Error;
if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
{
/* User Code */
/* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
if ((0 != rxDataSize) && (USB_CANCELLED_TRANSFER_LENGTH != rxDataSize))
{
usb.rxDataIndex = 0;
//copy to rxDataBuffer for processing
for (int32_t i = 0; i < rxDataSize; i++)
{
usb.rxDataBuffer[usb.rxDataIndex++] = rxBuffer[i];
}
uint32_t tempDataSize = rxDataSize; //temp variable to pass to USB_ProcessData()
rxDataSize = 0;
if(usb.programMode) //ProgramMode = send data for write to FLASH
{
FU_WriteProgramDataToFLASH();
}
else
{
//Process String
USB_ProcessString(tempDataSize);
}
}
#if 0 //Transmit
if (txDataSize)
{
uint32_t size = txDataSize;
txDataSize = 0;
error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, txBuffer, size);
if (error != kStatus_USB_Success)
{
/* Failure to send Data Handling code here */
}
}
#endif
}
}
//Send data to via USB
void USB_SendString(uint8_t * str)
{
if(!s_cdcVcom.attach) //exit if USB not connected
{
return;
}
uint32_t length = strlen(str);
if(length > USB_BUFFER_SIZE - 1) //allow for LF char
{
return; //TODO: handle this better. Use a txRingbuffer
}
//copy data to txBuffer
memcpy(txBuffer, str, length);
txBuffer[length++] = CR; //append CR for realterm
txBuffer[length++] = LF; //append LF for windows
txDataSize = length;
#if 1 //Send data
//Wait for USB ready
// TODO: Need to timeout here
SYSTEM_DATA_t *sys = system_getSys();
uint32_t timeout = sys->systemTime + 100;
while(!((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions)))
{
if (sys->systemTime > timeout)
{
txDataSize = 0;
return;
}
}
uint32_t size = txDataSize;
txDataSize = 0;
usb_status_t error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, txBuffer, size);
if (error != kStatus_USB_Success)
{
/* Failure to send Data Handling code here */
usb.sendErrorCount++;
}
#endif
}
#if 0 //main function from example
int main(void)
{
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
BOARD_InitPins();
BOARD_BootClockPLL150M();
CLOCK_SetupFROClocking(96000000U); /*!< Set up high frequency FRO output to selected frequency */
BOARD_InitDebugConsole();
POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*Turn on USB Phy */
USB_Init();
while (1)
{
USB_Update();
}
}
#endif