aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/fx3/b200
diff options
context:
space:
mode:
authorMark Meserve <mark.meserve@ni.com>2019-04-11 15:14:37 -0500
committermichael-west <michael.west@ettus.com>2019-05-21 16:08:43 -0700
commit4f57ecab13e37f132c99ec797d412def3f1e2a66 (patch)
tree4789bce38abf657f52a4ebd1dabce720e1e62f68 /firmware/fx3/b200
parent914206e04182d2446de14be29ef886ae7c013641 (diff)
downloaduhd-4f57ecab13e37f132c99ec797d412def3f1e2a66.tar.gz
uhd-4f57ecab13e37f132c99ec797d412def3f1e2a66.tar.bz2
uhd-4f57ecab13e37f132c99ec797d412def3f1e2a66.zip
b200: add custom bootloader
- Adds custom bootloader code - Refactor common functions in firmware and bootloader
Diffstat (limited to 'firmware/fx3/b200')
-rw-r--r--firmware/fx3/b200/.gitignore3
-rw-r--r--firmware/fx3/b200/bootloader/.gitignore5
-rw-r--r--firmware/fx3/b200/bootloader/main.c55
-rw-r--r--firmware/fx3/b200/bootloader/makefile92
-rw-r--r--firmware/fx3/b200/bootloader/usb_boot.c807
-rw-r--r--firmware/fx3/b200/bootloader/usb_descriptors.c187
-rw-r--r--firmware/fx3/b200/bootloader/usb_descriptors.h26
-rw-r--r--firmware/fx3/b200/common/common_const.h51
-rw-r--r--firmware/fx3/b200/common/common_descriptors.c237
-rw-r--r--firmware/fx3/b200/common/common_descriptors.h50
-rw-r--r--firmware/fx3/b200/common/common_helpers.c199
-rw-r--r--firmware/fx3/b200/common/common_helpers.h34
-rw-r--r--firmware/fx3/b200/firmware/b200_const.h (renamed from firmware/fx3/b200/b200_main.h)28
-rw-r--r--[-rwxr-xr-x]firmware/fx3/b200/firmware/b200_gpifconfig.h (renamed from firmware/fx3/b200/b200_gpifconfig.h)352
-rw-r--r--firmware/fx3/b200/firmware/b200_i2c.c (renamed from firmware/fx3/b200/b200_i2c.c)0
-rw-r--r--firmware/fx3/b200/firmware/b200_i2c.h (renamed from firmware/fx3/b200/b200_i2c.h)0
-rw-r--r--firmware/fx3/b200/firmware/b200_main.c (renamed from firmware/fx3/b200/b200_main.c)122
-rw-r--r--firmware/fx3/b200/firmware/b200_usb_descriptors.c (renamed from firmware/fx3/b200/b200_usb_descriptors.c)361
-rw-r--r--firmware/fx3/b200/firmware/b200_usb_descriptors.h21
-rw-r--r--firmware/fx3/b200/firmware/makefile (renamed from firmware/fx3/b200/makefile)16
-rw-r--r--firmware/fx3/b200/fx3_mem_map.patch23
21 files changed, 2039 insertions, 630 deletions
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 :
+ {
+