diff options
23 files changed, 2065 insertions, 639 deletions
diff --git a/firmware/fx3/.gitignore b/firmware/fx3/.gitignore index f2c372d44..81a6777c4 100644 --- a/firmware/fx3/.gitignore +++ b/firmware/fx3/.gitignore @@ -1,3 +1,5 @@ +boot_fw common +elf2img lpp_source u3p_firmware diff --git a/firmware/fx3/README.md b/firmware/fx3/README.md index 9b3d65489..00f38185f 100644 --- a/firmware/fx3/README.md +++ b/firmware/fx3/README.md @@ -5,7 +5,7 @@ INSTRUCTIONS The USRP B200 and B210 each use the Cypress FX3 USB3 PHY for USB3 connectivity. This device has an ARM core on it, which is programmed in C. This README will -show you how to build our firmware source +show you how to build our firmware and bootloader source. **A brief "Theory of Operations":** The host sends commands to the FX3, our USB3 PHY, which has an on-board ARM @@ -32,9 +32,11 @@ tools. These variables are: $ export ARMGCC_VERSION=4.5.2 ``` -Now, you'll need to set-up the Cypress SDK, as well. In the SDK, navigate to -the `firmware` directory, and copy the following sub-directories into -`uhd.git/firmware/fx3`: `common/`, `lpp_source/`, `u3p_firmware/`. +Now, you'll need to set-up the Cypress SDK, as well. In the SDK, copy the +following sub-directories from the `firmware` directory to +`uhd.git/firmware/fx3`: `common/`, `lpp_source/`, `u3p_firmware/`, `boot_fw/`. +In addition, copy the `elf2img` sub-directory from the `util` directory to +`uhd.git/firmware/fx3`. Your directory structure should now look like: @@ -46,7 +48,9 @@ uhd.git/ --fx3/ | --b200/ # From UHD + --boot_fw/ # From Cypress SDK --common/ # From Cypress SDK + --elf2img/ # From Cypress SDK --gpif2_designer/ # From UHD --lpp_source/ # From Cypress SDK --u3p_firmware/ # From Cypress SDK @@ -61,22 +65,33 @@ into the `common/` directory you just copied from the Cypress SDK, and apply the patch `b200/fx3_mem_map.patch`. ``` - # cd uhd.git/firmware/fx3/common/ - $ patch -p2 < ../b200/fx3_mem_map.patch + # cd uhd.git/firmware/fx3 + $ patch -p1 < ../b200/fx3_mem_map.patch ``` If you don't see any errors print on the screen, then the patch was successful. ## Building the Firmware -Now, you should be able to head into the `b200/` directory and simply build the -firmware: +Now, you should be able to head into the `b200/firmware` directory and simply +build the firmware: ``` - $ cd uhd.git/firmware/fx3/b200 + $ cd uhd.git/firmware/fx3/b200/firmware $ make ``` It will generate a `usrp_b200_fw.hex` file, which you can then give to UHD to program your USRP B200 or USRP B210. +## Building the Bootloader + +The bootloader is built in the `b200/bootloader` directory: + +``` + $ cd uhd.git/firmware/fx3/b200/bootloader + $ make +``` + +It will generate a `usrp_b200_bl.img` file, which you can supply as an argument +to b2xx_fx3_utils to load it onto the device. diff --git a/firmware/fx3/b200/.gitignore b/firmware/fx3/b200/.gitignore index 13c187886..2c36b03cd 100644 --- a/firmware/fx3/b200/.gitignore +++ b/firmware/fx3/b200/.gitignore @@ -1,4 +1,7 @@ +lib +!common *.o *.elf *.hex *.map +*.img diff --git a/firmware/fx3/b200/bootloader/.gitignore b/firmware/fx3/b200/bootloader/.gitignore new file mode 100644 index 000000000..75d01c18d --- /dev/null +++ b/firmware/fx3/b200/bootloader/.gitignore @@ -0,0 +1,5 @@ +cyfx3.ld +cyfx_gcc_startup.S +elf2img +fx3_armgcc_config.mak +fx3_build_config.mak diff --git a/firmware/fx3/b200/bootloader/main.c b/firmware/fx3/b200/bootloader/main.c new file mode 100644 index 000000000..f46690813 --- /dev/null +++ b/firmware/fx3/b200/bootloader/main.c @@ -0,0 +1,55 @@ +// +// 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" + +extern void usbBoot (void); +extern uint8_t glCheckForDisconnect; +extern uint8_t glInCompliance; + +int main (void) +{ + CyFx3BootErrorCode_t status; + CyFx3BootIoMatrixConfig_t ioCfg = { + .isDQ32Bit = CyFalse, + .useUart = CyFalse, + .useI2C = CyTrue, + .useI2S = CyFalse, + .useSpi = CyFalse, + .gpioSimpleEn[0] = 0, + .gpioSimpleEn[1] = 0 + }; + + CyFx3BootDeviceInit(CyTrue); + + status = CyFx3BootDeviceConfigureIOMatrix(&ioCfg); + + if (status != CY_FX3_BOOT_SUCCESS) + { + return status; + } + + usbBoot(); + + while (1) + { + if (glCheckForDisconnect) + { + CyFx3BootUsbCheckUsb3Disconnect(); + glCheckForDisconnect = 0; + } + + if (glInCompliance) + { + CyFx3BootUsbSendCompliancePatterns(); + glInCompliance = 0; + } + } + return 0; +} + diff --git a/firmware/fx3/b200/bootloader/makefile b/firmware/fx3/b200/bootloader/makefile new file mode 100644 index 000000000..3dc7fcb80 --- /dev/null +++ b/firmware/fx3/b200/bootloader/makefile @@ -0,0 +1,92 @@ +# +# Copyright 2019 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +IMGOUT = usrp_b200_bl.img + +all:$(IMGOUT) + +BL_ROOT=../../boot_fw +BL_INC=$(BL_ROOT)/include +BL_LIB=$(BL_ROOT)/lib +BL_CYP_SRC=$(BL_ROOT)/src + +ELF2IMG_SRC=../../elf2img/elf2img.c +ELF2IMG=elf2img + +CYFXBUILD = gcc + +include fx3_build_config.mak + +MODULE = cyfx_boot_app + +APP_SOURCE = main.c usb_boot.c usb_descriptors.c ../common/common_descriptors.c ../common/common_helpers.c + +INCFLAGS = -I$(BL_INC) -I../common + +APP_OBJECT=$(APP_SOURCE:%.c=./%.o) + +APP_ASM_OBJECT=$(APP_ASM_SOURCE:%.S=./%.o) + +EXES = $(MODULE).$(EXEEXT) + +ifeq ($(CYFXBUILD), gcc) + +APP_ASM_SOURCE = cyfx_gcc_startup.S + +else + +APP_ASM_SOURCE = + +endif + +$(APP_ASM_OBJECT) : %.o : %.S + $(ASSEMBLE) + +$(APP_OBJECT) : %.o : %.c ../lib/cyfx3_boot.a cyfx3.ld + $(COMPILE) $(INCFLAGS) + +$(MODULE).$(EXEEXT): $(APP_OBJECT) $(APP_ASM_OBJECT) + $(LINK) + +$(ELF2IMG): + gcc -o $(ELF2IMG) $(ELF2IMG_SRC) + +fx3_build_config.mak: + cp $(BL_CYP_SRC)/fx3_build_config.mak . +fx3_armgcc_config.mak: + cp $(BL_CYP_SRC)/fx3_armgcc_config.mak . +cyfx_gcc_startup.S: + cp $(BL_CYP_SRC)/cyfx_gcc_startup.S . +cyfx3.ld: + cp $(BL_CYP_SRC)/cyfx3.ld . +../lib/cyfx3_boot.a: + mkdir -p ../lib + cp $(BL_LIB)/cyfx3_boot.a ../lib + + +clean: + rm -f ./$(MODULE).$(EXEEXT) + rm -f ./$(MODULE).map + rm -f ./$(IMGOUT) + rm -f ./fx3_build_config.mak + rm -f ./fx3_armgcc_config.mak + rm -f ./cyfx_gcc_startup.S + rm -f ./cyfx3.ld + rm -f ../lib/cyfx3_boot.a + rmdir ../lib --ignore-fail-on-non-empty + rm -f ./*.o + rm -f ../common/*.o + rm -f ./$(ELF2IMG) +ifeq ($(CYFXBUILD), gcc) + rm -f ./gcceclipse_files/*.o +endif + +compile: $(APP_OBJECT) $(APP_ASM_OBJECT) $(EXES) + +$(IMGOUT): compile $(EXES) $(ELF2IMG) + ./$(ELF2IMG) -i $(EXES) -o $(IMGOUT) -i2cconf 0x1A + +#[]# 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); +} + diff --git a/firmware/fx3/b200/bootloader/usb_descriptors.c b/firmware/fx3/b200/bootloader/usb_descriptors.c new file mode 100644 index 000000000..47d3175a8 --- /dev/null +++ b/firmware/fx3/b200/bootloader/usb_descriptors.c @@ -0,0 +1,187 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +/* Bootloader's unique config and string descriptors. */ + +/* Bootloader Full Speed Configuration Descriptor */ +const unsigned char bl_fs_config_desc[] = +{ + /* Configuration Descriptor Type */ + 0x09, /* Descriptor Size */ + 0x02, /* Configuration Descriptor Type */ + 0x20,0x00, /* Length of this descriptor and all sub descriptors */ + 0x01, /* Number of interfaces */ + 0x01, /* Configuration number */ + 0x00, /* COnfiguration string index */ + 0x80, /* Config characteristics - Bus powered */ + 0x32, /* Max power consumption of device (in 2mA unit) : 100mA */ + + /* Interface Descriptor */ + 0x09, /* Descriptor size */ + 0x04, /* Interface Descriptor type */ + 0x00, /* Interface number */ + 0x00, /* Alternate setting number */ + 0x02, /* Number of end points */ + 0xFF, /* Interface class */ + 0x00, /* Interface sub class */ + 0x00, /* Interface protocol code */ + 0x00, /* Interface descriptor string index */ + + /* Endpoint Descriptor for Producer EP */ + 0x07, /* Descriptor size */ + 0x05, /* Endpoint Descriptor Type */ + 0x01, /* Endpoint address and description */ + 0x02, /* Bulk End point Type */ + 0x40,0x00, /* Max packet size = 64 bytes */ + 0x00, /* Servicing interval for data transfers : NA for Bulk */ + + /* Endpoint Descriptor for Consumer EP */ + 0x07, /* Descriptor size */ + 0x05, /* Endpoint Descriptor Type */ + 0x81, /* Endpoint address and description */ + 0x02, /* Bulk End point Type */ + 0x40,0x00, /* Max packet size = 64 bytes */ + 0x00 /* Servicing interval for data transfers : NA for Bulk */ +}; + +/* Bootloader High Speed Configuration Descriptor */ +const unsigned char bl_hs_config_desc[] = +{ + 0x09, /* Descriptor Size */ + 0x02, /* Configuration Descriptor Type */ + 0x20,0x00, /* Length of this descriptor and all sub descriptors */ + 0x01, /* Number of interfaces */ + 0x01, /* Configuration number */ + 0x00, /* COnfiguration string index */ + 0x80, /* Config characteristics - Bus powered */ + 0x32, /* Max power consumption of device (in 2mA unit) : 100mA */ + + /* Interface Descriptor */ + 0x09, /* Descriptor size */ + 0x04, /* Interface Descriptor type */ + 0x00, /* Interface number */ + 0x00, /* Alternate setting number */ + 0x02, /* Number of end points */ + 0xFF, /* Interface class */ + 0x00, /* Interface sub class */ + 0x00, /* Interface protocol code */ + 0x00, /* Interface descriptor string index */ + + /* Endpoint Descriptor for Producer EP */ + 0x07, /* Descriptor size */ + 0x05, /* Endpoint Descriptor Type */ + 0x01, /* Endpoint address and description */ + 0x02, /* Bulk End point Type */ + 0x00, /* Max packet size = 512 bytes */ + 0x02, + 0x00, /* Servicing interval for data transfers : NA for Bulk */ + + /* Endpoint Descriptor for Consumer EP */ + 0x07, /* Descriptor size */ + 0x05, /* Endpoint Descriptor Type */ + 0x81, /* Endpoint address and description */ + 0x02, /* Bulk End point Type */ + 0x00, /* Max packet size = 512 bytes */ + 0x02, + 0x00 /* Servicing interval for data transfers : NA for Bulk */ +}; + +/* Bootloader Super Speed Configuration Descriptor */ +const unsigned char bl_ss_config_desc[] = +{ + /* Configuration Descriptor Type */ + 0x09, /* Descriptor Size */ + 0x02, /* Configuration Descriptor Type */ + 0x2C,0x00, /* Length of this descriptor and all sub descriptors */ + 0x01, /* Number of interfaces */ + 0x01, /* Configuration number */ + 0x00, /* COnfiguration string index */ + 0x80, /* Config characteristics - D6: Self power; D5: Remote Wakeup */ + 0x32, /* Max power consumption of device (in 8mA unit) : 400mA */ + + /* Interface Descriptor */ + 0x09, /* Descriptor size */ + 0x04, /* Interface Descriptor type */ + 0x00, /* Interface number */ + 0x00, /* Alternate setting number */ + 0x02, /* Number of end points */ + 0xFF, /* Interface class */ + 0x00, /* Interface sub class */ + 0x00, /* Interface protocol code */ + 0x00, /* Interface descriptor string index */ + + /* Endpoint Descriptor for Producer EP */ + 0x07, /* Descriptor size */ + 0x05, /* Endpoint Descriptor Type */ + 0x01, /* Endpoint address and description */ + 0x02, /* Bulk End point Type */ + 0x00,0x04, /* Max packet size = 1024 bytes */ + 0x00, /* Servicing interval for data transfers : NA for Bulk */ + + /* Super Speed Endpoint Companion Descriptor for Producer EP */ + 0x06, /* Descriptor size */ + 0x30, /* SS Endpoint Companion Descriptor Type */ + 0x00, /* Max no. of packets in a Burst : 0: Burst 1 packet at a time */ + 0x00, /* Max streams for Bulk EP = 0 (No streams)*/ + 0x00,0x00, /* Service interval for the EP : NA for Bulk */ + + /* Endpoint Descriptor for Consumer EP */ + 0x07, /* Descriptor size */ + 0x05, /* Endpoint Descriptor Type */ + 0x81, /* Endpoint address and description */ + 0x02, /* Bulk End point Type */ + 0x00,0x04, /* Max packet size = 1024 bytes */ + 0x00, /* Servicing interval for data transfers : NA for Bulk */ + + /* Super Speed Endpoint Companion Descriptor for Consumer EP */ + 0x06, /* Descriptor size */ + 0x30, /* SS Endpoint Companion Descriptor Type */ + 0x00, /* Max no. of packets in a Burst : 0: Burst 1 packet at a time */ + 0x00, /* Max streams for Bulk EP = 0 (No streams)*/ + 0x00,0x00 /* Service interval for the EP : NA for Bulk */ +}; + +/* Bootloader Product String Descriptor */ +const unsigned char bl_manufacturer_desc[] = +{ + 0x10, + 0x03, + 'C', 0x00, + 'y', 0x00, + 'p', 0x00, + 'r', 0x00, + 'e', 0x00, + 's', 0x00, + 's', 0x00 +}; + +/* Bootloader Manufacturer String Descriptor */ +const unsigned char bl_product_desc[] = +{ + 0x16, + 0x03, + 'W', 0x00, + 'e', 0x00, + 's', 0x00, + 't', 0x00, + 'B', 0x00, + 'r', 0x00, + 'i', 0x00, + 'd', 0x00, + 'g', 0x00, + 'e', 0x00 +}; + +/* Bootloader Device Serial String Descriptor */ +const unsigned char bl_dev_serial_desc [] = +{ + 0x1A, /* bLength */ + 0x03, /* bDescType */ + '0',0,'0',0,'0',0,'0',0,'0',0,'0',0, + '0',0,'0',0,'0',0,'4',0,'B',0,'E',0, + 0,0, /* long word align */ +}; + diff --git a/firmware/fx3/b200/bootloader/usb_descriptors.h b/firmware/fx3/b200/bootloader/usb_descriptors.h new file mode 100644 index 000000000..8a7942327 --- /dev/null +++ b/firmware/fx3/b200/bootloader/usb_descriptors.h @@ -0,0 +1,26 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +/* Bootloader's unique config and string descriptors. */ + +/* Bootloader Full Speed Configuration Descriptor */ +extern const unsigned char bl_fs_config_desc[]; + +/* Bootloader High Speed Configuration Descriptor */ +extern const unsigned char bl_hs_config_desc[]; + +/* Bootloader Super Speed Configuration Descriptor */ +extern const unsigned char bl_ss_config_desc[]; + +/* Bootloader Manufacturer String Descriptor */ +extern const unsigned char bl_manufacturer_desc[]; + +/* Bootloader Product String Descriptor */ +extern const unsigned char bl_product_desc[]; + +/* Bootloader Device Serial String Descriptor */ +extern const unsigned char bl_dev_serial_desc[]; + diff --git a/firmware/fx3/b200/common/common_const.h b/firmware/fx3/b200/common/common_const.h new file mode 100644 index 000000000..1b40a7fdd --- /dev/null +++ b/firmware/fx3/b200/common/common_const.h @@ -0,0 +1,51 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef _COMMON_CONST_H +#define _COMMON_CONST_H + +#define EEPROM_REV_UNRECOGNIZED -1 + +#define EEPROM_SIGNATURE_ADDR 0x0000 +#define EEPROM_SIGNATURE_LENGTH 4 + +#define EEPROM_REV0_SIGNATURE 0xB2145943 +#define EEPROM_REV1_OR_GREATER_SIGNATURE 0xB01A5943 + +#define EEPROM_REV0_VID_ADDR 0x0006 +#define EEPROM_REV1_VID_ADDR 0x7F06 +#define EEPROM_VID_LENGTH 2 + +#define VID_ETTUS_RESEARCH 0x2500 +#define VID_NATIONAL_INSTRUMENTS 0x3923 +#define VID_CYPRESS 0x04B4 + +#define EEPROM_REV0_PID_ADDR 0x0004 +#define EEPROM_REV1_PID_ADDR 0x7F08 +#define EEPROM_PID_LENGTH 2 + +#define PID_ETTUS_B200_B210 0x0020 +#define PID_NI_USRP_2900 0x7813 +#define PID_NI_USRP_2901 0x7814 +#define PID_CYPRESS_DEFAULT 0x00F0 + +#define EEPROM_REV0_SERIAL_ADDR 0x04F7 +#define EEPROM_REV1_SERIAL_ADDR 0x7F23 +#define EEPROM_SERIAL_LENGTH 9 + +#define EEPROM_REV1_MAGIC_ADDR 0x7F00 +#define EEPROM_MAGIC_LENGTH 2 +#define EEPROM_EXPECTED_MAGIC 0xB200 + +#define EEPROM_REV1_REV_ADDR 0x7F02 +#define EEPROM_REV_LENGTH 2 +#define EEPROM_EXPECTED_REV 1 + +#define EEPROM_REV1_COMPAT_ADDR 0x7F04 +#define EEPROM_COMPAT_LENGTH 2 +#define EEPROM_EXPECTED_COMPAT 1 + +#endif /* _COMMON_CONST_H */ diff --git a/firmware/fx3/b200/common/common_descriptors.c b/firmware/fx3/b200/common/common_descriptors.c new file mode 100644 index 000000000..7cb670a4a --- /dev/null +++ b/firmware/fx3/b200/common/common_descriptors.c @@ -0,0 +1,237 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +/* This file contains all descriptors that are common between the bootloader + and firmware code. Non-const descriptors are modified at runtime based on + information read from the EEPROM. */ + +/* Standard Device Descriptor for USB 2.0 */ +unsigned char common_usb2_dev_desc[] = +{ + 0x12, /* Descriptor size */ + 0x01,/* CY_U3P_USB_DEVICE_DESCR Device descriptor type */ + 0x10,0x02, /* USB 2.10 */ + 0xFF, /* Device class */ + 0x00, /* Device sub-class */ + 0x00, /* Device protocol */ + 0x40, /* Maxpacket size for EP0 : 64 bytes */ + 0xB4,0x04, /* Vendor ID */ + 0xF0,0x00, /* Product ID */ + 0x00,0x00, /* Device release number */ + 0x01, /* Manufacture string index */ + 0x02, /* Product string index */ + 0x03, /* Serial number string index */ + 0x01 /* Number of configurations */ +}; + +/* Standard Device Descriptor for USB 3.0 */ +unsigned char common_usb3_dev_desc[] = +{ + 0x12, /* Descriptor size */ + 0x01,/* CY_U3P_USB_DEVICE_DESCR Device descriptor type */ + 0x00,0x03, /* USB 3.0 */ + 0xFF, /* Device class */ + 0x00, /* Device sub-class */ + 0x00, /* Device protocol */ + 0x09, /* Maxpacket size for EP0 : 2^9 */ + 0xB4,0x04, /* Vendor ID */ + 0xF0,0x00, /* Product ID */ + 0x00,0x00, /* Device release number */ + 0x01, /* Manufacture string index */ + 0x02, /* Product string index */ + 0x03, /* Serial number string index */ + 0x01 /* Number of configurations */ +}; + +/* Standard Device Qualifier Descriptor */ +const unsigned char common_dev_qual_desc[] = +{ + 0x0A, /* Descriptor size */ + 0x06,/* CY_U3P_USB_DEVQUAL_DESCR Device qualifier descriptor type */ + 0x00,0x02, /* USB 2.0 */ + 0xFF, /* Device class */ + 0x00, /* Device sub-class */ + 0x00, /* Device protocol */ + 0x40, /* Maxpacket size for EP0 : 64 bytes */ + 0x01, /* Number of configurations */ + 0x00 /* Reserved */ +}; + +/* Standard Binary Device Object Store Descriptor */ +const unsigned char common_usb_bos_desc[] = +{ + 0x05, /* Descriptor size */ + 0x0F,/* CY_U3P_BOS_DESCR Device descriptor type */ + 0x16,0x00, /* Length of this descriptor and all sub descriptors */ + 0x02, /* Number of device capability descriptors */ + + /* USB 2.0 extension */ + 0x07, /* Descriptor size */ + 0x10,/* CY_U3P_DEVICE_CAPB_DESCR Device capability type descriptor */ + 0x02,/* CY_U3P_USB2_EXTN_CAPB_TYPE USB 2.0 extension capability type */ + 0x02,0x00,0x00,0x00, /* Supported device level features: LPM support */ + + /* SuperSpeed device capability */ + 0x0A, /* Descriptor size */ + 0x10,/* CY_U3P_DEVICE_CAPB_DESCR Device capability type descriptor */ + 0x03,/* CY_U3P_SS_USB_CAPB_TYPE SuperSpeed device capability type */ + 0x00, /* Supported device level features */ + 0x0E,0x00, /* Speeds supported by the device : SS, HS and FS */ + 0x03, /* Functionality support */ + 0x00, /* U1 Device Exit latency */ + 0x00,0x00 /* U2 Device Exit latency */ +}; + +/* Standard Language ID String Descriptor */ +const unsigned char common_string_lang_id_desc[] = +{ + 0x04, /* Descriptor Size */ + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ + 0x09,0x04 /* Language ID supported */ +}; + + +/* Ettus Manufacturer String Descriptor */ +const unsigned char common_ettus_manufacturer_desc[] = +{ + 0x26, /* Descriptor Size */ + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ + 'E',0x00, + 't',0x00, + 't',0x00, + 'u',0x00, + 's',0x00, + ' ',0x00, + 'R',0x00, + 'e',0x00, + 's',0x00, + 'e',0x00, + 'a',0x00, + 'r',0x00, + 'c',0x00, + 'h',0x00, + ' ',0x00, + 'L',0x00, + 'L',0x00, + 'C',0x00 +}; + +/* NI Manufacturer String Descriptor */ +const unsigned char common_ni_manufacturer_desc[] = +{ + 0x36, /* Descriptor Size */ + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ + 'N',0x00, + 'a',0x00, + 't',0x00, + 'i',0x00, + 'o',0x00, + 'n',0x00, + 'a',0x00, + 'l',0x00, + ' ',0x00, + 'I',0x00, + 'n',0x00, + 's',0x00, + 't',0x00, + 'r',0x00, + 'u',0x00, + 'm',0x00, + 'e',0x00, + 'n',0x00, + 't',0x00, + 's',0x00, + ' ',0x00, + 'C',0x00, + 'o',0x00, + 'r',0x00, + 'p',0x00, + '.',0x00 +}; + + +/* Ettus Product String Descriptor */ +const unsigned char common_b200_product_desc[] = +{ + 0x14, /* Descriptor Size */ + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ + 'U',0x00, + 'S',0x00, + 'R',0x00, + 'P',0x00, + ' ',0x00, + 'B',0x00, + '2',0x00, + '0',0x00, + '0',0x00 +}; + +/* NI-USRP 2900 Product String Descriptor */ +const unsigned char common_niusrp_2900_product_desc[] = +{ + 0x1A, /* Descriptor Size */ + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ + 'N',0x00, + 'I',0x00, + ' ',0x00, + 'U',0x00, + 'S',0x00, + 'R',0x00, + 'P',0x00, + '-',0x00, + '2',0x00, + '9',0x00, + '0',0x00, + '0',0x00 +}; + +/* NI-USRP 2901 Product String Descriptor */ +const unsigned char common_niusrp_2901_product_desc[] = +{ + 0x1A, /* Descriptor Size */ + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ + 'N',0x00, + 'I',0x00, + ' ',0x00, + 'U',0x00, + 'S',0x00, + 'R',0x00, + 'P',0x00, + '-',0x00, + '2',0x00, + '9',0x00, + '0',0x00, + '1',0x00 +}; + +/* Unknown Product String Descriptor */ +const unsigned char common_unknown_desc[] = +{ + 0x10, /* Descriptor Size */ + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ + 'U',0x00, + 'n',0x00, + 'k',0x00, + 'n',0x00, + 'o',0x00, + 'w',0x00, + 'n',0x00 +}; + +unsigned char common_dev_serial_desc[] = +{ + 0x14, /* Descriptor Size */ + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00, + '0', 0x00 +}; diff --git a/firmware/fx3/b200/common/common_descriptors.h b/firmware/fx3/b200/common/common_descriptors.h new file mode 100644 index 000000000..15acac3fa --- /dev/null +++ b/firmware/fx3/b200/common/common_descriptors.h @@ -0,0 +1,50 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef _COMMON_DESCRIPTORS_H +#define _COMMON_DESCRIPTORS_H + +/* This file contains all descriptors that are common between the bootloader + and firmware code. Non-const descriptors are modified at runtime based on + information read from the EEPROM. */ + +/* Standard Device Descriptor for USB 2.0 */ +extern unsigned char common_usb2_dev_desc[]; + +/* Standard Device Descriptor for USB 3.0 */ +extern unsigned char common_usb3_dev_desc[]; + +/* Standard Device Qualifier Descriptor */ +extern const unsigned char common_dev_qual_desc[]; + +/* Standard Binary Device Object Store Descriptor */ +extern const unsigned char common_usb_bos_desc[]; + +/* Standard Language ID String Descriptor */ +extern const unsigned char common_string_lang_id_desc[]; + +/* Ettus Manufacturer String Descriptor */ +extern const unsigned char common_ettus_manufacturer_desc[]; + +/* NI Manufacturer String Descriptor */ +extern const unsigned char common_ni_manufacturer_desc[]; + +/* Ettus Product String Descriptor */ +extern const unsigned char common_b200_product_desc[]; + +/* NI-USRP 2900 Product String Descriptor */ +extern const unsigned char common_niusrp_2900_product_desc[]; + +/* NI-USRP 2901 Product String Descriptor */ +extern const unsigned char common_niusrp_2901_product_desc[]; + +/* Unknown Product String Descriptor */ +extern const unsigned char common_unknown_desc[]; + +/* Common Serial String Descriptor */ +extern unsigned char common_dev_serial_desc[]; + +#endif
\ No newline at end of file diff --git a/firmware/fx3/b200/common/common_helpers.c b/firmware/fx3/b200/common/common_helpers.c new file mode 100644 index 000000000..5a21a2106 --- /dev/null +++ b/firmware/fx3/b200/common/common_helpers.c @@ -0,0 +1,199 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include "common_helpers.h" +#include "common_const.h" +#include "common_descriptors.h" + +#define UNREAD 0xFFFF + +/* Check the rev, magic value, and eeprom compatibility field to determine if + our eeprom map is up-to-date with what is written on the device */ +int eeprom_is_readable(eeprom_read_t read_fn) { + /* Only check this once, then store that info */ + static int is_readable = UNREAD; + + if (is_readable != UNREAD) { + return is_readable; + } + + int rev = get_rev(read_fn); + + if (rev == EEPROM_REV_UNRECOGNIZED) + { + is_readable = 0; + return is_readable; + } + + + /* If rev is 0, there's no further checks available */ + if (rev == 0) + { + is_readable = 1; + return is_readable; + } + + /* For rev 1, check the EEPROM magic value and compat number */ + + if (rev == 1) { + { + uint8_t buffer[EEPROM_MAGIC_LENGTH]; + read_fn(EEPROM_REV1_MAGIC_ADDR, buffer, EEPROM_MAGIC_LENGTH); + if ((buffer[1] << 8 | buffer[0]) != EEPROM_EXPECTED_MAGIC) { + is_readable = 0; + return is_readable; + } + } + { + uint8_t buffer[EEPROM_COMPAT_LENGTH]; + read_fn(EEPROM_REV1_COMPAT_ADDR, buffer, EEPROM_COMPAT_LENGTH); + if ((buffer[1] << 8 | buffer[0]) > EEPROM_EXPECTED_COMPAT) { + is_readable = 0; + return is_readable; + } + } + is_readable = 1; + return is_readable; + } + + /* some other unrecognized rev */ + is_readable = 0; + return is_readable; +} + +/* Read the EEPROM layout revision number from EEPROM using the function + specified */ +int get_rev(eeprom_read_t read_fn) +{ + /* Only check the rev once, then store that info */ + static int rev = UNREAD; + + if (rev != UNREAD) { + return rev; + } + + uint8_t buffer[EEPROM_SIGNATURE_LENGTH]; + read_fn(EEPROM_SIGNATURE_ADDR, buffer, EEPROM_SIGNATURE_LENGTH); + + const uint32_t signature = buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 + | buffer[0]; + if (signature == EEPROM_REV0_SIGNATURE) { + rev = 0; + } else if (signature == EEPROM_REV1_OR_GREATER_SIGNATURE) { + rev = 1; + } else { + rev = EEPROM_REV_UNRECOGNIZED; + } + return rev; +} + + + +/* Read the vendor ID from EEPROM using the function specified*/ +uint16_t get_vid(eeprom_read_t read_fn) +{ + static uint16_t vid = UNREAD; + + if (vid != UNREAD) { + return vid; + } + + if (!eeprom_is_readable(read_fn)) { + vid = VID_CYPRESS; + return vid; + } + + // eeprom_is_readable guarantees rev is valid + int rev = get_rev(read_fn); + + const uint16_t addr = (rev == 0) ? EEPROM_REV0_VID_ADDR : EEPROM_REV1_VID_ADDR; + + uint8_t buffer[EEPROM_VID_LENGTH]; + read_fn(addr, buffer, EEPROM_VID_LENGTH); + vid = buffer[1] << 8 | buffer[0]; + return vid; +} + +/* Read the product ID from EEPROM using the function specified*/ +uint16_t get_pid(eeprom_read_t read_fn) +{ + static uint16_t pid = UNREAD; + + if (pid != UNREAD) { + return pid; + } + + if (!eeprom_is_readable(read_fn)) { + pid = PID_CYPRESS_DEFAULT; + return pid; + } + + // eeprom_is_readable guarantees rev is valid + int rev = get_rev(read_fn); + + const uint16_t addr = (rev == 0) ? EEPROM_REV0_PID_ADDR : EEPROM_REV1_PID_ADDR; + + uint8_t buffer[EEPROM_PID_LENGTH]; + read_fn(addr, buffer, EEPROM_PID_LENGTH); + pid = buffer[1] << 8 | buffer[0]; + return pid; +} + +/* Read the vendor ID from EEPROM using the function specified */ +const uint8_t* get_serial_string_descriptor(eeprom_read_t read_fn) +{ + static uint8_t* serial_string_descriptor = 0; + if (serial_string_descriptor) { + return serial_string_descriptor; + } + + /* All code paths will eventually return this value, but some will modify + it beforehand */ + serial_string_descriptor = common_dev_serial_desc; + + if (!eeprom_is_readable(read_fn)) { + return serial_string_descriptor; + } + + // eeprom_is_readable guarantees rev is valid + int rev = get_rev(read_fn); + + const uint16_t addr = (rev == 0) ? EEPROM_REV0_SERIAL_ADDR : EEPROM_REV1_SERIAL_ADDR; + + uint8_t buffer[EEPROM_SERIAL_LENGTH]; + read_fn(addr, buffer, EEPROM_SERIAL_LENGTH); + int i; + for (i = 0; i < EEPROM_SERIAL_LENGTH; ++i) { + common_dev_serial_desc[2 + i * 2] = buffer[i]; + } + return serial_string_descriptor; +} + +/* Return the string descriptor based on the VID given */ +const uint8_t* get_manufacturer_string_descriptor(uint16_t vid) +{ + if (vid == VID_ETTUS_RESEARCH) { + return common_ettus_manufacturer_desc; + } else if (vid == VID_NATIONAL_INSTRUMENTS) { + return common_ni_manufacturer_desc; + } else { + return common_unknown_desc; + } +} + +/* Return the string descriptor based on the PID given */ +const uint8_t* get_product_string_descriptor(uint16_t pid) +{ + if (pid == PID_ETTUS_B200_B210) { + return common_b200_product_desc; + } else if (pid == PID_NI_USRP_2900) { + return common_niusrp_2900_product_desc; + } else if (pid == PID_NI_USRP_2901) { + return common_niusrp_2901_product_desc; + } else { + return common_unknown_desc; + } +} diff --git a/firmware/fx3/b200/common/common_helpers.h b/firmware/fx3/b200/common/common_helpers.h new file mode 100644 index 000000000..8ff28fb09 --- /dev/null +++ b/firmware/fx3/b200/common/common_helpers.h @@ -0,0 +1,34 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef _COMMON_HELPERS_H +#define _COMMON_HELPERS_H + +#include "cyu3types.h" + +typedef void (*eeprom_read_t)(uint16_t, uint8_t*, uint8_t); + +/* Read the EEPROM layout revision number from EEPROM using the function + specified */ +int get_rev(eeprom_read_t read_fn); + +/* Read the vendor ID from EEPROM using the function specified*/ +uint16_t get_vid(eeprom_read_t read_fn); + +/* Read the product ID from EEPROM using the function specified*/ +uint16_t get_pid(eeprom_read_t read_fn); + +/* Read the vendor ID from EEPROM using the function specified + Buffer must be at least length 20 */ +const uint8_t* get_serial_string_descriptor(eeprom_read_t read_fn); + +/* Return the string descriptor based on the VID given */ +const uint8_t* get_manufacturer_string_descriptor(uint16_t vid); + +/* Return the string descriptor based on the PID given */ +const uint8_t* get_product_string_descriptor(uint16_t pid); + +#endif /* _COMMON_HELPERS_H */ diff --git a/firmware/fx3/b200/b200_main.h b/firmware/fx3/b200/firmware/b200_const.h index ddcc504b5..886643021 100644 --- a/firmware/fx3/b200/b200_main.h +++ b/firmware/fx3/b200/firmware/b200_const.h @@ -1,9 +1,12 @@ // // Copyright 2013-2014 Ettus Research LLC +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later // -#ifndef _B200_MAIN_H -#define _B200_MAIN_H +#ifndef _B200_CONST_H +#define _B200_CONST_H #include "cyu3externcstart.h" @@ -116,25 +119,6 @@ #define CTRL_COMM_PPORT_SOCKET CY_U3P_PIB_SOCKET_2 #define CTRL_RESP_PPORT_SOCKET CY_U3P_PIB_SOCKET_3 - -/* Descriptor definitions for USB enumerations. */ -extern uint8_t b200_usb2_dev_desc[]; -extern uint8_t b200_usb3_dev_desc[]; -extern const uint8_t b200_dev_qual_desc[]; -extern const uint8_t b200_usb_fs_config_desc[]; -extern const uint8_t b200_usb_hs_config_desc[]; -extern const uint8_t b200_usb_bos_desc[]; -extern const uint8_t b200_usb_ss_config_desc[]; -extern const uint8_t b200_string_lang_id_desc[]; -extern const uint8_t b200_usb_manufacture_desc[]; -extern const uint8_t b200_usb_product_desc[]; -extern const uint8_t niusrp_usb_manufacture_desc[]; -extern const uint8_t niusrp_2900_usb_product_desc[]; -extern const uint8_t niusrp_2901_usb_product_desc[]; -extern const uint8_t unknown_desc[]; -extern uint8_t dev_serial[]; - - #include "cyu3externcend.h" -#endif /* _B200_MAIN_H */ +#endif /* _B200_CONST_H */ diff --git a/firmware/fx3/b200/b200_gpifconfig.h b/firmware/fx3/b200/firmware/b200_gpifconfig.h index a6a24e0c5..aa1c36551 100755..100644 --- a/firmware/fx3/b200/b200_gpifconfig.h +++ b/firmware/fx3/b200/firmware/b200_gpifconfig.h @@ -1,176 +1,176 @@ -/*
- * Project Name: ssf2-edit.cyfx
- * Time : 11/17/2014 13:01:01
- * Device Type: FX3
- * Project Type: GPIF2
- *
- *
- *
- *
- * This is a generated file and should not be modified
- * This file need to be included only once in the firmware
- * This file is generated by Gpif2 designer tool version - 1.0.837.1
- *
- */
-
-#ifndef _INCLUDED_CYFXGPIF2CONFIG_
-#define _INCLUDED_CYFXGPIF2CONFIG_
-#include "cyu3types.h"
-#include "cyu3gpif.h"
-
-/* Summary
- Number of states in the state machine
- */
-#define CY_NUMBER_OF_STATES 7
-
-/* Summary
- Mapping of user defined state names to state indices
- */
-#define RESET 0
-#define IDLE 1
-#define READ 2
-#define WRITE 3
-#define SHORT_PKT 4
-#define ZLP 5
-#define DSS_STATE 6
-
-
-/* Summary
- Initial value of early outputs from the state machine.
- */
-#define ALPHA_RESET 0xC
-
-
-/* Summary
- Transition function values used in the state machine.
- */
-uint16_t CyFxGpifTransition[] = {
- 0x0000, 0x8080, 0x2222, 0x5555, 0x7F7F, 0x1F1F, 0x8888
-};
-
-/* Summary
- Table containing the transition information for various states.
- This table has to be stored in the WAVEFORM Registers.
- This array consists of non-replicated waveform descriptors and acts as a
- waveform table.
- */
-CyU3PGpifWaveData CyFxGpifWavedata[] = {
- {{0x1E086001,0x000302C4,0x80000000},{0x00000000,0x00000000,0x00000000}},
- {{0x4E080302,0x00000300,0x80000000},{0x1E086006,0x000302C4,0x80000000}},
- {{0x1E086001,0x000302C4,0x80000000},{0x4E040704,0x20000300,0xC0100000}},
- {{0x4E080302,0x00000300,0x80000000},{0x1E086001,0x000302C4,0x80000000}},
- {{0x00000000,0x00000000,0x00000000},{0x00000000,0x00000000,0x00000000}},
- {{0x00000000,0x00000000,0x00000000},{0x3E738705,0x00000300,0xC0100000}},
- {{0x00000000,0x00000000,0x00000000},{0x5E002703,0x2003030C,0x80000000}},
- {{0x00000000,0x00000000,0x00000000},{0x4E040704,0x20000300,0xC0100000}}
-};
-
-/* Summary
- Table that maps state indices to the descriptor table indices.
- */
-uint8_t CyFxGpifWavedataPosition[] = {
- 0,1,0,2,0,0,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 0,5,0,2,0,0,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 0,6,0,2,0,0,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 0,7,0,2,0,0,7
-};
-
-/* Summary
- GPIF II configuration register values.
- */
-uint32_t CyFxGpifRegValue[] = {
- 0x80000380, /* CY_U3P_PIB_GPIF_CONFIG */
- 0x000010AC, /* CY_U3P_PIB_GPIF_BUS_CONFIG */
- 0x01070002, /* CY_U3P_PIB_GPIF_BUS_CONFIG2 */
- 0x00000044, /* CY_U3P_PIB_GPIF_AD_CONFIG */
- 0x00000000, /* CY_U3P_PIB_GPIF_STATUS */
- 0x00000000, /* CY_U3P_PIB_GPIF_INTR */
- 0x00000000, /* CY_U3P_PIB_GPIF_INTR_MASK */
- 0x00000082, /* CY_U3P_PIB_GPIF_SERIAL_IN_CONFIG */
- 0x00000782, /* CY_U3P_PIB_GPIF_SERIAL_OUT_CONFIG */
- 0x00000500, /* CY_U3P_PIB_GPIF_CTRL_BUS_DIRECTION */
- 0x0000FFCF, /* CY_U3P_PIB_GPIF_CTRL_BUS_DEFAULT */
- 0x000000BF, /* CY_U3P_PIB_GPIF_CTRL_BUS_POLARITY */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_TOGGLE */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000018, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000019, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */
- 0x00000006, /* CY_U3P_PIB_GPIF_CTRL_COUNT_CONFIG */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_COUNT_RESET */
- 0x0000FFFF, /* CY_U3P_PIB_GPIF_CTRL_COUNT_LIMIT */
- 0x0000010A, /* CY_U3P_PIB_GPIF_ADDR_COUNT_CONFIG */
- 0x00000000, /* CY_U3P_PIB_GPIF_ADDR_COUNT_RESET */
- 0x0000FFFF, /* CY_U3P_PIB_GPIF_ADDR_COUNT_LIMIT */
- 0x00000000, /* CY_U3P_PIB_GPIF_STATE_COUNT_CONFIG */
- 0x0000FFFF, /* CY_U3P_PIB_GPIF_STATE_COUNT_LIMIT */
- 0x0000010A, /* CY_U3P_PIB_GPIF_DATA_COUNT_CONFIG */
- 0x00000000, /* CY_U3P_PIB_GPIF_DATA_COUNT_RESET */
- 0x0000FFFF, /* CY_U3P_PIB_GPIF_DATA_COUNT_LIMIT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_COMP_VALUE */
- 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_COMP_MASK */
- 0x00000000, /* CY_U3P_PIB_GPIF_DATA_COMP_VALUE */
- 0x00000000, /* CY_U3P_PIB_GPIF_DATA_COMP_MASK */
- 0x00000000, /* CY_U3P_PIB_GPIF_ADDR_COMP_VALUE */
- 0x00000000, /* CY_U3P_PIB_GPIF_ADDR_COMP_MASK */
- 0x00000000, /* CY_U3P_PIB_GPIF_DATA_CTRL */
- 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_DATA */
- 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_DATA */
- 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_DATA */
- 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_DATA */
- 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_DATA */
- 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_DATA */
- 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_DATA */
- 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_DATA */
- 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_ADDRESS */
- 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_ADDRESS */
- 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_ADDRESS */
- 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_ADDRESS */
- 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_ADDRESS */
- 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_ADDRESS */
- 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_ADDRESS */
- 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_ADDRESS */
- 0x80010400, /* CY_U3P_PIB_GPIF_THREAD_CONFIG */
- 0x80010401, /* CY_U3P_PIB_GPIF_THREAD_CONFIG */
- 0x80010402, /* CY_U3P_PIB_GPIF_THREAD_CONFIG */
- 0x80010403, /* CY_U3P_PIB_GPIF_THREAD_CONFIG */
- 0x00000000, /* CY_U3P_PIB_GPIF_LAMBDA_STAT */
- 0x00000000, /* CY_U3P_PIB_GPIF_ALPHA_STAT */
- 0x00000000, /* CY_U3P_PIB_GPIF_BETA_STAT */
- 0x000C0000, /* CY_U3P_PIB_GPIF_WAVEFORM_CTRL_STAT */
- 0x00000000, /* CY_U3P_PIB_GPIF_WAVEFORM_SWITCH */
- 0x00000000, /* CY_U3P_PIB_GPIF_WAVEFORM_SWITCH_TIMEOUT */
- 0x00000000, /* CY_U3P_PIB_GPIF_CRC_CONFIG */
- 0x00000000, /* CY_U3P_PIB_GPIF_CRC_DATA */
- 0xFFFFFFC1 /* CY_U3P_PIB_GPIF_BETA_DEASSERT */
-};
-
-/* Summary
- This structure holds all the configuration inputs for the GPIF II.
- */
-const CyU3PGpifConfig_t CyFxGpifConfig = {
- (uint16_t)(sizeof(CyFxGpifWavedataPosition)/sizeof(uint8_t)),
- CyFxGpifWavedata,
- CyFxGpifWavedataPosition,
- (uint16_t)(sizeof(CyFxGpifTransition)/sizeof(uint16_t)),
- CyFxGpifTransition,
- (uint16_t)(sizeof(CyFxGpifRegValue)/sizeof(uint32_t)),
- CyFxGpifRegValue
-};
-
-#endif /* _INCLUDED_CYFXGPIF2CONFIG_ */
+/* + * Project Name: ssf2-edit.cyfx + * Time : 11/17/2014 13:01:01 + * Device Type: FX3 + * Project Type: GPIF2 + * + * + * + * + * This is a generated file and should not be modified + * This file need to be included only once in the firmware + * This file is generated by Gpif2 designer tool version - 1.0.837.1 + * + */ + +#ifndef _INCLUDED_CYFXGPIF2CONFIG_ +#define _INCLUDED_CYFXGPIF2CONFIG_ +#include "cyu3types.h" +#include "cyu3gpif.h" + +/* Summary + Number of states in the state machine + */ +#define CY_NUMBER_OF_STATES 7 + +/* Summary + Mapping of user defined state names to state indices + */ +#define RESET 0 +#define IDLE 1 +#define READ 2 +#define WRITE 3 +#define SHORT_PKT 4 +#define ZLP 5 +#define DSS_STATE 6 + + +/* Summary + Initial value of early outputs from the state machine. + */ +#define ALPHA_RESET 0xC + + +/* Summary + Transition function values used in the state machine. + */ +uint16_t CyFxGpifTransition[] = { + 0x0000, 0x8080, 0x2222, 0x5555, 0x7F7F, 0x1F1F, 0x8888 +}; + +/* Summary + Table containing the transition information for various states. + This table has to be stored in the WAVEFORM Registers. + This array consists of non-replicated waveform descriptors and acts as a + waveform table. + */ +CyU3PGpifWaveData CyFxGpifWavedata[] = { + {{0x1E086001,0x000302C4,0x80000000},{0x00000000,0x00000000,0x00000000}}, + {{0x4E080302,0x00000300,0x80000000},{0x1E086006,0x000302C4,0x80000000}}, + {{0x1E086001,0x000302C4,0x80000000},{0x4E040704,0x20000300,0xC0100000}}, + {{0x4E080302,0x00000300,0x80000000},{0x1E086001,0x000302C4,0x80000000}}, + {{0x00000000,0x00000000,0x00000000},{0x00000000,0x00000000,0x00000000}}, + {{0x00000000,0x00000000,0x00000000},{0x3E738705,0x00000300,0xC0100000}}, + {{0x00000000,0x00000000,0x00000000},{0x5E002703,0x2003030C,0x80000000}}, + {{0x00000000,0x00000000,0x00000000},{0x4E040704,0x20000300,0xC0100000}} +}; + +/* Summary + Table that maps state indices to the descriptor table indices. + */ +uint8_t CyFxGpifWavedataPosition[] = { + 0,1,0,2,0,0,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 0,5,0,2,0,0,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 0,6,0,2,0,0,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 0,7,0,2,0,0,7 +}; + +/* Summary + GPIF II configuration register values. + */ +uint32_t CyFxGpifRegValue[] = { + 0x80000380, /* CY_U3P_PIB_GPIF_CONFIG */ + 0x000010AC, /* CY_U3P_PIB_GPIF_BUS_CONFIG */ + 0x01070002, /* CY_U3P_PIB_GPIF_BUS_CONFIG2 */ + 0x00000044, /* CY_U3P_PIB_GPIF_AD_CONFIG */ + 0x00000000, /* CY_U3P_PIB_GPIF_STATUS */ + 0x00000000, /* CY_U3P_PIB_GPIF_INTR */ + 0x00000000, /* CY_U3P_PIB_GPIF_INTR_MASK */ + 0x00000082, /* CY_U3P_PIB_GPIF_SERIAL_IN_CONFIG */ + 0x00000782, /* CY_U3P_PIB_GPIF_SERIAL_OUT_CONFIG */ + 0x00000500, /* CY_U3P_PIB_GPIF_CTRL_BUS_DIRECTION */ + 0x0000FFCF, /* CY_U3P_PIB_GPIF_CTRL_BUS_DEFAULT */ + 0x000000BF, /* CY_U3P_PIB_GPIF_CTRL_BUS_POLARITY */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_TOGGLE */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000018, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000019, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_BUS_SELECT */ + 0x00000006, /* CY_U3P_PIB_GPIF_CTRL_COUNT_CONFIG */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_COUNT_RESET */ + 0x0000FFFF, /* CY_U3P_PIB_GPIF_CTRL_COUNT_LIMIT */ + 0x0000010A, /* CY_U3P_PIB_GPIF_ADDR_COUNT_CONFIG */ + 0x00000000, /* CY_U3P_PIB_GPIF_ADDR_COUNT_RESET */ + 0x0000FFFF, /* CY_U3P_PIB_GPIF_ADDR_COUNT_LIMIT */ + 0x00000000, /* CY_U3P_PIB_GPIF_STATE_COUNT_CONFIG */ + 0x0000FFFF, /* CY_U3P_PIB_GPIF_STATE_COUNT_LIMIT */ + 0x0000010A, /* CY_U3P_PIB_GPIF_DATA_COUNT_CONFIG */ + 0x00000000, /* CY_U3P_PIB_GPIF_DATA_COUNT_RESET */ + 0x0000FFFF, /* CY_U3P_PIB_GPIF_DATA_COUNT_LIMIT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_COMP_VALUE */ + 0x00000000, /* CY_U3P_PIB_GPIF_CTRL_COMP_MASK */ + 0x00000000, /* CY_U3P_PIB_GPIF_DATA_COMP_VALUE */ + 0x00000000, /* CY_U3P_PIB_GPIF_DATA_COMP_MASK */ + 0x00000000, /* CY_U3P_PIB_GPIF_ADDR_COMP_VALUE */ + 0x00000000, /* CY_U3P_PIB_GPIF_ADDR_COMP_MASK */ + 0x00000000, /* CY_U3P_PIB_GPIF_DATA_CTRL */ + 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_DATA */ + 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_DATA */ + 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_DATA */ + 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_DATA */ + 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_DATA */ + 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_DATA */ + 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_DATA */ + 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_DATA */ + 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_ADDRESS */ + 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_ADDRESS */ + 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_ADDRESS */ + 0x00000000, /* CY_U3P_PIB_GPIF_INGRESS_ADDRESS */ + 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_ADDRESS */ + 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_ADDRESS */ + 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_ADDRESS */ + 0x00000000, /* CY_U3P_PIB_GPIF_EGRESS_ADDRESS */ + 0x80010400, /* CY_U3P_PIB_GPIF_THREAD_CONFIG */ + 0x80010401, /* CY_U3P_PIB_GPIF_THREAD_CONFIG */ + 0x80010402, /* CY_U3P_PIB_GPIF_THREAD_CONFIG */ + 0x80010403, /* CY_U3P_PIB_GPIF_THREAD_CONFIG */ + 0x00000000, /* CY_U3P_PIB_GPIF_LAMBDA_STAT */ + 0x00000000, /* CY_U3P_PIB_GPIF_ALPHA_STAT */ + 0x00000000, /* CY_U3P_PIB_GPIF_BETA_STAT */ + 0x000C0000, /* CY_U3P_PIB_GPIF_WAVEFORM_CTRL_STAT */ + 0x00000000, /* CY_U3P_PIB_GPIF_WAVEFORM_SWITCH */ + 0x00000000, /* CY_U3P_PIB_GPIF_WAVEFORM_SWITCH_TIMEOUT */ + 0x00000000, /* CY_U3P_PIB_GPIF_CRC_CONFIG */ + 0x00000000, /* CY_U3P_PIB_GPIF_CRC_DATA */ + 0xFFFFFFC1 /* CY_U3P_PIB_GPIF_BETA_DEASSERT */ +}; + +/* Summary + This structure holds all the configuration inputs for the GPIF II. + */ +const CyU3PGpifConfig_t CyFxGpifConfig = { + (uint16_t)(sizeof(CyFxGpifWavedataPosition)/sizeof(uint8_t)), + CyFxGpifWavedata, + CyFxGpifWavedataPosition, + (uint16_t)(sizeof(CyFxGpifTransition)/sizeof(uint16_t)), + CyFxGpifTransition, + (uint16_t)(sizeof(CyFxGpifRegValue)/sizeof(uint32_t)), + CyFxGpifRegValue +}; + +#endif /* _INCLUDED_CYFXGPIF2CONFIG_ */ diff --git a/firmware/fx3/b200/b200_i2c.c b/firmware/fx3/b200/firmware/b200_i2c.c index c6fa67c77..c6fa67c77 100644 --- a/firmware/fx3/b200/b200_i2c.c +++ b/firmware/fx3/b200/firmware/b200_i2c.c diff --git a/firmware/fx3/b200/b200_i2c.h b/firmware/fx3/b200/firmware/b200_i2c.h index c5c781946..c5c781946 100644 --- a/firmware/fx3/b200/b200_i2c.h +++ b/firmware/fx3/b200/firmware/b200_i2c.h diff --git a/firmware/fx3/b200/b200_main.c b/firmware/fx3/b200/firmware/b200_main.c index ac4988ae0..26507dda7 100644 --- a/firmware/fx3/b200/b200_main.c +++ b/firmware/fx3/b200/firmware/b200_main.c @@ -1,5 +1,8 @@ // // Copyright 2013-2015 Ettus Research LLC +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later // /* This file defines the application that runs on the Cypress FX3 device, and @@ -10,10 +13,14 @@ #include <stdarg.h> #include <stdio.h> -#include "b200_main.h" +#include "b200_const.h" #include "b200_gpifconfig.h" #include "b200_i2c.h" +#include "common_helpers.h" +#include "common_descriptors.h" +#include "b200_usb_descriptors.h" + #include "cyu3dma.h" #include "cyu3error.h" #include "cyu3gpif.h" @@ -789,6 +796,10 @@ void reset_gpif(void) { g_fx3_state = STATE_RUNNING; } +void eeprom_read(uint16_t addr, uint8_t* buffer, uint8_t length) +{ + CyFxUsbI2cTransfer(addr, 0xA0, length, buffer, CyTrue); +} CyU3PReturnStatus_t b200_set_io_matrix(CyBool_t fpga_config_mode) { CyU3PIoMatrixConfig_t io_config_matrix; @@ -1571,13 +1582,16 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) { && (bRequest == CY_U3P_USB_SC_GET_DESCRIPTOR) \ && (wValue == ((CY_U3P_USB_STRING_DESCR << 8) | 0xEE))) { /* Make sure we do not send more data than requested. */ - if(wLength > b200_usb_product_desc[0]) { - wLength = b200_usb_product_desc[0]; + const uint8_t* product_desc = get_product_string_descriptor( + get_pid(&eeprom_read)); + if (wLength > product_desc[0]) + { + wLength = product_desc[0]; } //msg("MS string desc"); - CyU3PUsbSendEP0Data(wLength, ((uint8_t *) b200_usb_product_desc)); + CyU3PUsbSendEP0Data(wLength, ((uint8_t*)product_desc)); handled = CyTrue; } @@ -2160,7 +2174,6 @@ void b200_gpif_init(void) { CyU3PPibRegisterCallback(gpif_error_cb, CYU3P_PIB_INTR_ERROR); } - /*! Start and configure the FX3's SPI module. * * This module is used for programming the FPGA. After the FPGA is configured, @@ -2222,115 +2235,66 @@ void b200_usb_init(void) { CyU3PUsbRegisterLPMRequestCallback(lpm_request_callback); /* Check to see if a VID/PID is in the EEPROM that we should use. */ - uint8_t valid[4]; - uint8_t vidpid[4]; - CyU3PMemSet(valid, 0, 4); - CyFxUsbI2cTransfer(0x0, 0xA0, 4, valid, CyTrue); - if(*((uint32_t *) &(valid[0])) == 0xB2145943) { - - /* Pull the programmed device serial out of the i2c EEPROM, and copy the - * characters into the device serial string, which is then advertised as - * part of the USB descriptors. */ - CyU3PMemSet(vidpid, 0, 4); - CyFxUsbI2cTransfer(0x4, 0xA0, 4, vidpid, CyTrue); - b200_usb2_dev_desc[8] = vidpid[2]; - b200_usb2_dev_desc[9] = vidpid[3]; - b200_usb2_dev_desc[10] = vidpid[0]; - b200_usb2_dev_desc[11] = vidpid[1]; - - b200_usb3_dev_desc[8] = vidpid[2]; - b200_usb3_dev_desc[9] = vidpid[3]; - b200_usb3_dev_desc[10] = vidpid[0]; - b200_usb3_dev_desc[11] = vidpid[1]; - } + const uint16_t vid = get_vid(&eeprom_read); + const uint16_t pid = get_pid(&eeprom_read); - /* We support two VIDs: - * Ettus Research: 0x2500 - * National Instruments: 0x3923 - * - * We support three PIDs: - * Ettus B200/B210: 0x0020 - * NI USRP-2900: 0x7813 - * NI USRP-2901: 0x7814 - */ - uint8_t *mfr_string = NULL; - uint8_t *product_string = NULL; - if((vidpid[3] == 0x25) && (vidpid[2] == 0x00)) { - mfr_string = b200_usb_manufacture_desc; - product_string = b200_usb_product_desc; - } else if((vidpid[3] == 0x39) && (vidpid[2] == 0x23)) { - mfr_string = niusrp_usb_manufacture_desc; - - if((vidpid[1] == 0x78) && (vidpid[0] == 0x13)) { - product_string = niusrp_2900_usb_product_desc; - } else if((vidpid[1] == 0x78) && (vidpid[0] == 0x14)) { - product_string = niusrp_2901_usb_product_desc; - } else { - product_string = unknown_desc; - } - } else { - mfr_string = unknown_desc; - product_string = unknown_desc; - } + 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; - uint8_t ascii_serial[9]; - CyU3PMemSet(ascii_serial, 0, 9); - CyFxUsbI2cTransfer(0x4f7, 0xA0, 9, ascii_serial, CyTrue); - uint8_t count; - dev_serial[0] = 2; - for(count = 0; count < 9; count++) { - uint8_t byte = ascii_serial[count]; - if (byte < 32 || byte > 127) break; - dev_serial[2 + (count * 2)] = byte; - // FIXME: Set count*2 + 1 = 0x00 ? - dev_serial[0] += 2; - } + 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; + + const uint8_t *mfr_string = get_manufacturer_string_descriptor(vid); + const uint8_t *product_string = get_product_string_descriptor(pid); + const uint8_t *serial_string = get_serial_string_descriptor(&eeprom_read); /* Set our USB enumeration descriptors! Note that there are different * function calls for each USB speed: FS, HS, SS. */ /* Device descriptors */ CyU3PUsbSetDesc(CY_U3P_USB_SET_HS_DEVICE_DESCR, 0, - (uint8_t *) b200_usb2_dev_desc); + (uint8_t *)common_usb2_dev_desc); CyU3PUsbSetDesc(CY_U3P_USB_SET_SS_DEVICE_DESCR, 0, - (uint8_t *) b200_usb3_dev_desc); + (uint8_t *)common_usb3_dev_desc); /* Device qualifier descriptors */ CyU3PUsbSetDesc(CY_U3P_USB_SET_DEVQUAL_DESCR, 0, - (uint8_t *) b200_dev_qual_desc); + (uint8_t *)common_dev_qual_desc); /* Configuration descriptors */ CyU3PUsbSetDesc(CY_U3P_USB_SET_HS_CONFIG_DESCR, 0, - (uint8_t *) b200_usb_hs_config_desc); + (uint8_t *)b200_usb_hs_config_desc); CyU3PUsbSetDesc(CY_U3P_USB_SET_FS_CONFIG_DESCR, 0, - (uint8_t *) b200_usb_fs_config_desc); + (uint8_t *)b200_usb_fs_config_desc); CyU3PUsbSetDesc(CY_U3P_USB_SET_SS_CONFIG_DESCR, 0, - (uint8_t *) b200_usb_ss_config_desc); + (uint8_t *)b200_usb_ss_config_desc); /* BOS Descriptor */ CyU3PUsbSetDesc(CY_U3P_USB_SET_SS_BOS_DESCR, 0, - (uint8_t *) b200_usb_bos_desc); + (uint8_t *)common_usb_bos_desc); /* String descriptors */ CyU3PUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 0, - (uint8_t *) b200_string_lang_id_desc); + (uint8_t *)common_string_lang_id_desc); CyU3PUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 1, - (uint8_t *) mfr_string); + (uint8_t *)mfr_string); CyU3PUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 2, - (uint8_t *) product_string); + (uint8_t *)product_string); CyU3PUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 3, - (uint8_t *) dev_serial); + (uint8_t *)serial_string); //////////////////////////////////////////////////////// - // FIXME: CyU3PUsbSetTxDeemphasis(0x11); <0x1F // Shouldn't need to change this - const uint32_t tx_swing = g_config.tx_swing/*65*//*45*/; // 65 & 45 are OK, 120 causes much link recovery. <128. 1.2V is USB3 limit. if (CyU3PUsbSetTxSwing(tx_swing) == CY_U3P_SUCCESS) msg("CyU3PUsbSetTxSwing: %d", tx_swing); diff --git a/firmware/fx3/b200/b200_usb_descriptors.c b/firmware/fx3/b200/firmware/b200_usb_descriptors.c index 53979219b..30e6d876c 100644 --- a/firmware/fx3/b200/b200_usb_descriptors.c +++ b/firmware/fx3/b200/firmware/b200_usb_descriptors.c @@ -1,97 +1,16 @@ // // Copyright 2013-2015 Ettus Research LLC +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later // -/* Define the USB 2.0 and USB 3.0 enumeration descriptions for the USRP B200 - * device. */ - - -#include "b200_main.h" - - -/* Standard Device Descriptor for USB 2.0 */ -uint8_t b200_usb2_dev_desc[] __attribute__ ((aligned (32))) = -{ - 0x12, /* Descriptor size */ - CY_U3P_USB_DEVICE_DESCR, /* Device descriptor type */ - 0x10,0x02, /* USB 2.10 */ - 0xFF, /* Device class */ - 0x00, /* Device sub-class */ - 0x00, /* Device protocol */ - 0x40, /* Maxpacket size for EP0 : 64 bytes */ - 0xB4,0x04, /* Vendor ID */ - 0xF0,0x00, /* Product ID */ - 0x00,0x00, /* Device release number */ - 0x01, /* Manufacture string index */ - 0x02, /* Product string index */ - 0x03, /* Serial number string index */ - 0x01 /* Number of configurations */ -}; - - -/* Standard Device Descriptor for USB 3.0 */ -uint8_t b200_usb3_dev_desc[] __attribute__ ((aligned (32))) = -{ - 0x12, /* Descriptor size */ - CY_U3P_USB_DEVICE_DESCR, /* Device descriptor type */ - 0x00,0x03, /* USB 3.0 */ - 0xFF, /* Device class */ - 0x00, /* Device sub-class */ - 0x00, /* Device protocol */ - 0x09, /* Maxpacket size for EP0 : 2^9 */ - 0xB4,0x04, /* Vendor ID */ - 0xF0,0x00, /* Product ID */ - 0x00,0x00, /* Device release number */ - 0x01, /* Manufacture string index */ - 0x02, /* Product string index */ - 0x03, /* Serial number string index */ - 0x01 /* Number of configurations */ -}; - - -/* Binary Device Object Store Descriptor */ -const uint8_t b200_usb_bos_desc[] __attribute__ ((aligned (32))) = -{ - 0x05, /* Descriptor size */ - CY_U3P_BOS_DESCR, /* Device descriptor type */ - 0x16,0x00, /* Length of this descriptor and all sub descriptors */ - 0x02, /* Number of device capability descriptors */ - - /* USB 2.0 extension */ - 0x07, /* Descriptor size */ - CY_U3P_DEVICE_CAPB_DESCR, /* Device capability type descriptor */ - CY_U3P_USB2_EXTN_CAPB_TYPE, /* USB 2.0 extension capability type */ - 0x02,0x00,0x00,0x00, /* Supported device level features: LPM support */ - - /* SuperSpeed device capability */ - 0x0A, /* Descriptor size */ - CY_U3P_DEVICE_CAPB_DESCR, /* Device capability type descriptor */ - CY_U3P_SS_USB_CAPB_TYPE, /* SuperSpeed device capability type */ - 0x00, /* Supported device level features */ - 0x0E,0x00, /* Speeds supported by the device : SS, HS and FS */ - 0x03, /* Functionality support */ - 0x00, /* U1 Device Exit latency */ - 0x00,0x00 /* U2 Device Exit latency */ -}; - - -/* Standard Device Qualifier Descriptor */ -const uint8_t b200_dev_qual_desc[] __attribute__ ((aligned (32))) = -{ - 0x0A, /* Descriptor size */ - CY_U3P_USB_DEVQUAL_DESCR, /* Device qualifier descriptor type */ - 0x00,0x02, /* USB 2.0 */ - 0xFF, /* Device class */ - 0x00, /* Device sub-class */ - 0x00, /* Device protocol */ - 0x40, /* Maxpacket size for EP0 : 64 bytes */ - 0x01, /* Number of configurations */ - 0x00 /* Reserved */ -}; +/* Firmware's unique config and string descriptors */ +#include "b200_const.h" -/* Standard Full Speed Configuration Descriptor */ -const uint8_t b200_usb_fs_config_desc[] __attribute__ ((aligned (32))) = +/* Firmware Full Speed Configuration Descriptor */ +const uint8_t b200_usb_fs_config_desc[] = { /* Configuration descriptor */ 0x09, /* Descriptor size */ @@ -192,8 +111,8 @@ const uint8_t b200_usb_fs_config_desc[] __attribute__ ((aligned (32))) = }; -/* Standard High Speed Configuration Descriptor */ -const uint8_t b200_usb_hs_config_desc[] __attribute__ ((aligned (32))) = +/* Firmware High Speed Configuration Descriptor */ +const uint8_t b200_usb_hs_config_desc[] = { /* Configuration descriptor */ 0x09, /* Descriptor size */ @@ -294,8 +213,8 @@ const uint8_t b200_usb_hs_config_desc[] __attribute__ ((aligned (32))) = }; -/* Standard Super Speed Configuration Descriptor */ -const uint8_t b200_usb_ss_config_desc[] __attribute__ ((aligned (32))) = +/* Firmware Super Speed Configuration Descriptor */ +const uint8_t b200_usb_ss_config_desc[] = { /* Configuration descriptor */ 0x09, /* Descriptor size */ @@ -423,256 +342,11 @@ const uint8_t b200_usb_ss_config_desc[] __attribute__ ((aligned (32))) = 0x00,0x00 /* Service interval for the EP : 0 for bulk */ }; - -const uint8_t b200_usb_ss_config_desc_new[] __attribute__ ((aligned (32))) = -{ - /* Configuration descriptor */ - 0x09, /* Descriptor size */ - CY_U3P_USB_CONFIG_DESCR, /* Configuration descriptor type */ - 0x4F,0x00, /* Length of this descriptor and all sub descriptors */ - 0x02, /* Number of interfaces */ - 0x01, /* Configuration number */ - 0x00, /* COnfiguration string index */ - 0x80, /* Config characteristics - D6: Self power; D5: Remote wakeup */ - 0x01, /* Lie about the max power consumption (in 8mA unit) : 8mA */ - - /* Interface descriptor */ - 0x09, /* Descriptor size */ - CY_U3P_USB_INTRFC_DESCR, /* Interface Descriptor type */ - 0x00, /* Interface number */ - 0x00, /* Alternate setting number */ - 0x00, /* Number of end points */ - 0xFF, /* Interface class */ - 0x00, /* Interface sub class */ - 0x00, /* Interface protocol code */ - 0x02, /* Interface descriptor string index */ - - /* Interface descriptor */ - 0x09, /* Descriptor size */ - CY_U3P_USB_INTRFC_DESCR, /* Interface Descriptor type */ - 0x01, /* Interface number */ - 0x00, /* Alternate setting number */ - 0x04, /* Number of end points */ - 0xFF, /* Interface class */ - 0x00, /* Interface sub class */ - 0x00, /* Interface protocol code */ - 0x02, /* Interface descriptor string index */ - - /* Endpoint descriptor for producer EP */ - 0x07, /* Descriptor size */ - CY_U3P_USB_ENDPNT_DESCR, /* Endpoint descriptor type */ - DATA_ENDPOINT_PRODUCER, /* Endpoint address and description */ - CY_U3P_USB_EP_BULK, /* Bulk endpoint type */ - 0x00,0x04, /* Max packet size = 1024 bytes */ - 0x00, /* Servicing interval for data transfers : 0 for bulk */ - - /* Super speed endpoint companion descriptor for producer EP */ - 0x06, /* Descriptor size */ - CY_U3P_SS_EP_COMPN_DESCR, /* SS endpoint companion descriptor type */ - (USB3_PACKETS_PER_BURST - 1), /* Max no. of packets in a burst : 0: burst 1 packet at a time */ - 0x00, /* Max streams for bulk EP = 0 (No streams) */ - 0x00,0x00, /* Service interval for the EP : 0 for bulk */ - - /* Endpoint descriptor for consumer EP */ - 0x07, /* Descriptor size */ - CY_U3P_USB_ENDPNT_DESCR, /* Endpoint descriptor type */ - DATA_ENDPOINT_CONSUMER, /* Endpoint address and description */ - CY_U3P_USB_EP_BULK, /* Bulk endpoint type */ - 0x00,0x04, /* Max packet size = 1024 bytes */ - 0x00, /* Servicing interval for data transfers : 0 for Bulk */ - - /* Super speed endpoint companion descriptor for consumer EP */ - 0x06, /* Descriptor size */ - CY_U3P_SS_EP_COMPN_DESCR, /* SS endpoint companion descriptor type */ - (USB3_PACKETS_PER_BURST - 1), /* Max no. of packets in a burst : 0: burst 1 packet at a time */ - 0x00, /* Max streams for bulk EP = 0 (No streams) */ - 0x00,0x00, /* Service interval for the EP : 0 for bulk */ - - /* Endpoint descriptor for producer EP */ - 0x07, /* Descriptor size */ - CY_U3P_USB_ENDPNT_DESCR, /* Endpoint descriptor type */ - CTRL_ENDPOINT_PRODUCER, /* Endpoint address and description */ - CY_U3P_USB_EP_BULK, /* Bulk endpoint type */ - 0x00,0x04, /* Max packet size = 1024 bytes */ - 0x00, /* Servicing interval for data transfers : 0 for bulk */ - - /* Super speed endpoint companion descriptor for producer EP */ - 0x06, /* Descriptor size */ - CY_U3P_SS_EP_COMPN_DESCR, /* SS endpoint companion descriptor type */ - (USB3_PACKETS_PER_BURST - 1), /* Max no. of packets in a burst : 0: burst 1 packet at a time */ - 0x00, /* Max streams for bulk EP = 0 (No streams) */ - 0x00,0x00, /* Service interval for the EP : 0 for bulk */ - - /* Endpoint descriptor for consumer EP */ - 0x07, /* Descriptor size */ - CY_U3P_USB_ENDPNT_DESCR, /* Endpoint descriptor type */ - CTRL_ENDPOINT_CONSUMER, /* Endpoint address and description */ - CY_U3P_USB_EP_BULK, /* Bulk endpoint type */ - 0x00,0x04, /* Max packet size = 1024 bytes */ - 0x00, /* Servicing interval for data transfers : 0 for Bulk */ - - /* Super speed endpoint companion descriptor for consumer EP */ - 0x06, /* Descriptor size */ - CY_U3P_SS_EP_COMPN_DESCR, /* SS endpoint companion descriptor type */ - (USB3_PACKETS_PER_BURST - 1), /* Max no. of packets in a burst : 0: burst 1 packet at a time */ - 0x00, /* Max streams for bulk EP = 0 (No streams) */ - 0x00,0x00 /* Service interval for the EP : 0 for bulk */ -}; - - -/* Standard Language ID String Descriptor */ -const uint8_t b200_string_lang_id_desc[] __attribute__ ((aligned (32))) = - { - 0x04, /* Descriptor Size */ - CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */ - 0x09,0x04 /* Language ID supported */ - }; - - -/* Standard Manufacturer String Descriptor */ -const uint8_t b200_usb_manufacture_desc[] __attribute__ ((aligned (32))) = - { - 0x26, /* Descriptor Size */ - CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */ - 'E',0x00, - 't',0x00, - 't',0x00, - 'u',0x00, - 's',0x00, - ' ',0x00, - 'R',0x00, - 'e',0x00, - 's',0x00, - 'e',0x00, - 'a',0x00, - 'r',0x00, - 'c',0x00, - 'h',0x00, - ' ',0x00, - 'L',0x00, - 'L',0x00, - 'C',0x00 - }; - -/* NI Manufacturer String Descriptor */ -const uint8_t niusrp_usb_manufacture_desc[] __attribute__ ((aligned (32))) = - { - 0x36, /* Descriptor Size */ - CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */ - 'N',0x00, - 'a',0x00, - 't',0x00, - 'i',0x00, - 'o',0x00, - 'n',0x00, - 'a',0x00, - 'l',0x00, - ' ',0x00, - 'I',0x00, - 'n',0x00, - 's',0x00, - 't',0x00, - 'r',0x00, - 'u',0x00, - 'm',0x00, - 'e',0x00, - 'n',0x00, - 't',0x00, - 's',0x00, - ' ',0x00, - 'C',0x00, - 'o',0x00, - 'r',0x00, - 'p',0x00, - '.',0x00 - }; - - -/* Standard Product String Descriptor */ -const uint8_t b200_usb_product_desc[] __attribute__ ((aligned (32))) = - { - 0x14, /* Descriptor Size */ - CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */ - 'U',0x00, - 'S',0x00, - 'R',0x00, - 'P',0x00, - ' ',0x00, - 'B',0x00, - '2',0x00, - '0',0x00, - '0',0x00 - }; - -/* NI-USRP 2900 Product String Descriptor */ -const uint8_t niusrp_2900_usb_product_desc[] __attribute__ ((aligned (32))) = - { - 0x1A, /* Descriptor Size */ - CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */ - 'N',0x00, - 'I',0x00, - ' ',0x00, - 'U',0x00, - 'S',0x00, - 'R',0x00, - 'P',0x00, - '-',0x00, - '2',0x00, - '9',0x00, - '0',0x00, - '0',0x00 - }; - -/* NI-USRP 2901 Product String Descriptor */ -const uint8_t niusrp_2901_usb_product_desc[] __attribute__ ((aligned (32))) = - { - 0x1A, /* Descriptor Size */ - CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */ - 'N',0x00, - 'I',0x00, - ' ',0x00, - 'U',0x00, - 'S',0x00, - 'R',0x00, - 'P',0x00, - '-',0x00, - '2',0x00, - '9',0x00, - '0',0x00, - '1',0x00 - }; - -const uint8_t unknown_desc[] __attribute__ ((aligned (32))) = - { - 0x10, /* Descriptor Size */ - CY_U3P_USB_STRING_DESCR, /* Device Descriptor Type */ - 'U',0x00, - 'n',0x00, - 'k',0x00, - 'n',0x00, - 'o',0x00, - 'w',0x00, - 'n',0x00 - }; - -/* Microsoft OS Descriptor. */ -const uint8_t CyFxUsbOSDscr[] __attribute__ ((aligned (32))) = -{ - 0x10, - CY_U3P_USB_STRING_DESCR, - 'O', 0x00, - 'S', 0x00, - ' ', 0x00, - 'D', 0x00, - 'e', 0x00, - 's', 0x00, - 'c', 0x00 -}; - -uint8_t dev_serial[20] __attribute__ ((aligned (32))) = +/* Firmware Device Serial String Descriptor */ +uint8_t b200_dev_serial_desc[20] = { 0x14, - CY_U3P_USB_STRING_DESCR, + 0x03,/* CY_U3P_USB_STRING_DESCR Device Descriptor Type */ '0', 0x00, '0', 0x00, '0', 0x00, @@ -682,9 +356,4 @@ uint8_t dev_serial[20] __attribute__ ((aligned (32))) = '0', 0x00, '0', 0x00, '0', 0x00 -}; - -/* Place this buffer as the last buffer so that no other variable / code shares - * the same cache line. Do not add any other variables / arrays in this file. - * This will lead to variables sharing the same cache line. */ -const uint8_t CyFxUsbDscrAlignBuffer[32] __attribute__ ((aligned (32))); +};
\ No newline at end of file diff --git a/firmware/fx3/b200/firmware/b200_usb_descriptors.h b/firmware/fx3/b200/firmware/b200_usb_descriptors.h new file mode 100644 index 000000000..f3889b9af --- /dev/null +++ b/firmware/fx3/b200/firmware/b200_usb_descriptors.h @@ -0,0 +1,21 @@ +// +// Copyright 2013-2014 Ettus Research LLC +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef _B200_USB_DESCRIPTORS_H +#define _B200_USB_DESCRIPTORS_H + +#include "cyu3externcstart.h" + +/* Descriptor definitions for USB enumerations. */ +extern uint8_t b200_usb_fs_config_desc[]; +extern uint8_t b200_usb_hs_config_desc[]; +extern uint8_t b200_usb_ss_config_desc[]; +extern uint8_t b200_dev_serial_desc[]; + +#include "cyu3externcend.h" + +#endif /* _B200_USB_DESCRIPTORS_H */ diff --git a/firmware/fx3/b200/makefile b/firmware/fx3/b200/firmware/makefile index 22eb1bbcc..53d423dfb 100644 --- a/firmware/fx3/b200/makefile +++ b/firmware/fx3/b200/firmware/makefile @@ -1,5 +1,8 @@ # # Copyright 2013-2014 Ettus Research LLC +# Copyright 2019 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: GPL-3.0-or-later # HEX_OUT = usrp_b200_fw.hex @@ -7,8 +10,8 @@ HEX_OUT = usrp_b200_fw.hex all:$(HEX_OUT) # Pull in the Cypress SDK files to build the firmware -FX3FWROOT=.. -FX3PFWROOT=../u3p_firmware +FX3FWROOT=../.. +FX3PFWROOT=../../u3p_firmware include $(FX3FWROOT)/common/fx3_build_config.mak ifndef OC @@ -17,11 +20,9 @@ endif MODULE = b200_main -SOURCE += $(MODULE).c -SOURCE += b200_usb_descriptors.c -SOURCE += b200_i2c.c +SOURCE += $(MODULE).c b200_i2c.c b200_usb_descriptors.c ../common/common_helpers.c ../common/common_descriptors.c -INCLUDES = b200_main.h b200_gpifconfig.h b200_i2c.h +INCFLAGS = -I../common LDLIBS += \ "$$ARMGCC_INSTALL_PATH"/arm-none-eabi/lib/libm.a @@ -34,7 +35,7 @@ EXES = $(MODULE).$(EXEEXT) $(MODULE).$(EXEEXT): $(A_OBJECT) $(C_OBJECT) $(LINK) $(LINKFLAGS) -$(C_OBJECT) : %.o : %.c $(INCLUDES) +$(C_OBJECT) : %.o : %.c $(COMPILE) $(INCFLAGS) $(A_OBJECT) : %.o : %.S @@ -44,6 +45,7 @@ clean: rm -f ./$(MODULE).$(EXEEXT) rm -f ./$(MODULE).map rm -f ./*.o + rm -f ../common/*.o $(HEX_OUT): $(C_OBJECT) $(A_OBJECT) $(EXES) $(OC) -O ihex $(EXES) $@ diff --git a/firmware/fx3/b200/fx3_mem_map.patch b/firmware/fx3/b200/fx3_mem_map.patch index 37d704ace..df9ff0e7a 100644 --- a/firmware/fx3/b200/fx3_mem_map.patch +++ b/firmware/fx3/b200/fx3_mem_map.patch @@ -66,3 +66,26 @@ diff -ur 1.2.3-orig/common/fx3.ld 1.2.3/common/fx3.ld + PROVIDE(__heap_size = __heap_end - __heap_start);
}
+diff -ur 1.2.3-orig/boot_fw/src/cyfx3.ld 1.2.3/boot_fw/src/cyfx3.ld +--- 1.2.3-orig/boot_fw/src/cyfx3.ld 2019-02-12 16:40:48.000000000 -0800 ++++ 1.2.3/boot_fw/src/cyfx3.ld 2019-03-20 14:36:18.992529192 -0700 +@@ -34,12 +34,18 @@ +
+ MEMORY
+ {
++ BLANK : ORIGIN = 0x40070000 LENGTH = 0x0100
+ SYS_MEM : ORIGIN = 0x40078000 LENGTH = 0x7000
+ DATA : ORIGIN = 0x4007F000 LENGTH = 0x1000
+ }
+
+ SECTIONS
+ {
++ . = 0x40070000;
++ .blank :
++ {
++ . += 0x100;
++ } > BLANK
+ . = 0x40078000;
+ .text :
+ {
+
|