/* * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. * Copyright 2016 - 2017 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #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" /******************************************************************************* * 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 while(!((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))); //TODO: make this not block forever 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