diff options
Diffstat (limited to 'firmware/fx3/b200/bootloader/usb_boot.c')
-rw-r--r-- | firmware/fx3/b200/bootloader/usb_boot.c | 807 |
1 files changed, 807 insertions, 0 deletions
diff --git a/firmware/fx3/b200/bootloader/usb_boot.c b/firmware/fx3/b200/bootloader/usb_boot.c new file mode 100644 index 000000000..ba7eb9dfb --- /dev/null +++ b/firmware/fx3/b200/bootloader/usb_boot.c @@ -0,0 +1,807 @@ +// +// Copyright 2011-2012 Cypress Semiconductor Corporation +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include "cyfx3usb.h" +#include "cyfx3device.h" +#include "cyfx3utils.h" +#include "cyfx3i2c.h" + +#include "common_helpers.h" +#include "common_descriptors.h" +#include "usb_descriptors.h" + +typedef enum +{ + eStall = 0, /* Send STALL */ + eDataIn, /* Data IN Stage */ + eDataOut, /* Data Out Stage */ + eStatus /* Status Stage */ +} eUsbStage; + +typedef int (*PFI)(); + +#define USB_SETUP_DIR (0x80) /* 0x80 = To Host */ +#define USB_SETUP_MASK (0x60) /* Used to mask off request type */ +#define USB_STANDARD_REQUEST (0x00) /* Standard Request */ +#define USB_VENDOR_REQUEST (0x40) /* Vendor Request */ +#define USB_REQ_MASK (0x3F) /* USB Request mask */ +#define USB_REQ_DEV (0) /* Device Request */ +#define USB_REQ_INTERFACE (1) /* Interface Request */ +#define USB_REQ_ENDPOINT (2) /* Endpoint Request */ +#define USB_SET_INTERFACE (11) +#define USB_SC_SET_SEL (0x30) /* Set system exit latency. */ +#define USB_SC_SET_ISOC_DELAY (0x31) + +#define SELF_POWERED (0x01) +#define REMOTE_WAKEUP (0x02) +#define U1_ENABLE (0x04) +#define U2_ENABLE (0x08) +#define LTM_ENABLE (0x10) + +uint8_t glUsbState = 0; +uint8_t gConfig = 0; /* Variable to hold the config info. */ +uint8_t gAltSetting = 0; /* Variable to hold the interface info. */ +uint8_t gUsbDevStatus = 0; +uint8_t glCheckForDisconnect = 0; +uint8_t glInCompliance = 0; + +/* 4KB of buffer area used for control endpoint transfers. */ +#define gpUSBData (uint8_t*)(0x40077000) +#define USB_DATA_BUF_SIZE (1024*4) + +CyU3PUsbDescrPtrs *gpUsbDescPtr; /* Pointer to the USB Descriptors */ +CyFx3BootUsbEp0Pkt_t gEP0; + +void myMemCopy(uint8_t* d, uint8_t* s, int32_t cnt) +{ + int32_t i; + for (i = 0; i < cnt; i++) { + *d++ = *s++; + } +} + +void myMemSet(uint8_t* d, uint8_t c, int32_t cnt) +{ + int32_t i; + for (i = 0; i < cnt; i++) { + *d++ = c; + } +} + +/************************************************ + * Request handlers + ***********************************************/ + +/* Function to handle the GET_STATUS Standard request. */ +int getStatus (void) +{ + uint16_t data = 0; + + switch (gEP0.bmReqType & USB_REQ_MASK) + { + case USB_REQ_DEV: + if (CyFx3BootUsbGetSpeed () == CY_FX3_BOOT_SUPER_SPEED) + { + data = (gpUsbDescPtr->usbSSConfigDesc_p[7] & 0x40) ? 1 : 0; + data |= gUsbDevStatus; + } + else + { + data = (gpUsbDescPtr->usbHSConfigDesc_p[7] & 0x40) ? 1 : 0; + data |= gUsbDevStatus; + } + break; + + case USB_REQ_INTERFACE: + if (!gConfig) + { + return eStall; + } + break; + + case USB_REQ_ENDPOINT: + if (CyFx3BootUsbGetEpCfg (gEP0.bIdx0, 0, (CyBool_t *)&data) != 0) + { + return eStall; + } + break; + default: + return eStall; + } + + *(uint16_t*)gEP0.pData = data; + return eDataIn; +} + +/* Function to handle the GET_DESCRIPTOR Standard request */ +int getDescriptor (void) +{ + uint32_t len = 0; + uint8_t *p = 0; + uint8_t *cfg_p = 0; + uint8_t usbSpeed; + + usbSpeed = CyFx3BootUsbGetSpeed(); + + gpUsbDescPtr->usbHSConfigDesc_p[1] = CY_U3P_USB_CONFIG_DESCR; + gpUsbDescPtr->usbFSConfigDesc_p[1] = CY_U3P_USB_CONFIG_DESCR; + + if (usbSpeed == CY_FX3_BOOT_HIGH_SPEED) + { + cfg_p = (uint8_t*)gpUsbDescPtr->usbHSConfigDesc_p; + len = ((gpUsbDescPtr->usbHSConfigDesc_p[3] << 8) | gpUsbDescPtr->usbHSConfigDesc_p[2]); + } + else if (usbSpeed == CY_FX3_BOOT_SUPER_SPEED) + { + cfg_p = (uint8_t*)gpUsbDescPtr->usbSSConfigDesc_p; + len = ((gpUsbDescPtr->usbSSConfigDesc_p[3] << 8) | gpUsbDescPtr->usbSSConfigDesc_p[2]); + } + else if (usbSpeed == CY_FX3_BOOT_FULL_SPEED) + { + cfg_p = (uint8_t*)gpUsbDescPtr->usbFSConfigDesc_p; + len = ((gpUsbDescPtr->usbFSConfigDesc_p[3] << 8) | gpUsbDescPtr->usbFSConfigDesc_p[2]); + } + + switch (gEP0.bVal1) + { + case CY_U3P_USB_DEVICE_DESCR: + { + if ((usbSpeed == CY_FX3_BOOT_HIGH_SPEED) || (usbSpeed == CY_FX3_BOOT_FULL_SPEED)) + { + p = (uint8_t*)gpUsbDescPtr->usbDevDesc_p; + len = gpUsbDescPtr->usbDevDesc_p[0]; + } + else if (usbSpeed == CY_FX3_BOOT_SUPER_SPEED) + { + p = (uint8_t*)gpUsbDescPtr->usbSSDevDesc_p; + len = gpUsbDescPtr->usbSSDevDesc_p[0]; + } + break; + } + case CY_U3P_BOS_DESCR: + { + p = (uint8_t *)gpUsbDescPtr->usbSSBOSDesc_p; + len = (gpUsbDescPtr->usbSSBOSDesc_p[3] << 8) | gpUsbDescPtr->usbSSBOSDesc_p[2]; + break; + } + case CY_U3P_USB_CONFIG_DESCR: + { + p = cfg_p; + break; + } + case CY_U3P_USB_DEVQUAL_DESCR: + { + if ((usbSpeed == CY_FX3_BOOT_HIGH_SPEED) || (usbSpeed == CY_FX3_BOOT_FULL_SPEED)) + { + p = (uint8_t*)gpUsbDescPtr->usbDevQualDesc_p; + len = gpUsbDescPtr->usbDevQualDesc_p[0]; + break; + } + return eStall; + } + case CY_U3P_USB_STRING_DESCR: + { + /* Ensure that we do not index past the limit of the array. */ + if (gEP0.bVal0 < CY_FX3_USB_MAX_STRING_DESC_INDEX) + { + p = (uint8_t*)gpUsbDescPtr->usbStringDesc_p[gEP0.bVal0]; + if (p != 0) + len = p[0]; + } + else + return eStall; + break; + } + case CY_U3P_USB_OTHERSPEED_DESCR: + { + if (usbSpeed == CY_FX3_BOOT_HIGH_SPEED) + { + gpUsbDescPtr->usbFSConfigDesc_p[1] = CY_U3P_USB_OTHERSPEED_DESCR; + p = (uint8_t*)gpUsbDescPtr->usbFSConfigDesc_p; + + len = ((gpUsbDescPtr->usbFSConfigDesc_p[3] < 8) | gpUsbDescPtr->usbFSConfigDesc_p[2]); + + if (len > gEP0.wLen) + { + len = gEP0.wLen; + } + } + else if (usbSpeed == CY_FX3_BOOT_FULL_SPEED) + { + gpUsbDescPtr->usbHSConfigDesc_p[1] = CY_U3P_USB_OTHERSPEED_DESCR; + p = (uint8_t*)gpUsbDescPtr->usbHSConfigDesc_p; + len = ((gpUsbDescPtr->usbHSConfigDesc_p[3] < 8) | gpUsbDescPtr->usbHSConfigDesc_p[2]); + + if (len > gEP0.wLen) + { + len = gEP0.wLen; + } + } + } + break; + default: + { + return eStall; + } + } + + if (p != 0) + { + myMemCopy (gpUSBData, p, len); + if (gEP0.wLen > len) + { + gEP0.wLen = len; + } + + return eDataIn; + } + else + /* Stall EP0 if the descriptor sought is not available. */ + return eStall; +} + +/* Function to handle the SET_CONFIG Standard request */ +int setConfig (void) +{ + uint8_t usbSpeed = 0; + uint32_t retVal = 0; + CyFx3BootUsbEpConfig_t epCfg; + + if ((gEP0.bVal0 == 0) || (gEP0.bVal0 == 1)) + { + glUsbState = gEP0.bVal0; + gConfig = gEP0.bVal0; + + /* Get the Bus speed */ + usbSpeed = CyFx3BootUsbGetSpeed(); + + epCfg.pcktSize = 512; + /* Based on the Bus Speed configure the endpoint packet size */ + if (usbSpeed == CY_FX3_BOOT_HIGH_SPEED) + { + epCfg.pcktSize = 512; + } + if (usbSpeed == CY_FX3_BOOT_SUPER_SPEED) + { + epCfg.pcktSize = 1024; + } + if (usbSpeed == CY_FX3_BOOT_FULL_SPEED) + { + epCfg.pcktSize = 64; + } + + /* Producer Endpoint configuration */ + epCfg.enable = 1; + epCfg.epType = CY_FX3_BOOT_USB_EP_BULK; + epCfg.burstLen = 1; + epCfg.streams = 0; + epCfg.isoPkts = 0; + + /* Configure the Endpoint */ + retVal = CyFx3BootUsbSetEpConfig(0x01, &epCfg); + if (retVal != 0) + { + /* TODO: Error Handling */ + return eStall; + } + + /* Consumer Endpoint configuration */ + epCfg.enable = 1; + epCfg.epType = CY_FX3_BOOT_USB_EP_BULK; + epCfg.burstLen = 1; + epCfg.streams = 0; + epCfg.isoPkts = 0; + + /* Configure the Endpoint */ + retVal = CyFx3BootUsbSetEpConfig (0x81, &epCfg); + if (retVal != 0) + { + /* TODO: Error Handling */ + return eStall; + } + + return eStatus; + } + + return eStall; +} + +/* Function to handle the GET_INTERFACE Standard request */ +int getInterface (void) +{ + if (gConfig == 0) + { + return eStall; + } + + gEP0.pData = (uint8_t *)&gAltSetting; + return eDataIn; +} + +/* Function to handle the SET_INTERFACE Standard request */ +int setInterface (void) +{ + gAltSetting = gEP0.bVal0; + return eStatus; +} + +/* This function returns stall for not supported requests. */ +int stall (void) +{ + return eStall; +} + +/* Function to handle the SET_ADDRESS Standard request. */ +int setAddress (void) +{ + return eStatus; +} + +/* Function to handle the CLEAR_FEATURE Standard request. */ +int clearFeature (void) +{ + /* All of the actual handling for the CLEAR_FEATURE request is done in the API. + We only need to update the device status flags here. + */ + if (CyFx3BootUsbSetClrFeature (0, (CyBool_t)glUsbState, &gEP0) != 0) + { + return eStall; + } + + if (gEP0.bmReqType == USB_REQ_DEV) + { + /* Update the device status flags as required. */ + if (CyFx3BootUsbGetSpeed () == CY_FX3_BOOT_SUPER_SPEED) + { + switch (gEP0.bVal0) + { + case 48: + gUsbDevStatus &= ~U1_ENABLE; + break; + case 49: + gUsbDevStatus &= ~U2_ENABLE; + break; + case 50: + gUsbDevStatus &= ~LTM_ENABLE; + break; + default: + break; + } + } + else + { + if (gEP0.bVal0 == 1) + { + gUsbDevStatus &= ~REMOTE_WAKEUP; + } + } + } + + return eStatus; +} + +/* Function to handle the SET_FEATURE Standard request. */ +int setFeature (void) +{ + /* All of the actual handling for the SET_FEATURE command is done in the API. + * We only need to update the device status flags here. + */ + if (CyFx3BootUsbSetClrFeature (1, (CyBool_t)glUsbState, &gEP0) != 0) + { + return eStall; + } + + if (gEP0.bmReqType == USB_REQ_DEV) + { + /* Update the device status flags as required. */ + if (CyFx3BootUsbGetSpeed () == CY_FX3_BOOT_SUPER_SPEED) + { + switch (gEP0.bVal0) + { + case 48: + gUsbDevStatus |= U1_ENABLE; + break; + case 49: + gUsbDevStatus |= U2_ENABLE; + break; + case 50: + gUsbDevStatus |= LTM_ENABLE; + break; + default: + break; + } + } + else + { + if (gEP0.bVal0 == 1) + { + gUsbDevStatus |= REMOTE_WAKEUP; + } + } + } + return eStatus; +} + +/* Function to handle the GET_CONFIG Standard request. */ +int getConfig (void) +{ + gEP0.pData = (uint8_t *)&gConfig; + return eDataIn; +} + +const PFI chapter9_cmds[] = +{ + getStatus, /* USB_GET_STATUS 0 */ + clearFeature, /* USB_CLEAR_FEATURE 1 */ + stall, /* Reserved 2 */ + setFeature, /* USB_SET_FEATURE 3 */ + stall, /* Reserved 4 */ + setAddress, /* USB_SET_ADDRESS 5 */ + getDescriptor, /* USB_GET_DESCRIPTOR 6 */ + stall, /* USB_SET_DESCRIPTOR 7 */ + getConfig, /* USB_GET_CONFIGURATION 8 */ + setConfig, /* USB_SET_CONFIGURATION 9 */ + getInterface, /* USB_GET_INTERFACE 10 */ + setInterface, /* USB_SET_INTERFACE 11 */ +}; + +/* This function validates the addresses being written to/read from + Return Value: + 0 - Address is valid + -1 - Address is not valid +*/ +int checkAddress (uint32_t address, uint32_t len) +{ + if (address & 3) + { + /* expect long word boundary */ + return -1; + } + + len += address; + + if ((address >= CY_FX3_BOOT_SYSMEM_BASE1) && (len <= CY_FX3_BOOT_SYSMEM_END)) + { + return 0; + } + + if (len <= CY_FX3_BOOT_ITCM_END) + { + return 0; + } + + return -1; +} + +/* Function to handle the vendor commands. */ +void vendorCmdHandler (void) +{ + int stage; + int status; + uint32_t address = ((gEP0.bIdx1 << 24) | (gEP0.bIdx0 << 16) | (gEP0.bVal1 << 8) | (gEP0.bVal0)); + uint16_t len = gEP0.wLen; + uint16_t bReq = gEP0.bReq; + uint16_t dir = gEP0.bmReqType & USB_SETUP_DIR; + + if (len > USB_DATA_BUF_SIZE) + { + CyFx3BootUsbStall (0, CyTrue, CyFalse); + return; + } + + if (dir) + { + stage = eDataIn; + } + else + { + stage = eDataOut; + } + + /* Vendor Command 0xA0 handling */ + if (bReq == 0xA0) + { + /* Note: This is a command issued by the CyControl Application to detect the legacy products. + As we are an FX3 device we stall the endpoint to indicate that this is not a legacy device. + */ + if (address == 0xE600) + { + /* Stall the Endpoint */ + CyFx3BootUsbStall (0, CyTrue, CyFalse); + return; + } + + status = checkAddress (address, len); + if (len == 0) + { + /* Mask the USB Interrupts and Disconnect the USB Phy. */ + CyFx3BootUsbConnect (CyFalse, CyTrue); + /* Transfer to Program Entry */ + CyFx3BootJumpToProgramEntry (address); + return; + } + + if (status < 0) + { + /* Stall the endpoint */ + CyFx3BootUsbStall (0, CyTrue, CyFalse); + return; + } + + /* Validate the SYSMEM address being accessed */ + if ((address >= CY_FX3_BOOT_SYSMEM_BASE1) && (address < CY_FX3_BOOT_SYSMEM_END)) + { + gEP0.pData = (uint8_t*)address; + } + + CyFx3BootUsbAckSetup (); + + if (eDataIn == stage) + { + if ((address + gEP0.wLen) <= CY_FX3_BOOT_ITCM_END) + { + myMemCopy(gEP0.pData, (uint8_t *)address , len); + } + + status = CyFx3BootUsbDmaXferData (0x80, (uint32_t)gEP0.pData, gEP0.wLen, CY_FX3_BOOT_WAIT_FOREVER); + if (status != CY_FX3_BOOT_SUCCESS) + { + /* USB DMA Transfer failed. Stall the Endpoint. */ + CyFx3BootUsbStall (0, CyTrue, CyFalse); + return; + } + } + else if (stage == eDataOut) + { + status = CyFx3BootUsbDmaXferData (0x00, (uint32_t)gEP0.pData, gEP0.wLen, CY_FX3_BOOT_WAIT_FOREVER); + if (status != CY_FX3_BOOT_SUCCESS) + { + /* USB DMA Transfer failed. Stall the Endpoint. */ + CyFx3BootUsbStall (0, CyTrue, CyFalse); + return; + } + + /* Validate ITCM Memory */ + if ((address + gEP0.wLen) <= CY_FX3_BOOT_ITCM_END) + { + /* Avoid writing to the interrupt table. */ + if (address < 0xFF) { + gEP0.pData += 0xFF-address; + gEP0.wLen -= 0xFF-address; + address = 0xFF; + } + myMemCopy((uint8_t *)address, gEP0.pData, gEP0.wLen); + } + } + return; + } + + /* Version request */ + if (dir && bReq == 0xB8) { + uint8_t version_info[] = {1, 21, 0, 0, 0, 0}; + + CyFx3BootUsbAckSetup (); + status = CyFx3BootUsbDmaXferData (0x80, (uint32_t)version_info, + sizeof(version_info), CY_FX3_BOOT_WAIT_FOREVER); + if (status != CY_FX3_BOOT_SUCCESS) { + /* USB DMA Transfer failed. Stall the Endpoint. */ + CyFx3BootUsbStall (0, CyTrue, CyFalse); + } + + return; + } + + /* Stall the Endpoint */ + CyFx3BootUsbStall (0, CyTrue, CyFalse); + return; +} + +/* Setup Data handler */ +void setupDataHandler (uint32_t setupDat0, uint32_t setupDat1) +{ + uint32_t *p; + int status = eStall; + + p = (uint32_t*)&gEP0; + p[0] = setupDat0; + p[1] = setupDat1; + + gEP0.pData = gpUSBData; + + switch (gEP0.bmReqType & USB_SETUP_MASK) + { + case USB_STANDARD_REQUEST: + if (gEP0.bReq <= USB_SET_INTERFACE) + { + status = (*chapter9_cmds[gEP0.bReq])(); + } + else + { + if (gEP0.bReq == USB_SC_SET_SEL) + { + if ((CyFx3BootUsbGetSpeed () == CY_FX3_BOOT_SUPER_SPEED) && (gEP0.bIdx0 == 0) && + (gEP0.bIdx1 == 0) && (gEP0.bVal0 == 0) && (gEP0.bVal1 == 0) && (gEP0.wLen == 6)) + { + gEP0.wLen = 32; + status = eDataOut; + } + else + { + status = eStall; + } + } + else if (gEP0.bReq == USB_SC_SET_ISOC_DELAY) + { + status = eStatus; + if ((CyFx3BootUsbGetSpeed () != CY_FX3_BOOT_SUPER_SPEED) || (gEP0.bIdx0 != 0) || + (gEP0.bIdx1 != 0) || (gEP0.wLen != 0)) + { + status = eStall; + } + } + else + { + status = eStall; + } + } + break; + + case USB_VENDOR_REQUEST: + vendorCmdHandler(); + return; + } + + switch (status) + { + case eDataIn: + CyFx3BootUsbAckSetup (); + status = CyFx3BootUsbDmaXferData (0x80, (uint32_t)gEP0.pData, gEP0.wLen, 1000); + if (status != CY_FX3_BOOT_SUCCESS) + { + CyFx3BootUsbStall (0, CyTrue, CyFalse); + } + break; + case eDataOut: + CyFx3BootUsbAckSetup (); + status = CyFx3BootUsbDmaXferData (0x00, (uint32_t)gEP0.pData, gEP0.wLen, CY_FX3_BOOT_WAIT_FOREVER); + if (status != CY_FX3_BOOT_SUCCESS) + { + CyFx3BootUsbStall (0, CyTrue, CyFalse); + } + break; + case eStatus: + CyFx3BootUsbAckSetup (); + break; + default: + CyFx3BootUsbStall (0, CyTrue, CyFalse); + return; + } + + return; +} + +/* USB Event Handler. This function is invoked from the USB ISR and as such MUST not be + blocked. +*/ +void usbEventCallback (CyFx3BootUsbEventType_t event) +{ + if (event == CY_FX3_BOOT_USB_RESET) + { + gConfig = 0; + gAltSetting = 0; + gUsbDevStatus = 0; + glUsbState = 0; + glInCompliance = 0; + } + + if ((event == CY_FX3_BOOT_USB_CONNECT) || + (event == CY_FX3_BOOT_USB_DISCONNECT)) + { + glUsbState = 0; + gUsbDevStatus = 0; + } + + if (event == CY_FX3_BOOT_USB_IN_SS_DISCONNECT) + { + glCheckForDisconnect = CyTrue; + } + + if (event == CY_FX3_BOOT_USB_COMPLIANCE) + { + glInCompliance = CyTrue; + } + + return; +} + +/* Function passed to common EEPROM functions to access the EEPROM */ +void eeprom_read(uint16_t addr, uint8_t* buffer, uint8_t length) +{ + CyFx3BootI2cPreamble_t preamble; + preamble.length = 4; + preamble.buffer[0] = 0xA0; + preamble.buffer[1] = addr >> 8; + preamble.buffer[2] = addr & 0xFF; + preamble.buffer[3] = 0xA1; + preamble.ctrlMask = 0x0004; + CyFx3BootI2cReceiveBytes(&preamble, buffer, length, 0); +} + +/* USB initialization */ +void usbBoot() +{ + /* Reset globals */ + gConfig = 0; + gAltSetting = 0; + gUsbDevStatus = 0; + glUsbState = 0; + glCheckForDisconnect = 0; + glInCompliance = 0; + + /* Init */ + CyFx3BootUsbStart (CyFalse, usbEventCallback); + + /* Run USB circuitry off of host power, not internal power. */ + CyFx3BootUsbVBattEnable (CyFalse); + + /* Register callbacks */ + CyFx3BootRegisterSetupCallback (setupDataHandler); + + /* Enable I2C for EEPROM access */ + CyFx3BootI2cInit(); + CyFx3BootI2cConfig_t i2cCfg = { + .bitRate = 100000, + .isDma = CyFalse, + .busTimeout = 0xFFFFFFFF, + .dmaTimeout = 0xFFFF}; + CyFx3BootI2cSetConfig(&i2cCfg); + + /* Retrieve VID and PID from EEPROM */ + const uint16_t vid = get_vid(&eeprom_read); + const uint16_t pid = get_pid(&eeprom_read); + + /* Power down I2C */ + CyFx3BootI2cDeInit(); + + /* Populate device descriptors with IDs */ + common_usb2_dev_desc[8] = vid & 0xFF; + common_usb2_dev_desc[9] = vid >> 8; + common_usb2_dev_desc[10] = pid & 0xFF; + common_usb2_dev_desc[11] = pid >> 8; + + common_usb3_dev_desc[8] = vid & 0xFF; + common_usb3_dev_desc[9] = vid >> 8; + common_usb3_dev_desc[10] = pid & 0xFF; + common_usb3_dev_desc[11] = pid >> 8; + + /* Copy all descriptors */ + CyFx3BootUsbSetDesc( + CY_U3P_USB_SET_HS_DEVICE_DESCR, 0, (uint8_t*)common_usb2_dev_desc); + CyFx3BootUsbSetDesc( + CY_U3P_USB_SET_SS_DEVICE_DESCR, 0, (uint8_t*)common_usb3_dev_desc); + + CyFx3BootUsbSetDesc(CY_U3P_USB_SET_DEVQUAL_DESCR, 0, (uint8_t*)common_dev_qual_desc); + + CyFx3BootUsbSetDesc(CY_U3P_USB_SET_HS_CONFIG_DESCR, 0, (uint8_t*)bl_hs_config_desc); + CyFx3BootUsbSetDesc(CY_U3P_USB_SET_FS_CONFIG_DESCR, 0, (uint8_t*)bl_fs_config_desc); + CyFx3BootUsbSetDesc(CY_U3P_USB_SET_SS_CONFIG_DESCR, 0, (uint8_t*)bl_ss_config_desc); + + CyFx3BootUsbSetDesc(CY_U3P_USB_SET_SS_BOS_DESCR, 0, (uint8_t*)common_usb_bos_desc); + + CyFx3BootUsbSetDesc( + CY_U3P_USB_SET_STRING_DESCR, 0, (uint8_t*)common_string_lang_id_desc); + + CyFx3BootUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 1, (uint8_t*)bl_manufacturer_desc); + CyFx3BootUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 2, (uint8_t*)bl_product_desc); + CyFx3BootUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 3, (uint8_t*)bl_dev_serial_desc); + + gpUsbDescPtr = CyFx3BootUsbGetDesc(); + + /* Connect! */ + CyFx3BootUsbConnect (CyTrue, CyTrue); +} + |