libfx2 Reference

Contents:

Introduction

libfx2 is a chip support package for Cypress EZ-USB FX2 series microcontrollers.

On the firmware side, it provides:

  • register definitions,

  • makefile templates,

  • common code for handling standard USB requests,

  • a bootloader implementing Cypress vendor commands.

On the software side, it provides:

  • fx2, a Python library for interacting with the bootloader,

  • fx2tool, a tool for programming and debugging the chips.

Prerequisites

libfx2 has the following dependencies:

On a Debian system, these can be installed with:

apt-get install make sdcc python3 python3-libusb1

Then, compile all firmware components:

make -C firmware

Then, install the Python components to ~/.local:

python3 software/setup.py develop --user

The last step is not required if you just want to upload example firmware.

Getting started

Read configuration EEPROM:

fx2tool -S firmware/bootloader/bootloader.ihex read_eeprom 0 7

Load the Blinky example (a LED should be attached to PA0):

make -C examples/blinky load

Blinking a LED

Read the code for the blinky example if you’re looking for something minimal:

main.c
#include <fx2regs.h>
#include <fx2ints.h>

// Register an interrupt handler for TIMER0 overflow
void isr_TF0() __interrupt(_INT_TF0) {
  static int i;
  if(i++ % 64 == 0)
    PA0 = !PA0;
}

int main() {
  // Configure pins
  PA0 = 1;      // set PA0 to high
  OEA = 0b1;    // set PA0 as output

  // Configure TIMER0
  TCON = _M0_0; // use 16-bit counter mode
  ET0 = 1;      // generate an interrupt
  TR0 = 1;      // run

  // Enable interrupts
  EA  = 1;
  while(1);
}
Makefile
TARGET  = blinky

LIBFX2  = ../../firmware/library
include $(LIBFX2)/fx2rules.mk

Interacting over USB

Consider the code of the Cypress bootloader if you want to see how simple USB functionality can be implemented:

main.c
#include <fx2lib.h>
#include <fx2usb.h>
#include <fx2delay.h>
#include <fx2eeprom.h>

usb_desc_device_c usb_device = {
  .bLength              = sizeof(struct usb_desc_device),
  .bDescriptorType      = USB_DESC_DEVICE,
  .bcdUSB               = 0x0200,
  .bDeviceClass         = USB_DEV_CLASS_VENDOR,
  .bDeviceSubClass      = USB_DEV_SUBCLASS_VENDOR,
  .bDeviceProtocol      = USB_DEV_PROTOCOL_VENDOR,
  .bMaxPacketSize0      = 64,
  .idVendor             = 0x04b4,
  .idProduct            = 0x8613,
  .bcdDevice            = 0x0000,
  .iManufacturer        = 1,
  .iProduct             = 2,
  .iSerialNumber        = 0,
  .bNumConfigurations   = 1,
};

usb_desc_interface_c usb_interface = {
  .bLength              = sizeof(struct usb_desc_interface),
  .bDescriptorType      = USB_DESC_INTERFACE,
  .bInterfaceNumber     = 0,
  .bAlternateSetting    = 0,
  .bNumEndpoints        = 0,
  .bInterfaceClass      = USB_IFACE_CLASS_VENDOR,
  .bInterfaceSubClass   = USB_IFACE_SUBCLASS_VENDOR,
  .bInterfaceProtocol   = USB_IFACE_PROTOCOL_VENDOR,
  .iInterface           = 0,
};

usb_configuration_c usb_config = {
  {
    .bLength              = sizeof(struct usb_desc_configuration),
    .bDescriptorType      = USB_DESC_CONFIGURATION,
    .bNumInterfaces       = 1,
    .bConfigurationValue  = 1,
    .iConfiguration       = 0,
    .bmAttributes         = USB_ATTR_RESERVED_1,
    .bMaxPower            = 50,
  },
  {
    { .interface = &usb_interface },
    { 0 }
  }
};

// check for "earlier than 3.5", but version macros shipped in 3.6
#if !defined(__SDCC_VERSION_MAJOR)
__code const struct usb_configuration *__code const usb_configs[] = {
#else
usb_configuration_set_c usb_configs[] = {
#endif
  &usb_config,
};

usb_ascii_string_c usb_strings[] = {
  [0] = "whitequark@whitequark.org",
  [1] = "FX2 series Cypress-class bootloader",
};

usb_descriptor_set_c usb_descriptor_set = {
  .device           = &usb_device,
  .config_count     = ARRAYSIZE(usb_configs),
  .configs          = usb_configs,
  .string_count     = ARRAYSIZE(usb_strings),
  .strings          = usb_strings,
};

enum {
  USB_REQ_CYPRESS_EEPROM_SB  = 0xA2,
  USB_REQ_CYPRESS_EXT_RAM    = 0xA3,
  USB_REQ_CYPRESS_RENUMERATE = 0xA8,
  USB_REQ_CYPRESS_EEPROM_DB  = 0xA9,
  USB_REQ_LIBFX2_PAGE_SIZE   = 0xB0,
};

// We perform lengthy operations in the main loop to avoid hogging the interrupt.
// This flag is used for synchronization between the main loop and the ISR;
// to allow new SETUP requests to arrive while the previous one is still being
// handled (with all data received), the flag should be reset as soon as
// the entire SETUP request is parsed.
volatile bool pending_setup;

void handle_usb_setup(__xdata struct usb_req_setup *req) {
  req;
  if(pending_setup) {
    STALL_EP0();
  } else {
    pending_setup = true;
  }
}

// The EEPROM write cycle time is the same for a single byte or a single page;
// it is therefore far more efficient to write EEPROMs in entire pages.
// Unfortunately, there is no way to discover page size if it is not known
// beforehand. We play it safe and write individual bytes unless the page size
// was set explicitly via a libfx2-specific request, such that Cypress vendor
// requests A2/A9 work the same as in Cypress libraries by default.
uint8_t page_size = 0; // log2(page size in bytes)

void handle_pending_usb_setup() {
  __xdata struct usb_req_setup *req = (__xdata struct usb_req_setup *)SETUPDAT;

  if(req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_VENDOR|USB_DIR_OUT) &&
     req->bRequest == USB_REQ_CYPRESS_RENUMERATE) {
    pending_setup = false;

    USBCS |= _DISCON;
    delay_ms(10);
    USBCS &= ~_DISCON;

    return;
  }

  if(req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_VENDOR|USB_DIR_OUT) &&
     req->bRequest == USB_REQ_LIBFX2_PAGE_SIZE) {
    page_size = req->wValue;
    pending_setup = false;

    ACK_EP0();
    return;
  }

  if((req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_VENDOR|USB_DIR_IN) ||
      req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_VENDOR|USB_DIR_OUT)) &&
     (req->bRequest == USB_REQ_CYPRESS_EEPROM_SB ||
      req->bRequest == USB_REQ_CYPRESS_EEPROM_DB)) {
    bool     arg_read  = (req->bmRequestType & USB_DIR_IN);
    bool     arg_dbyte = (req->bRequest == USB_REQ_CYPRESS_EEPROM_DB);
    uint8_t  arg_chip  = arg_dbyte ? 0x51 : 0x50;
    uint16_t arg_addr  = req->wValue;
    uint16_t arg_len   = req->wLength;
    pending_setup = false;

    while(arg_len > 0) {
      uint8_t len = arg_len < 64 ? arg_len : 64;

      if(arg_read) {
        while(EP0CS & _BUSY);
        if(!eeprom_read(arg_chip, arg_addr, EP0BUF, len, arg_dbyte)) {
          STALL_EP0();
          break;
        }
        SETUP_EP0_BUF(len);
      } else {
        SETUP_EP0_BUF(0);
        while(EP0CS & _BUSY);
        if(!eeprom_write(arg_chip, arg_addr, EP0BUF, len, arg_dbyte, page_size,
                         /*timeout=*/166)) {
          STALL_EP0();
          break;
        }
      }

      arg_len  -= len;
      arg_addr += len;
    }

    return;
  }

  if((req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_VENDOR|USB_DIR_IN) ||
      req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_VENDOR|USB_DIR_OUT)) &&
     req->bRequest == USB_REQ_CYPRESS_EXT_RAM) {
    bool     arg_read = (req->bmRequestType & USB_DIR_IN);
    uint16_t arg_addr = req->wValue;
    uint16_t arg_len  = req->wLength;
    pending_setup = false;

    while(arg_len > 0) {
      uint8_t len = arg_len < 64 ? arg_len : 64;

      if(arg_read) {
        while(EP0CS & _BUSY);
        xmemcpy(EP0BUF, (__xdata void *)arg_addr, len);
        SETUP_EP0_BUF(len);
      } else {
        SETUP_EP0_BUF(0);
        while(EP0CS & _BUSY);
        xmemcpy((__xdata void *)arg_addr, EP0BUF, arg_len);
      }

      arg_len  -= len;
      arg_addr += len;
    }

    return;
  }

  STALL_EP0();
}

int main() {
  CPUCS = _CLKOE|_CLKSPD1;

  // Don't re-enumerate. `fx2tool -B` will load this firmware to access EEPROM, and it
  // expects to be able to keep accessing the device. If you are using this firmware
  // in your own code, set /*diconnect=*/true.
  usb_init(/*disconnect=*/false);

  while(1) {
    if(pending_setup)
      handle_pending_usb_setup();
  }
}
Makefile
TARGET    = boot-cypress
LIBRARIES = fx2 fx2usb fx2isrs

LIBFX2 	= ../library
include $(LIBFX2)/fx2rules.mk

Adding an DFU bootloader

It is easy to integrate a standards-compliant and OS-agnostic Device Firmware Upgrade bootloader as libfx2 provides all necessary infrastructure, and it only needs to be configured for a specific board and integrated into a target application:

main.c
#include <fx2lib.h>
#include <fx2delay.h>
#include <fx2eeprom.h>
#include <fx2usbdfu.h>

// Replace this with the actual EEPROM size on your board to use its full capacity.
#define FIRMWARE_SIZE 16384

// Application mode descriptors.

usb_desc_device_c usb_device = {
  .bLength              = sizeof(struct usb_desc_device),
  .bDescriptorType      = USB_DESC_DEVICE,
  .bcdUSB               = 0x0200,
  .bDeviceClass         = USB_DEV_CLASS_PER_INTERFACE,
  .bDeviceSubClass      = USB_DEV_SUBCLASS_PER_INTERFACE,
  .bDeviceProtocol      = USB_DEV_PROTOCOL_PER_INTERFACE,
  .bMaxPacketSize0      = 64,
  .idVendor             = 0x04b4,
  .idProduct            = 0x8613,
  .bcdDevice            = 0x0000,
  .iManufacturer        = 1,
  .iProduct             = 2,
  .iSerialNumber        = 0,
  .bNumConfigurations   = 1,
};

extern usb_dfu_desc_functional_c usb_dfu_functional;

usb_desc_interface_c usb_interface_dfu_runtime = {
  .bLength              = sizeof(struct usb_desc_interface),
  .bDescriptorType      = USB_DESC_INTERFACE,
  .bInterfaceNumber     = 0,
  .bAlternateSetting    = 0,
  .bNumEndpoints        = 0,
  .bInterfaceClass      = USB_IFACE_CLASS_APP_SPECIFIC,
  .bInterfaceSubClass   = USB_IFACE_SUBCLASS_DFU,
  .bInterfaceProtocol   = USB_IFACE_PROTOCOL_DFU_RUNTIME,
  .iInterface           = 0,
};

usb_configuration_c usb_config_app = {
  {
    .bLength              = sizeof(struct usb_desc_configuration),
    .bDescriptorType      = USB_DESC_CONFIGURATION,
    .bNumInterfaces       = 1,
    .bConfigurationValue  = 1,
    .iConfiguration       = 0,
    .bmAttributes         = USB_ATTR_RESERVED_1,
    .bMaxPower            = 50,
  },
  {
    { .interface = &usb_interface_dfu_runtime },
    { .generic   = (struct usb_desc_generic *) &usb_dfu_functional },
    { 0 }
  }
};

usb_configuration_set_c usb_configs_app[] = {
  &usb_config_app,
};

usb_ascii_string_c usb_strings_app[] = {
  [0] = "whitequark@whitequark.org",
  [1] = "Example application with DFU support",
};

// DFU mode descriptors

usb_desc_interface_c usb_interface_dfu_upgrade = {
  .bLength              = sizeof(struct usb_desc_interface),
  .bDescriptorType      = USB_DESC_INTERFACE,
  .bInterfaceNumber     = 0,
  .bAlternateSetting    = 0,
  .bNumEndpoints        = 0,
  .bInterfaceClass      = USB_IFACE_CLASS_APP_SPECIFIC,
  .bInterfaceSubClass   = USB_IFACE_SUBCLASS_DFU,
  .bInterfaceProtocol   = USB_IFACE_PROTOCOL_DFU_UPGRADE,
  .iInterface           = 3,
};

usb_dfu_desc_functional_c usb_dfu_functional = {
  .bLength              = sizeof(struct usb_dfu_desc_functional),
  .bDescriptorType      = USB_DESC_DFU_FUNCTIONAL,
  .bmAttributes         = USB_DFU_ATTR_CAN_DNLOAD |
                          USB_DFU_ATTR_CAN_UPLOAD |
                          USB_DFU_ATTR_MANIFESTATION_TOLERANT |
                          USB_DFU_ATTR_WILL_DETACH,
  .wTransferSize        = 64,
  .bcdDFUVersion        = 0x0101,
};

usb_configuration_c usb_config_dfu = {
  {
    .bLength              = sizeof(struct usb_desc_configuration),
    .bDescriptorType      = USB_DESC_CONFIGURATION,
    .bNumInterfaces       = 1,
    .bConfigurationValue  = 1,
    .iConfiguration       = 0,
    .bmAttributes         = USB_ATTR_RESERVED_1,
    .bMaxPower            = 50,
  },
  {
    { .interface = &usb_interface_dfu_upgrade },
    { .generic   = (struct usb_desc_generic *) &usb_dfu_functional },
    { 0 }
  }
};

usb_configuration_set_c usb_configs_dfu[] = {
  &usb_config_dfu,
};

usb_ascii_string_c usb_strings_dfu[] = {
  [0] = "whitequark@whitequark.org",
  [1] = "FX2 series DFU-class bootloader",
  [2] = "Boot EEPROM"
};

// Application and DFU code

__xdata struct usb_descriptor_set usb_descriptor_set = {
  .device           = &usb_device,
  .config_count     = ARRAYSIZE(usb_configs_app),
  .configs          = usb_configs_app,
  .string_count     = ARRAYSIZE(usb_strings_app),
  .strings          = usb_strings_app,
};

usb_dfu_status_t firmware_upload(uint32_t address, __xdata uint8_t *data,
                                 __xdata uint16_t *length) __reentrant {
  if(address < FIRMWARE_SIZE) {
    // Only 2-byte EEPROMs are large enough to store any sort of firmware, and the address
    // of a 2-byte boot EEPROM is fixed, so it's safe to hardcode it here.
    if(eeprom_read(0x51, address, data, *length, /*double_byte=*/true)) {
      return USB_DFU_STATUS_OK;
    } else {
      return USB_DFU_STATUS_errUNKNOWN;
    }
  } else {
    *length = 0;
    return USB_DFU_STATUS_OK;
  }
}

usb_dfu_status_t firmware_dnload(uint32_t address, __xdata uint8_t *data,
                                 uint16_t length) __reentrant {
  if(length == 0) {
    if(address == FIRMWARE_SIZE)
      return USB_DFU_STATUS_OK;
    else
      return USB_DFU_STATUS_errNOTDONE;
  } else if(address < FIRMWARE_SIZE) {
    // Use 8-byte page writes, which are slow but universally compatible. (Strictly speaking,
    // no EEPROM can be assumed to provide any page writes, but virtually every EEPROM larger
    // than 16 KiB supports at least 8-byte pages).
    //
    // If the datasheet for the EEPROM lists larger pages as permissible, this would provide
    // a significant speed boost. Unfortunately it is not really possible to discover the page
    // size by interrogating the EEPROM.
    if(eeprom_write(0x51, address, data, length, /*double_byte=*/true,
                    /*page_size=*/3, /*timeout=*/166)) {
      return USB_DFU_STATUS_OK;
    } else {
      return USB_DFU_STATUS_errWRITE;
    }
  } else {
    return USB_DFU_STATUS_errADDRESS;
  }
}

usb_dfu_status_t firmware_manifest() __reentrant {
  // Simulate committing the firmware. If this function is not necessary, it may simply be omitted,
  // together with its entry in `usb_dfu_iface_state`.
  delay_ms(1000);

  return USB_DFU_STATUS_OK;
}

usb_dfu_iface_state_t usb_dfu_iface_state = {
  // Set to bInterfaceNumber of the DFU descriptor in the application mode.
  .interface          = 0,

  .firmware_upload    = firmware_upload,
  .firmware_dnload    = firmware_dnload,
  .firmware_manifest  = firmware_manifest,
};

void handle_usb_setup(__xdata struct usb_req_setup *req) {
  if(usb_dfu_setup(&usb_dfu_iface_state, req))
    return;

  STALL_EP0();
}

int main() {
  // Run core at 48 MHz fCLK.
  CPUCS = _CLKSPD1;

  // Re-enumerate, to make sure our descriptors are picked up correctly.
  usb_init(/*disconnect=*/true);

  while(1) {
    // Handle switching to DFU mode from application mode.
    if(usb_dfu_iface_state.state == USB_DFU_STATE_appDETACH) {
      // Wait until the host has received our ACK of the DETACH request before actually
      // disconnecting. This is because if we disconnect immediately, the host might just
      // return an error to the DFU utility.
      delay_ms(10);
      USBCS |= _DISCON;

      // Switch to DFU mode.
      usb_dfu_iface_state.state = USB_DFU_STATE_dfuIDLE;

      // Re-enumerate using the DFU mode descriptors. For Windows compatibility, it is necessary
      // to change USB Product ID in the Device descriptor as well, since Windows is unable
      // to rebind a DFU driver to the same VID:PID pair. (Windows is euphemistically called out
      // in the DFU spec as a "certain operating system").
      ((usb_desc_device_t *)usb_device)->idProduct++;
      usb_descriptor_set.config_count = ARRAYSIZE(usb_configs_dfu);
      usb_descriptor_set.configs      = usb_configs_dfu;
      usb_descriptor_set.string_count = ARRAYSIZE(usb_strings_dfu);
      usb_descriptor_set.strings      = usb_strings_dfu;

      // Don't reconnect again in `usb_init`, as we have just disconnected explicitly.
      usb_init(/*disconnect=*/false);
    }

    // Handle any lengthy DFU requests, i.e. the ones that call back into firmware_* functions.
    usb_dfu_setup_deferred(&usb_dfu_iface_state);
  }
}
Makefile
TARGET    = boot-dfu
LIBRARIES = fx2 fx2usb fx2dfu fx2isrs
MODEL     = small

LIBFX2  = ../library
include $(LIBFX2)/fx2rules.mk

The DFU images suitable for flashing can be generated from Intel HEX firmware images using the dfu subcommand of the command-line tool.

Adding an UF2 bootloader

It is easy to integrate a very versatile and OS-agnostic UF2 compliant bootloader as libfx2 provides all necessary infrastructure, and it only needs to be configured for a specific board and integrated into a target application:

main.c
#include <fx2lib.h>
#include <fx2delay.h>
#include <fx2eeprom.h>
#include <fx2usbmassstor.h>
#include <fx2uf2.h>

usb_desc_device_c usb_device = {
  .bLength              = sizeof(struct usb_desc_device),
  .bDescriptorType      = USB_DESC_DEVICE,
  .bcdUSB               = 0x0200,
  .bDeviceClass         = USB_DEV_CLASS_PER_INTERFACE,
  .bDeviceSubClass      = USB_DEV_SUBCLASS_PER_INTERFACE,
  .bDeviceProtocol      = USB_DEV_PROTOCOL_PER_INTERFACE,
  .bMaxPacketSize0      = 64,
  .idVendor             = 0x04b4,
  .idProduct            = 0x8613,
  .bcdDevice            = 0x0000,
  .iManufacturer        = 1,
  .iProduct             = 2,
  .iSerialNumber        = 3,
  .bNumConfigurations   = 1,
};

usb_desc_interface_c usb_interface_mass_storage = {
  .bLength              = sizeof(struct usb_desc_interface),
  .bDescriptorType      = USB_DESC_INTERFACE,
  .bInterfaceNumber     = 0,
  .bAlternateSetting    = 0,
  .bNumEndpoints        = 2,
  .bInterfaceClass      = USB_IFACE_CLASS_MASS_STORAGE,
  .bInterfaceSubClass   = USB_IFACE_SUBCLASS_MASS_STORAGE_SCSI,
  .bInterfaceProtocol   = USB_IFACE_PROTOCOL_MASS_STORAGE_BBB,
  .iInterface           = 0,
};

usb_desc_endpoint_c usb_endpoint_ep2_out = {
  .bLength              = sizeof(struct usb_desc_endpoint),
  .bDescriptorType      = USB_DESC_ENDPOINT,
  .bEndpointAddress     = 2,
  .bmAttributes         = USB_XFER_BULK,
  .wMaxPacketSize       = 512,
  .bInterval            = 0,
};

usb_desc_endpoint_c usb_endpoint_ep6_in = {
  .bLength              = sizeof(struct usb_desc_endpoint),
  .bDescriptorType      = USB_DESC_ENDPOINT,
  .bEndpointAddress     = 6|USB_DIR_IN,
  .bmAttributes         = USB_XFER_BULK,
  .wMaxPacketSize       = 512,
  .bInterval            = 0,
};

usb_configuration_c usb_config = {
  {
    .bLength              = sizeof(struct usb_desc_configuration),
    .bDescriptorType      = USB_DESC_CONFIGURATION,
    .bNumInterfaces       = 1,
    .bConfigurationValue  = 1,
    .iConfiguration       = 0,
    .bmAttributes         = USB_ATTR_RESERVED_1,
    .bMaxPower            = 50,
  },
  {
    { .interface  = &usb_interface_mass_storage },
    { .endpoint   = &usb_endpoint_ep2_out },
    { .endpoint   = &usb_endpoint_ep6_in  },
    { 0 }
  }
};

usb_configuration_set_c usb_configs[] = {
  &usb_config,
};

usb_ascii_string_c usb_strings[] = {
  [0] = "whitequark@whitequark.org",
  [1] = "FX2 series UF2-class bootloader",
  // USB MS BBB 4.1.1 requires each device to have an unique serial number that is at least
  // 12 characters long. We cannot satisfy the uniqueness requirement, but we at least provide
  // a serial number in a valid format.
  [2] = "000000000000",
};

usb_descriptor_set_c usb_descriptor_set = {
  .device          = &usb_device,
  .config_count    = ARRAYSIZE(usb_configs),
  .configs         = usb_configs,
  .string_count    = ARRAYSIZE(usb_strings),
  .strings         = usb_strings,
};

usb_mass_storage_bbb_state_t usb_mass_storage_state = {
  .interface    = 0,
  .max_in_size  = 512,

  .command      = uf2_scsi_command,
  .data_out     = uf2_scsi_data_out,
  .data_in      = uf2_scsi_data_in,
};

static bool firmware_read(uint32_t address, __xdata uint8_t *data, uint16_t length) __reentrant {
  // Only 2-byte EEPROMs are large enough to store any sort of firmware, and the address
  // of a 2-byte boot EEPROM is fixed, so it's safe to hardcode it here.
  return eeprom_read(0x51, address, data, length, /*double_byte=*/true);
}

static bool firmware_write(uint32_t address, __xdata uint8_t *data, uint16_t length) __reentrant {
  // Use 8-byte page writes, which are slow but universally compatible. (Strictly speaking,
  // no EEPROM can be assumed to provide any page writes, but virtually every EEPROM larger
  // than 16 KiB supports at least 8-byte pages).
  //
  // If the datasheet for the EEPROM lists larger pages as permissible, this would provide
  // a significant speed boost. Unfortunately it is not really possible to discover the page
  // size by interrogating the EEPROM.
  return eeprom_write(0x51, address, data, length, /*double_byte=*/true,
                      /*page_size=*/3, /*timeout=*/166);
}

// Configure for 16Kx8 EEPROM, since this is upwards compatible with larger EEPROMs and
// any application integrating the UF2 bootloader will be at least ~12 KB in size.
// (The overhead of the bootloader is smaller than that, since much of the USB machinery
// can be shared between the bootloader and the application.)
uf2_configuration_c uf2_config = {
  // Provide a virtual mass storage device of 32 MiB in size. Using a device that is
  // too small will result in broken filesystem being generated (in particular, below
  // a certain cluster count, the filesystm gets interpreted as FAT12 instead of FAT16),
  // and a device that is too large will result in slower operations (mounting, etc).
  // 32 MiB is a good number.
  .total_sectors  = 2 * 32768,
  // Replace the Model: and Board-ID: fields with ones specific for your board.
  // Note that Board-ID: field should be machine-readable.
  // The INFO_UF2.TXT file can be up to 512 bytes in size.
  .info_uf2_txt   =
    "UF2 Bootloader for Cypress FX2\r\n"
    "Model: Generic Developer Board with 16Kx8 EEPROM\r\n"
    "Board-ID: FX2-Generic_16Kx8-v0\r\n",
  // Replace the URL with a hyperlink to a document describing your board.
  .index_htm      =
    "<meta http-equiv=\"refresh\" content=\"0; url=https://github.com/whitequark/libfx2/\">",
  // Replace this with the actual EEPROM size on your board to use its full capacity.
  .firmware_size  = 16384,

  .firmware_read  = firmware_read,
  .firmware_write = firmware_write,
};

void handle_usb_setup(__xdata struct usb_req_setup *req) {
  if(usb_mass_storage_bbb_setup(&usb_mass_storage_state, req))
    return;

  STALL_EP0();
}

volatile bool pending_ep6_in;

void isr_IBN() __interrupt {
  pending_ep6_in = true;
  CLEAR_USB_IRQ();
  NAKIRQ = _IBN;
  IBNIRQ = _IBNI_EP6;
}

int main() {
  // Run core at 48 MHz fCLK.
  CPUCS = _CLKSPD1;

  // Use newest chip features.
  REVCTL = _ENH_PKT|_DYN_OUT;

  // NAK all transfers.
  SYNCDELAY;
  FIFORESET = _NAKALL;

  // EP2 is configured as 512-byte double buffed BULK OUT.
  EP2CFG  =  _VALID|_TYPE1|_BUF1;
  EP2CS   = 0;
  // EP6 is configured as 512-byte double buffed BULK IN.
  EP6CFG  =  _VALID|_DIR|_TYPE1|_BUF1;
  EP6CS   = 0;
  // EP4/8 are not used.
  EP4CFG &= ~_VALID;
  EP8CFG &= ~_VALID;

  // Enable IN-BULK-NAK interrupt for EP6.
  IBNIE = _IBNI_EP6;
  NAKIE = _IBN;

  // Reset and prime EP2, and reset EP6.
  SYNCDELAY;
  FIFORESET = _NAKALL|2;
  SYNCDELAY;
  OUTPKTEND = _SKIP|2;
  SYNCDELAY;
  OUTPKTEND = _SKIP|2;
  SYNCDELAY;
  FIFORESET = _NAKALL|6;
  SYNCDELAY;
  FIFORESET = 0;

  // Re-enumerate, to make sure our descriptors are picked up correctly.
  usb_init(/*disconnect=*/true);

  while(1) {
    if(!(EP2CS & _EMPTY)) {
      uint16_t length = (EP2BCH << 8) | EP2BCL;
      if(usb_mass_storage_bbb_bulk_out(&usb_mass_storage_state, EP2FIFOBUF, length)) {
        EP2BCL = 0;
      } else {
        EP2CS  = _STALL;
        EP6CS  = _STALL;
      }
    }

    if(pending_ep6_in) {
      __xdata uint16_t length;
      if(usb_mass_storage_bbb_bulk_in(&usb_mass_storage_state, EP6FIFOBUF, &length)) {
        if(length > 0) {
          EP6BCH = length >> 8;
          SYNCDELAY;
          EP6BCL = length;
        }
      } else {
        EP6CS  = _STALL;
      }

      pending_ep6_in = false;
    }
  }
}
Makefile
TARGET    = boot-uf2
LIBRARIES = fx2 fx2usb fx2usbmassstor fx2uf2 fx2isrs
MODEL     = medium

LIBFX2  = ../library
include $(LIBFX2)/fx2rules.mk

The UF2 images suitable for flashing can be generated from Intel HEX firmware images using the uf2 subcommand of the command-line tool.

Command-line tool reference

Bootloader tool

Cypress FX2/FX2LP bootloader tool

This tool can read and write data in three formats:

  • hex: contiguous hexadecimal dump with non-significant whitespace

  • bin (.bin extension): contiguous binary

  • ihex (.ihex, .ihx, .hex extensions): discontiguous Intel HEX records

By default, the format is automatically determined from the file extension, and if reading from standard input or writing to standard output, whether the stream is a terminal (human-readable hexadecimal is used) or not (binary is used).

usage: fx2tool [-h] [-d DEVICE] [-F {hex,bin,ihex,auto}] [-S FILENAME] [-B]
               COMMAND ...

Positional Arguments

COMMAND

Possible choices: load, read_ram, write_ram, read_xram, write_xram, read_eeprom, write_eeprom, reenumerate, program, update, dump, uf2, dfu

Named Arguments

-d, --device

device VID:PID pair

Default: (1204, 34323)

-F, --format

Possible choices: hex, bin, ihex, auto

data input/output format

Default: “auto”

-S, --stage2

load the specified second stage bootloader before any further action

-B, --bootloader

load the second stage bootloader provided with fx2tool

Default: False

Sub-commands

load

Loads firmware into on-chip code memory and runs it.

fx2tool load [-h] FIRMWARE
Positional Arguments
FIRMWARE

read firmware from the specified file

read_ram

Reads data from on-chip code RAM.

“External” RAM means on-chip RAM external to the 8051 core, i.e. RAM where __code or __xdata objects are placed by the toolchain. Internal RAM of the 8051 is not accessible by this tool.

fx2tool read_ram [-h] [-f FILENAME] ADDRESS LENGTH
Positional Arguments
ADDRESS

starting address

LENGTH

amount of bytes to read

Named Arguments
-f, --file

write data to the specified file

Default: -

write_ram

Writes data to on-chip code RAM.

“External” RAM means on-chip RAM external to the 8051 core, i.e. RAM where __code or __xdata objects are placed by the toolchain. Internal RAM of the 8051 is not accessible by this tool.

fx2tool write_ram [-h] [-a ADDRESS] (-f FILENAME | -d DATA)
Named Arguments
-a, --offset

starting address

Default: 0

-f, --file

read data from the specified file

-d, --data

hexadecimal bytes to write

read_xram

Reads data from RAM using the movx instruction.

“External” RAM means on-chip RAM external to the 8051 core, i.e. RAM where __code or __xdata objects are placed by the toolchain. Internal RAM of the 8051 is not accessible by this tool.

fx2tool read_xram [-h] [-f FILENAME] ADDRESS LENGTH
Positional Arguments
ADDRESS

starting address

LENGTH

amount of bytes to read

Named Arguments
-f, --file

write data to the specified file

Default: -

write_xram

Writes data to RAM using the movx instruction.

“External” RAM means on-chip RAM external to the 8051 core, i.e. RAM where __code or __xdata objects are placed by the toolchain. Internal RAM of the 8051 is not accessible by this tool.

fx2tool write_xram [-h] [-a ADDRESS] (-f FILENAME | -d DATA)
Named Arguments
-a, --offset

starting address

Default: 0

-f, --file

read data from the specified file

-d, --data

hexadecimal bytes to write

read_eeprom

Reads data from boot EEPROM.

An appropriate second stage bootloader must be loaded for this command to work, see the –stage2 option. The format of the bootloader firmware file is auto-detected.

fx2tool read_eeprom [-h] [-W WIDTH] [-f FILENAME] ADDRESS LENGTH
Positional Arguments
ADDRESS

starting address

LENGTH

amount of bytes to read

Named Arguments
-W, --address-width

Possible choices: 1, 2

EEPROM address width in bytes

Default: 2

-f, --file

write data to the specified file

Default: -

write_eeprom

Writes data to boot EEPROM.

An appropriate second stage bootloader must be loaded for this command to work, see the –stage2 option. The format of the bootloader firmware file is auto-detected.

fx2tool write_eeprom [-h] [-W WIDTH] [-a ADDRESS] (-f FILENAME | -d DATA)
                     [-p SIZE]
Named Arguments
-W, --address-width

Possible choices: 1, 2

EEPROM address width in bytes

Default: 2

-a, --offset

starting address

Default: 0

-f, --file

read data from the specified file

-d, --data

hexadecimal bytes to write

-p, --page-size

power-of-two EEPROM page size (default: 1)

Default: 1

reenumerate

Simulates device disconnection and reconnection.

An appropriate second stage bootloader must be loaded for this command to work, see the –stage2 option. The format of the bootloader firmware file is auto-detected.

fx2tool reenumerate [-h]
program

Writes USB VID, PID, and DID, and if specified, firmware, into boot EEPROM.

An appropriate second stage bootloader must be loaded for this command to work, see the –stage2 option. The format of the bootloader firmware file is auto-detected.

fx2tool program [-h] [-W WIDTH] [-p SIZE] [-V ID] [-P ID] [-D ID] [-N] [-F]
                [-f FILENAME]
Named Arguments
-W, --address-width

Possible choices: 1, 2

EEPROM address width in bytes

Default: 2

-p, --page-size

power-of-two EEPROM page size (default: 1)

Default: 1

-V, --vid

USB vendor ID (default: 04b4)

Default: 1204

-P, --pid

USB product ID (default: 8613)

Default: 34323

-D, --did

USB device ID (default: 0000)

Default: 0

-N, --disconnect

do not automatically enumerate on startup

Default: False

-F, --fast

use 400 kHz clock for loading firmware via I2C

Default: False

-f, --firmware

read firmware from the specified file

update

Writes USB VID, PID, DID, boot options, and if specified, firmware, into boot EEPROM, without changing any omitted parameters.

An appropriate second stage bootloader must be loaded for this command to work, see the –stage2 option. The format of the bootloader firmware file is auto-detected.

fx2tool update [-h] [-W WIDTH] [-p SIZE] [-V ID] [-P ID] [-D ID] [-N] [-E]
               [-F] [-S] [-f FILENAME | -n]
Named Arguments
-W, --address-width

Possible choices: 1, 2

EEPROM address width in bytes

Default: 2

-p, --page-size

power-of-two EEPROM page size (default: 1)

Default: 1

-V, --vid

USB vendor ID

-P, --pid

USB product ID

-D, --did

USB device ID

-N, --disconnect

do not automatically enumerate on startup

-E, --no-disconnect

do automatically enumerate on startup

-F, --fast

use 400 kHz clock for loading firmware via I2C

-S, --slow

use 100 kHz clock for loading firmware via I2C

-f, --firmware

read firmware from the specified file

-n, --no-firmware

remove any firmware present

Default: False

dump

Reads USB VID, PID, DID, boot options, and if present, firmware, from boot EEPROM.

An appropriate second stage bootloader must be loaded for this command to work, see the –stage2 option. The format of the bootloader firmware file is auto-detected.

fx2tool dump [-h] [-W WIDTH] [-f FILENAME]
Named Arguments
-W, --address-width

Possible choices: 1, 2

EEPROM address width in bytes

Default: 2

-f, --firmware

write firmware to the specified file

uf2

Assembles USB VID, PID, DID, boot options and firmware into an image that can be flashed into the boot EEPROM using the UF2 firmware update protocol.

fx2tool uf2 [-h] [-V ID] [-P ID] [-D ID] [-N] [-F] FIRMWARE-FILE UF2-FILE
Positional Arguments
FIRMWARE-FILE

read firmware from the specified file

UF2-FILE

write UF2 firmware update image to the specified file

Named Arguments
-V, --vid

USB vendor ID (default: 04b4)

Default: 1204

-P, --pid

USB product ID (default: 8613)

Default: 34323

-D, --did

USB device ID (default: 0000)

Default: 0

-N, --disconnect

do not automatically enumerate on startup

Default: False

-F, --fast

use 400 kHz clock for loading firmware via I2C

Default: False

dfu

Assembles USB VID, PID, DID, boot options and firmware into an image that can be flashed into the boot EEPROM using the standard Device Firmware Update protocol.

fx2tool dfu [-h] [-V ID] [-P ID] [-D ID] [-N] [-F] [--dfu-pid ID]
            FIRMWARE-FILE DFU-FILE
Positional Arguments
FIRMWARE-FILE

read firmware from the specified file

DFU-FILE

write DFU image to the specified file

Named Arguments
-V, --vid

USB vendor ID (default: 04b4)

Default: 1204

-P, --pid

USB product ID (default: 8613)

Default: 34323

-D, --did

USB device ID (default: 0000)

Default: 0

-N, --disconnect

do not automatically enumerate on startup

Default: False

-F, --fast

use 400 kHz clock for loading firmware via I2C

Default: False

--dfu-pid

DFU mode USB product ID (default: firmware product ID)

Host-side library reference

class fx2.FX2Config(vendor_id=1204, product_id=34323, device_id=0, disconnect=False, i2c_400khz=False)[source]

Cypress FX2 EEPROM configuration data.

vendor_idint

USB vendor ID, 16 bits.

product_idint

USB product ID, 16 bits.

device_idint

USB device ID, 16 bits in binary-coded decimal.

disconnectbool

If True, do not enumerate on startup. If False, enumerate as a default FX2 device with specified VID/PID/DID.

i2c_400khzbool

If True, use 400 kHz I2C clock to read firmware from EEPROM. If False, use 100 kHz clock.

firmwarelist

Firmware to be loaded into on-chip program/data RAM. If empty, “C0 load” is used; if not, “C2 load” is used, and the command to bring the CPU out of reset is inserted automatically.

append(addr, chunk)[source]

Append a command to load chunk at addr into on-chip program/data RAM on device startup.

encode(max_size=None)[source]

Convert configuration to an image that can be loaded into an EEPROM.

Returns the EEPROM image if the resulting configuration is smaller than max_size, or raises ValueError if it is not.

classmethod decode(data, partial=False)[source]

Parse configuration from an image loaded from an EEPROM.

Returns None if the EEPROM image is empty (the EEPROM was erased), FX2Config if it contains a valid configuration, or raises ValueError if it does not.

If partial is True, only requires any data records present to be complete; if it is False, it is an error unless the image contains the final data record.

class fx2.FX2Device(vendor_id=1204, product_id=34323)[source]

A Cypress FX2 series device.

The initializer of this class locates the device by provided VID:PID pair, or raises a FX2DeviceError.

usbusb1.USBDeviceHandle

Raw USB device handle.

control_read(request_type, request, value, index, length, timeout=None)[source]

Issue an USB control read request with timeout defaulting to self.timeout.

control_write(request_type, request, value, index, data, timeout=None)[source]

Issue an USB control write request with timeout defaulting to self.timeout.

bulk_read(endpoint, length, timeout=None)[source]

Issue an USB bulk read request with timeout defaulting to self.timeout.

bulk_write(endpoint, data, timeout=None)[source]

Issue an USB bulk write request with timeout defaulting to self.timeout.

read_ram(addr, length)[source]

Read length bytes at addr from internal RAM. Note that not all memory can be addressed this way; consult the TRM.

write_ram(addr, data)[source]

Write data to addr to internal RAM. Note that not all memory can be addressed this way; consult the TRM.

load_ram(chunks)[source]

Write chunks, a list of (address, data) pairs, to internal RAM, and start the CPU core. See also write_ram.

cpu_reset(is_reset)[source]

Bring CPU in or out of reset.

read_boot_eeprom(addr, length, addr_width, chunk_size=256)[source]

Read length bytes at addr from boot EEPROM in chunk_size chunks.

Requires the second stage bootloader.

write_boot_eeprom(addr, data, addr_width, chunk_size=16, page_size=0)[source]

Write data to addr in boot EEPROM that has 2 ** page_size byte pages in chunk_size chunks.

Writing EEPROM is much slower than reading; for best performance, specify page_size per EEPROM datasheet, and set chunk_size to a small multiple of 2 ** page_size. Otherwise, timeouts may occur.

Requires the second stage bootloader or a compatible firmware.

reenumerate()[source]

Trigger re-enumeration.

Requires the second stage bootloader or a compatible firmware.

exception fx2.FX2DeviceError[source]

An exception raised on a communication error.

fx2.format.autodetect(file)[source]

Autodetect file format based on properties of a given file object.

Returns “ihex” for .hex, .ihex and .ihx file extensions, “bin” for .bin file extension, “hex” if file is a TTY, and raises ValueError otherwise.

fx2.format.input_data(file_or_data, fmt='auto', offset=0)[source]

Read Intel HEX, hexadecimal, or binary data from file_or_data. If file_or_data is a string, it is treated as hexadecimal. Otherwise, the format is determined by the fmt argument.

Raises ValueError if the input data has invalid format.

Returns a list of (address, data) chunks.

Parameters
  • fmt"ihex" for Intel HEX, "hex" for hexadecimal, "bin" for binary, or "auto" for autodetection via autodetect().

  • offset – Offset the data by specified amount of bytes.

fx2.format.output_data(file, data, fmt='auto', offset=0)[source]

Write Intel HEX, hexadecimal, or binary data to file.

Parameters
  • data – A byte array (bytes, bytearray and list of (addr, chunk) pairs are all valid).

  • fmt"ihex" for Intel HEX, "hex" for hexadecimal, "bin" for binary, or "auto" for autodetection via autodetect().

  • offset – Offset the data by specified amount of bytes.

fx2.format.flatten_data(data, *, fill=0)[source]

Flatten a list of (addr, chunk) pairs, such as that returned by input_data(), to a flat byte array, such as that accepted by output_data().

fx2.format.diff_data(old, new)[source]

Compute the difference between old and new byte arrays, and return a list of (addr, chunk) pairs containing only the bytes that are changed between new and old.

Build system reference

libfx2 provides a flexible build system based on GNU Make for convenient development. It provides:

  • out-of-tree builds,

  • rebuilds after changes to application headers,

  • rebuilds (of both libfx2 and application) after changes to libfx2,

  • minimal and readable configuration for most common cases,

  • a load target for building and uploading the design using fx2tool.

To start using it, create a source file…

main.c
#include <fx2regs.h>

int main() {
  IOA = OEA = 1;
  while(1);
}

... and a Makefile, replacing .../libfx2 with the path to the root of this repository…

Makefile
LIBFX2 = .../libfx2/firmware/library
include $(LIBFX2)/fx2rules.mk

... and you’re done! Running make will build a firmware.ihex, and running make load will run it on any connected Cypress development kit.

Of course, as your project grows, so has your build system. The configuration values that may be set are as follows:

  • TARGET sets the base name of the output Intel HEX file. It is firmware if not specified.

  • SOURCES lists the .c or .asm source files to be built, without extension. It is main if not specified.

  • LIBRARIES lists the standard libraries to be linked in, without extension. It is fx2isrs by default, and can be any of fx2, fx2isrs and fx2usb.

  • VID, PID set the USB VID:PID pair used to search for the development board. They are 04B4:8613 if not specified, which is the VID:PID pair of the Cypress development kit.

  • MODEL sets the sdcc code model, one of small, medium, large or huge. The libfx2 standard library as well as sdcc standard library are built for all code models. It is small if not specified.

  • CODE_SIZE, XRAM_SIZE set the sizes of the corresponding sdcc segments. The CODE and XRAM segments must add up to at most 0x4000. They are 0x3e00 and 0x0200 if not specified.

  • CFLAGS appends arbitrary flags to every sdcc invocation.

An elaborate Makefile could look as follows:

Makefile
VID      ?= 20b7
PID      ?= 9db1

TARGET    = glasgow
SOURCES   = main leds fpga dac_ldo adc
LIBRARIES = fx2 fx2usb fx2isrs
MODEL     = medium
CODE_SIZE = 0x3000
XRAM_SIZE = 0x1000
CFLAGS    = -DSYNCDELAYLEN=16

LIBFX2    = ../vendor/libfx2/firmware/library
include $(LIBFX2)/fx2rules.mk

Device-side library reference

usb.h

The usb.h header contains standard USB request and descriptor definitions. See the USB 2.0 specification, chapter 9 for details.

Reference

Typedefs

typedef const struct usb_desc_generic usb_desc_generic_c
typedef const struct usb_desc_device usb_desc_device_c
typedef struct usb_desc_device usb_desc_device_t
typedef const struct usb_desc_device_qualifier usb_desc_device_qualifier_c
typedef const struct usb_desc_configuration usb_desc_configuration_c
typedef const struct usb_desc_interface usb_desc_interface_c
typedef const struct usb_desc_endpoint usb_desc_endpoint_c
typedef const struct usb_desc_langid usb_desc_langid_c
typedef const struct usb_desc_string usb_desc_string_c

Enums

enum usb_direction

Values:

enumerator USB_DIR_OUT
enumerator USB_DIR_IN
enumerator USB_DIR_MASK
enum usb_type

Values:

enumerator USB_TYPE_STANDARD
enumerator USB_TYPE_CLASS
enumerator USB_TYPE_VENDOR
enumerator USB_TYPE_MASK
enum usb_recipient

Values:

enumerator USB_RECIP_DEVICE
enumerator USB_RECIP_IFACE
enumerator USB_RECIP_ENDPT
enumerator USB_RECIP_OTHER
enumerator USB_RECIP_MASK
enum usb_request

Values:

enumerator USB_REQ_GET_STATUS
enumerator USB_REQ_CLEAR_FEATURE
enumerator USB_REQ_SET_FEATURE
enumerator USB_REQ_SET_ADDRESS
enumerator USB_REQ_GET_DESCRIPTOR
enumerator USB_REQ_SET_DESCRIPTOR
enumerator USB_REQ_GET_CONFIGURATION
enumerator USB_REQ_SET_CONFIGURATION
enumerator USB_REQ_GET_INTERFACE
enumerator USB_REQ_SET_INTERFACE
enumerator USB_REQ_SYNCH_FRAME
enum usb_descriptor

Values:

enumerator USB_DESC_DEVICE
enumerator USB_DESC_CONFIGURATION
enumerator USB_DESC_STRING
enumerator USB_DESC_INTERFACE
enumerator USB_DESC_ENDPOINT
enumerator USB_DESC_DEVICE_QUALIFIER
enumerator USB_DESC_OTHER_SPEED_CONFIGURATION
enumerator USB_DESC_INTERFACE_POWER
enum usb_feature

Values:

enumerator USB_FEAT_DEVICE_REMOTE_WAKEUP
enumerator USB_FEAT_ENDPOINT_HALT
enumerator USB_FEAT_TEST_MODE
enum usb_attributes

Values:

enumerator USB_ATTR_RESERVED_1
enumerator USB_ATTR_SELF_POWERED
enumerator USB_ATTR_REMOTE_WAKEUP
enum usb_transfer_type

Values:

enumerator USB_XFER_CONTROL
enumerator USB_XFER_ISOCHRONOUS
enumerator USB_XFER_BULK
enumerator USB_XFER_INTERRUPT
enumerator USB_XFER_MASK
enum usb_synchronization_type

Values:

enumerator USB_SYNC_NONE
enumerator USB_SYNC_ASYNCHRONOUS
enumerator USB_SYNC_ADAPTIVE
enumerator USB_SYNC_SYNCHRONOUS
enumerator USB_SYNC_MASK
enum usb_usage_type

Values:

enumerator USB_USAGE_DATA
enumerator USB_USAGE_FEEDBACK
enumerator USB_USAGE_IMPLICIT_FEEDBACK_DATA
enumerator USB_USAGE_MASK
enum usb_tx_per_microframe

Values:

enumerator USB_TX_1_PER_MICROFRAME
enumerator USB_TX_2_PER_MICROFRAME
enumerator USB_TX_3_PER_MICROFRAME
enum [anonymous]

Values:

enumerator USB_DEV_CLASS_PER_INTERFACE
enumerator USB_DEV_SUBCLASS_PER_INTERFACE
enumerator USB_DEV_PROTOCOL_PER_INTERFACE
enumerator USB_DEV_CLASS_VENDOR
enumerator USB_DEV_SUBCLASS_VENDOR
enumerator USB_DEV_PROTOCOL_VENDOR
enum [anonymous]

Values:

enumerator USB_IFACE_CLASS_APP_SPECIFIC
enumerator USB_IFACE_CLASS_VENDOR
enumerator USB_IFACE_SUBCLASS_VENDOR
enumerator USB_IFACE_PROTOCOL_VENDOR
struct usb_req_setup
#include <usb.h>

Public Members

uint8_t bmRequestType
uint8_t bRequest
uint16_t wValue
uint16_t wIndex
uint16_t wLength
struct usb_desc_generic
#include <usb.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t data[]
struct usb_desc_device
#include <usb.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint16_t bcdUSB
uint8_t bDeviceClass
uint8_t bDeviceSubClass
uint8_t bDeviceProtocol
uint8_t bMaxPacketSize0
uint16_t idVendor
uint16_t idProduct
uint16_t bcdDevice
uint8_t iManufacturer
uint8_t iProduct
uint8_t iSerialNumber
uint8_t bNumConfigurations
struct usb_desc_device_qualifier
#include <usb.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint16_t bcdUSB
uint8_t bDeviceClass
uint8_t bDeviceSubClass
uint8_t bDeviceProtocol
uint8_t bMaxPacketSize0
uint8_t bNumConfigurations
uint8_t bReserved
struct usb_desc_configuration
#include <usb.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint16_t wTotalLength
uint8_t bNumInterfaces
uint8_t bConfigurationValue
uint8_t iConfiguration
uint8_t bmAttributes
uint8_t bMaxPower
struct usb_desc_interface
#include <usb.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t bInterfaceNumber
uint8_t bAlternateSetting
uint8_t bNumEndpoints
uint8_t bInterfaceClass
uint8_t bInterfaceSubClass
uint8_t bInterfaceProtocol
uint8_t iInterface
struct usb_desc_endpoint
#include <usb.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t bEndpointAddress
uint8_t bmAttributes
uint16_t wMaxPacketSize
uint8_t bInterval
struct usb_desc_langid
#include <usb.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint16_t wLANGID[]
struct usb_desc_string
#include <usb.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t bString[]

usbmicrosoft.h

The usbmicrosoft.h header contains Microsoft-specific USB request and descriptor definitions. See the Microsoft OS Descriptors for USB Devices page for details.

Reference

Defines

USB_DESC_MICROSOFT_V10_SIGNATURE

Typedefs

typedef const struct usb_desc_microsoft_v10 usb_desc_microsoft_v10_c
typedef const struct usb_desc_ms_ext_compat_id usb_desc_ms_ext_compat_id_c

Enums

enum usb_descriptor_microsoft

Values:

enumerator USB_DESC_MS_EXTENDED_COMPAT_ID
enumerator USB_DESC_MS_EXTENDED_PROPERTIES
struct usb_desc_microsoft_v10
#include <usbmicrosoft.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t qwSignature[14]
uint8_t bMS_VendorCode
uint8_t bPad
struct usb_desc_ms_compat_function
#include <usbmicrosoft.h>

Public Members

uint8_t bFirstInterfaceNumber
uint8_t bReserved1
uint8_t compatibleID[8]
uint8_t subCompatibleID[8]
uint8_t bReserved[6]
struct usb_desc_ms_ext_compat_id
#include <usbmicrosoft.h>

Public Members

uint32_t dwLength
uint16_t bcdVersion
uint16_t wIndex
uint8_t bCount
uint8_t bReserved[7]
struct usb_desc_ms_compat_function functions[]

usbdfu.h

The usbdfu.h header contains USB Device Firmware Upgrade interface class request and descriptor definitions. See the USB Device Class Specification for Device Firmware Upgrade document for details.

Reference

Defines

USB_DFU_STATUS_NAMES

Typedefs

typedef const struct usb_dfu_desc_functional usb_dfu_desc_functional_c
typedef enum usb_dfu_status usb_dfu_status_t

Enums

enum [anonymous]

Values:

enumerator USB_DESC_DFU_FUNCTIONAL
enum usb_dfu_attributes

Values:

enumerator USB_DFU_ATTR_CAN_DNLOAD
enumerator USB_DFU_ATTR_CAN_UPLOAD
enumerator USB_DFU_ATTR_MANIFESTATION_TOLERANT
enumerator USB_DFU_ATTR_WILL_DETACH
enum [anonymous]

Values:

enumerator USB_IFACE_SUBCLASS_DFU
enumerator USB_IFACE_PROTOCOL_DFU_RUNTIME
enumerator USB_IFACE_PROTOCOL_DFU_UPGRADE
enum usb_dfu_request

Values:

enumerator USB_DFU_REQ_DETACH
enumerator USB_DFU_REQ_DNLOAD
enumerator USB_DFU_REQ_UPLOAD
enumerator USB_DFU_REQ_GETSTATUS
enumerator USB_DFU_REQ_CLRSTATUS
enumerator USB_DFU_REQ_GETSTATE
enumerator USB_DFU_REQ_ABORT
enum usb_dfu_state

Values:

enumerator USB_DFU_STATE_appIDLE

Device is running its normal application.

enumerator USB_DFU_STATE_appDETACH

Device is running its normal application, has received the DFU_DETACH request, and is waiting for a USB reset.

enumerator USB_DFU_STATE_dfuIDLE

Device is operating in the DFU mode and is waiting for requests.

enumerator USB_DFU_STATE_dfuDNLOAD_SYNC

Device has received a block and is waiting for the host to solicit the status via DFU_GETSTATUS.

enumerator USB_DFU_STATE_dfuDNBUSY

Device is programming a control-write block into its nonvolatile memories.

enumerator USB_DFU_STATE_dfuDNLOAD_IDLE

Device is processing a download operation. Expecting DFU_DNLOAD requests.

enumerator USB_DFU_STATE_dfuMANIFEST_SYNC

Device has received the final block of firmware from the host and is waiting for receipt of DFU_GETSTATUS to begin the Manifestation phase; or device has completed the Manifestation phase and is waiting for receipt of DFU_GETSTATUS. (Devices that can enter this state after the Manifestation phase set bmAttributes bit bitManifestationTolerant to 1.)

enumerator USB_DFU_STATE_dfuMANIFEST

Device is in the Manifestation phase. (Not all devices will be able to respond to DFU_GETSTATUS when in this state.)

enumerator USB_DFU_STATE_dfuMANIFEST_WAIT_RESET

Device has programmed its memories and is waiting for a USB reset or a power on reset. (Devices that must enter this state clear bitManifestationTolerant to 0.)

enumerator USB_DFU_STATE_dfuUPLOAD_IDLE

The device is processing an upload operation. Expecting DFU_UPLOAD requests.

enumerator USB_DFU_STATE_dfuERROR

An error has occurred. Awaiting the DFU_CLRSTATUS request.

enum usb_dfu_status

Values:

enumerator USB_DFU_STATUS_OK

No error condition is present.

enumerator USB_DFU_STATUS_errTARGET

File is not targeted for use by this device.

enumerator USB_DFU_STATUS_errFILE

File is for this device but fails some vendor-specific verification test.

enumerator USB_DFU_STATUS_errWRITE

Device is unable to write memory.

enumerator USB_DFU_STATUS_errERASE

Memory erase function failed.

enumerator USB_DFU_STATUS_errCHECK_ERASED

Memory erase check failed.

enumerator USB_DFU_STATUS_errPROG

Program memory function failed.

enumerator USB_DFU_STATUS_errVERIFY

Programmed memory failed verification.

enumerator USB_DFU_STATUS_errADDRESS

Cannot program memory due to received address that is out of range.

enumerator USB_DFU_STATUS_errNOTDONE

Received DFU_DNLOAD with wLength = 0, but device does not think it has all of the data yet.

enumerator USB_DFU_STATUS_errFIRMWARE

Device’s firmware is corrupt. It cannot return to run-time (non-DFU) operations.

enumerator USB_DFU_STATUS_errVENDOR

iString indicates a vendor-specific error.

enumerator USB_DFU_STATUS_errUSBR

Device detected unexpected USB reset signaling.

enumerator USB_DFU_STATUS_errPOR

Device detected unexpected power on reset.

enumerator USB_DFU_STATUS_errUNKNOWN

Something went wrong, but the device does not know what it was.

enumerator USB_DFU_STATUS_errSTALLEDPKT

Device stalled an unexpected request.

struct usb_dfu_desc_functional
#include <usbdfu.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t bmAttributes
uint16_t wDetachTimeOut
uint16_t wTransferSize
uint16_t bcdDFUVersion
struct usb_dfu_req_get_status
#include <usbdfu.h>

Public Members

uint8_t bStatus
uint8_t bwPollTimeout
uint16_t bwPollTimeoutHigh
uint8_t bState
uint8_t iString

usbcdc.h

The usbcdc.h header contains USB Communications device and interface class request and descriptor definitions. See the USB Class Definitions for Communications Devices document as well as USB Communications Class Subclass Specification documents for details.

Reference

Typedefs

typedef const struct usb_cdc_desc_functional_header usb_cdc_desc_functional_header_c
typedef const struct usb_cdc_desc_functional_call_mgmt usb_cdc_desc_functional_call_mgmt_c
typedef const struct usb_cdc_desc_functional_acm usb_cdc_desc_functional_acm_c
typedef const struct usb_cdc_desc_functional_union usb_cdc_desc_functional_union_c

Enums

enum [anonymous]

Values:

enumerator USB_DEV_CLASS_CDC

Communications Device Class.

enumerator USB_IFACE_CLASS_CIC

Communications Interface Class.

enumerator USB_IFACE_CLASS_DIC

Data Interface Class.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_DLCM

Direct Line Control Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_ACM

Abstract Control Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_TCM

Telephone Control Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_MCCM

Multi-Channel Control Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_CAPICM

CAPI Control Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_ENCM

Ethernet Networking Control Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_ATMNCM

ATM Networking Control Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_WHCM

Wireless Handset Control Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_DEV_MGMT

Device Management Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_MDLM

Mobile Direct Line Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_OBEX

OBEX Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_EEM

Ethernet Emulation Model Interface Subclass.

enumerator USB_IFACE_SUBCLASS_CDC_CIC_NCM

Network Control Model Interface Subclass.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_NONE

Communications Interface Protocol: No class specific protocol required.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_AT_V250

Communications Interface Protocol: AT Commands: V.250 etc.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_AT_PCCA_101

Communications Interface Protocol: AT Commands defined by PCCA-101.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_AT_PCCA_101_ANNEX_O

Communications Interface Protocol: AT Commands defined by PCCA-101 & Annex O.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_GSM_07_07

Communications Interface Protocol: AT Commands defined by GSM 07.07.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_3GPP_27_007

Communications Interface Protocol: AT Commands defined by 3GPP 27.007.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_TIA_CDMA

Communications Interface Protocol: AT Commands defined by TIA for CDMA.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_EEM

Communications Interface Protocol: Ethernet Emulation Model.

enumerator USB_IFACE_PROTOCOL_CDC_CIC_EXTERNAL

Communications Interface Protocol: Commands defined by Command Set Functional Descriptor.

enumerator USB_IFACE_SUBCLASS_CDC_DIC

Data Interface Subclass.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_NONE

Data Interface Protocol: No class specific protocol required.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_NTB

Data Interface Protocol: Network Transfer Block.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_I_430

Data Interface Protocol: Physical interface protocol for ISDN BRI.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_HDLC

Data Interface Protocol: HDLC.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_TRANSPARENT

Data Interface Protocol: Transparent.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_Q_921M

Data Interface Protocol: Management protocol for Q.921 data link protocol.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_Q_921D

Data Interface Protocol: Data link protocol for Q.931.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_Q_921TM

Data Interface Protocol: TEI-multiplexor for Q.921 data link protocol.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_V_42BIS

Data Interface Protocol: Data compression procedures.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_Q_931_EURO_ISDN

Data Interface Protocol: Euro-ISDN protocol control.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_V_120

Data Interface Protocol: V.24 rate adaptation to ISDN.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_CAPI_2_0

Data Interface Protocol: CAPI Commands.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_HOST_BASED

Data Interface Protocol: Host based driver.

enumerator USB_IFACE_PROTOCOL_CDC_DIC_EXTERNAL

Data Interface Protocol: Protocol(s) defined by Protocol Unit Functional Descriptors on Communications Class Interface

enum [anonymous]

Values:

enumerator USB_DESC_CS_INTERFACE
enumerator USB_DESC_CS_ENDPOINT
enum usb_cdc_desc_functional_subtype

Values:

enumerator USB_DESC_CDC_FUNCTIONAL_SUBTYPE_HEADER

Header Functional Descriptor.

enumerator USB_DESC_CDC_FUNCTIONAL_SUBTYPE_CALL_MGMT

Call Management Functional Descriptor.

enumerator USB_DESC_CDC_FUNCTIONAL_SUBTYPE_ACM

Abstract Control Management Functional Descriptor.

enumerator USB_DESC_CDC_FUNCTIONAL_SUBTYPE_UNION

Union Functional Descriptor.

enum [anonymous]

Values:

enumerator USB_CDC_CALL_MGMT_CAP_HANDLES_CALL_MGMT

Not set - Device does not handle call management itself. Set - Device handles call management itself.

enumerator USB_CDC_CALL_MGMT_CAP_CALL_MGMT_OVER_DATA

Not set - Device sends/receives call management information only over the Communications Class interface. Set - Device can send/receive call management information over a Data Class interface.

enum [anonymous]

Values:

enumerator USB_CDC_ACM_CAP_REQ_COMM_FEATURE

Set - Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature.

enumerator USB_CDC_ACM_CAP_REQ_LINE_CODING_STATE

Set - Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State.

enumerator USB_CDC_ACM_CAP_REQ_SEND_BREAK

Set - Device supports the request Send_Break.

enumerator USB_CDC_ACM_CAP_REQ_NETWORK_CONNECTION

Set - Device supports the notification Network_Connection.

enum usb_cdc_request

Class-Specific Request Codes.

Values:

enumerator USB_CDC_REQ_SEND_ENCAPSULATED_COMMAND
enumerator USB_CDC_REQ_GET_ENCAPSULATED_RESPONSE
enum usb_cdc_pstn_request

Class-Specific Request Codes for PSTN subclasses.

Values:

enumerator USB_CDC_PSTN_REQ_SET_COMM_FEATURE
enumerator USB_CDC_PSTN_REQ_GET_COMM_FEATURE
enumerator USB_CDC_PSTN_REQ_CLEAR_COMM_FEATURE
enumerator USB_CDC_PSTN_REQ_SET_AUX_LINE_STATE
enumerator USB_CDC_PSTN_REQ_SET_HOOK_STATE
enumerator USB_CDC_PSTN_REQ_PULSE_SETUP
enumerator USB_CDC_PSTN_REQ_SEND_PULSE
enumerator USB_CDC_PSTN_REQ_SET_PULSE_TIME
enumerator USB_CDC_PSTN_REQ_RING_AUX_JACK
enumerator USB_CDC_PSTN_REQ_SET_LINE_CODING
enumerator USB_CDC_PSTN_REQ_GET_LINE_CODING
enumerator USB_CDC_PSTN_REQ_SET_CONTROL_LINE_STATE
enumerator USB_CDC_PSTN_REQ_SEND_BREAK
enumerator USB_CDC_PSTN_REQ_SET_RINGER_PARMS
enumerator USB_CDC_PSTN_REQ_GET_RINGER_PARMS
enumerator USB_CDC_PSTN_REQ_SET_OPERATION_PARMS
enumerator USB_CDC_PSTN_REQ_GET_OPERATION_PARMS
enumerator USB_CDC_PSTN_REQ_SET_LINE_PARMS
enumerator USB_CDC_PSTN_REQ_GET_LINE_PARMS
enumerator USB_CDC_PSTN_REQ_DIAL_DIGITS
enum [anonymous]

Values:

enumerator USB_CDC_REQ_LINE_CODING_STOP_BITS_1
enumerator USB_CDC_REQ_LINE_CODING_STOP_BITS_1_5
enumerator USB_CDC_REQ_LINE_CODING_STOP_BITS_2
enumerator USB_CDC_REQ_LINE_CODING_PARITY_NONE
enumerator USB_CDC_REQ_LINE_CODING_PARITY_ODD
enumerator USB_CDC_REQ_LINE_CODING_PARITY_EVEN
enumerator USB_CDC_REQ_LINE_CODING_PARITY_MARK
enumerator USB_CDC_REQ_LINE_CODING_PARITY_SPACE
struct usb_cdc_desc_functional_header
#include <usbcdc.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t bDescriptorSubType
uint16_t bcdCDC
struct usb_cdc_desc_functional_call_mgmt
#include <usbcdc.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t bDescriptorSubType
uint8_t bmCapabilities
uint8_t bDataInterface
struct usb_cdc_desc_functional_acm
#include <usbcdc.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t bDescriptorSubType
uint8_t bmCapabilities
struct usb_cdc_desc_functional_union
#include <usbcdc.h>

Public Members

uint8_t bLength
uint8_t bDescriptorType
uint8_t bDescriptorSubType
uint8_t bControlInterface
uint8_t bSubordinateInterface[]
struct usb_cdc_req_line_coding
#include <usbcdc.h>

Public Members

uint32_t dwDTERate
uint8_t bCharFormat
uint8_t bParityType
uint8_t bDataBits

usbmassstor.h

The usbmassstor.h header contains USB Mass Storage interface class request and descriptor definitions. See the USB Mass Storage Class Specification Overview and USB Mass Storage Class Bulk-Only Transport documents for details.

Reference

Typedefs

typedef struct usb_mass_storage_cbw usb_mass_storage_cbw_t
typedef struct usb_mass_storage_csw usb_mass_storage_csw_t

Enums

enum [anonymous]

Values:

enumerator USB_IFACE_CLASS_MASS_STORAGE
enumerator USB_IFACE_SUBCLASS_MASS_STORAGE_RBC
enumerator USB_IFACE_SUBCLASS_MASS_STORAGE_ATAPI
enumerator USB_IFACE_SUBCLASS_MASS_STORAGE_UFI
enumerator USB_IFACE_SUBCLASS_MASS_STORAGE_SCSI
enumerator USB_IFACE_SUBCLASS_MASS_STORAGE_LSD_FS
enumerator USB_IFACE_SUBCLASS_MASS_STORAGE_IEEE_1667
enumerator USB_IFACE_PROTOCOL_MASS_STORAGE_CBI_COMPL
enumerator USB_IFACE_PROTOCOL_MASS_STORAGE_CBI
enumerator USB_IFACE_PROTOCOL_MASS_STORAGE_BBB
enumerator USB_IFACE_PROTOCOL_MASS_STORAGE_UAS
enum usb_mass_storage_request

Values:

enumerator USB_REQ_MASS_STORAGE_ADSC
enumerator USB_REQ_MASS_STORAGE_GET_REQUESTS
enumerator USB_REQ_MASS_STORAGE_PUT_REQUESTS
enumerator USB_REQ_MASS_STORAGE_GET_MAX_LUN
enumerator USB_REQ_MASS_STORAGE_BOMSR
enum [anonymous]

Values:

enumerator USB_MASS_STORAGE_CBW_SIGNATURE
enum usb_mass_storage_cbw_flags

Values:

enumerator USB_MASS_STORAGE_CBW_FLAG_DATA_IN
enumerator USB_MASS_STORAGE_CBW_RESERVED_FLAGS
enum [anonymous]

Values:

enumerator USB_MASS_STORAGE_CSW_SIGNATURE
enum usb_mass_storage_csw_status

Values:

enumerator USB_MASS_STORAGE_CSW_STATUS_PASSED
enumerator USB_MASS_STORAGE_CSW_STATUS_FAILED
enumerator USB_MASS_STORAGE_CSW_STATUS_PHASE_ERROR
struct usb_mass_storage_cbw
#include <usbmassstor.h>

Public Members

uint32_t dCBWSignature
uint32_t dCBWTag
uint32_t dCBWDataTransferLength
uint8_t bmCBWFlags
uint8_t bCBWLUN
uint8_t bCBWCBLength
uint8_t CBWCB[16]
struct usb_mass_storage_csw
#include <usbmassstor.h>

Public Members

uint32_t dCSWSignature
uint32_t dCSWTag
uint32_t dCSWDataResidue
uint8_t bCSWStatus

fx2regs.h

The fx2regs.h header contains register definitions for the Cypress FX2 series.

Renamed registers

All definitions are (semi-)automatically generated from the datasheet information, and names match the datasheet, except where that would result in a conflict.

The following definitions are changed:

  • in the TMOD register, bits corresponding to the TIMER0 and TIMER1 peripherals are suffixed with _0 and _1,

  • in the PORTECFG register, bit INT6 is renamed to INT6,

  • in the EPnGPIFPFSTOP registers, bit FIFOnFLAG is renamed to FIFOFLAG,

  • in the GPIFTRIG and GPIFIDLECS registers, bit GPIFDONE is renamed to GPIFIDLE.

The following definitions are absent:

  • all EPn and PKTSn bit definitions.

All bit definitions that are a part of a two’s-complement number (e.g. An and Dn address and data bits) are also absent.

Reference

Bits from register DPS

_SEL

Bit 0.

Bits from register PCON

_IDLE

Bit 0.

_SMOD0

Bit 7.

Bits from register TCON

_IT0

Bit 0.

_IE0

Bit 1.

_IT1

Bit 2.

_IE1

Bit 3.

_TR0

Bit 4.

_TF0

Bit 5.

_TR1

Bit 6.

_TF1

Bit 7.

Bits from register TMOD

_M0_0

Bit 0.

_M1_0

Bit 1.

_CT_0

Bit 2.

_GATE_0

Bit 3.

_M0_1

Bit 4.

_M1_1

Bit 5.

_CT_1

Bit 6.

_GATE_1

Bit 7.

Bits from register CKCON

_MD0

Bit 0.

_MD1

Bit 1.

_MD2

Bit 2.

_T0M

Bit 3.

_T1M

Bit 4.

_T2M

Bit 5.

Bits from register EXIF

_USBINT

Bit 4.

_I2CINT

Bit 5.

_IE4

Bit 6.

_IE5

Bit 7.

Bits from register SCON0

_RI_0

Bit 0.

_TI_0

Bit 1.

_RB8_0

Bit 2.

_TB8_0

Bit 3.

_REN_0

Bit 4.

_SM2_0

Bit 5.

_SM1_0

Bit 6.

_SM0_0

Bit 7.

Bits from register IE

_EX0

Bit 0.

_ET0

Bit 1.

_EX1

Bit 2.

_ET1

Bit 3.

_ES0

Bit 4.

_ET2

Bit 5.

_ES1

Bit 6.

_EA

Bit 7.

Bits from register EP2468STAT

_EP2E

Bit 0.

_EP2F

Bit 1.

_EP4E

Bit 2.

_EP4F

Bit 3.

_EP6E

Bit 4.

_EP6F

Bit 5.

_EP8E

Bit 6.

_EP8F

Bit 7.

Bits from register EP24FIFOFLGS

_EP2FF

Bit 0.

_EP2EF

Bit 1.

_EP2PF

Bit 2.

_EP4FF

Bit 4.

_EP4EF

Bit 5.

_EP4PF

Bit 6.

Bits from register EP68FIFOFLGS

_EP6FF

Bit 0.

_EP6EF

Bit 1.

_EP6PF

Bit 2.

_EP8FF

Bit 4.

_EP8EF

Bit 5.

_EP8PF

Bit 6.

Bits from register AUTOPTRSETUP

_APTREN

Bit 0.

_APTR1INC

Bit 1.

_APTR2INC

Bit 2.

Bits from register IP

_PX0

Bit 0.

_PT0

Bit 1.

_PX1

Bit 2.

_PT1

Bit 3.

_PS0

Bit 4.

_PT2

Bit 5.

_PS1

Bit 6.

Bits from register EP01STAT

_EP1OUTBSY

Bit 1.

_EP1INBSY

Bit 2.

Bits from register GPIFTRIG

_RW

Bit 2.

Bits from registers GPIFIDLECS, GPIFTRIG

_GPIFIDLE

Bit 7.

Bits from register SCON1

_RI_1

Bit 0.

_TI_1

Bit 1.

_RB8_1

Bit 2.

_TB8_1

Bit 3.

_REN_1

Bit 4.

_SM2_1

Bit 5.

_SM1_1

Bit 6.

_SM0_1

Bit 7.

Bits from register T2CON

_CPRL2

Bit 0.

_CT2

Bit 1.

_TR2

Bit 2.

_EXEN2

Bit 3.

_TCLK

Bit 4.

_RCLK

Bit 5.

_EXF2

Bit 6.

_TF2

Bit 7.

Bits from register PSW

_P

Bit 0.

_F1

Bit 1.

_OV

Bit 2.

_RS0

Bit 3.

_RS1

Bit 4.

_F0

Bit 5.

_AC

Bit 6.

_CY

Bit 7.

Bits from register EICON

_INT6

Bit 4.

_RESI

Bit 5.

_ERESI

Bit 6.

Bits from register EIE

_EUSB

Bit 0.

_EI2C

Bit 1.

_EX4

Bit 2.

_EX5

Bit 3.

_EX6

Bit 4.

Bits from register EIP

_PUSB

Bit 1.

_PI2C

Bit 2.

_PX4

Bit 3.

_PX5

Bit 4.

_PX6

Bit 5.

Bits from register GPCR2

_FULL_SPEED_ONLY

Bit 4.

Bits from register CPUCS

_8051RES

Bit 0.

_CLKOE

Bit 1.

_CLKINV

Bit 2.

_CLKSPD0

Bit 3.

_CLKSPD1

Bit 4.

_PORTCSTB

Bit 5.

Bits from register IFCONFIG

_IFCFG0

Bit 0.

_IFCFG1

Bit 1.

_GSTATE

Bit 2.

_ASYNC

Bit 3.

_IFCLKPOL

Bit 4.

_IFCLKOE

Bit 5.

_3048MHZ

Bit 6.

_IFCLKSRC

Bit 7.

Bits from register PINFLAGSAB

_FLAGA0

Bit 0.

_FLAGA1

Bit 1.

_FLAGA2

Bit 2.

_FLAGA3

Bit 3.

_FLAGB0

Bit 4.

_FLAGB1

Bit 5.

_FLAGB2

Bit 6.

_FLAGB3

Bit 7.

Bits from register PINFLAGSCD

_FLAGC0

Bit 0.

_FLAGC1

Bit 1.

_FLAGC2

Bit 2.

_FLAGC3

Bit 3.

_FLAGD0

Bit 4.

_FLAGD1

Bit 5.

_FLAGD2

Bit 6.

_FLAGD3

Bit 7.

Bits from register FIFORESET

_NAKALL

Bit 7.

Bits from register BREAKPT

_BPEN

Bit 1.

_BPPULSE

Bit 2.

_BREAK

Bit 3.

Bits from register UART230

_230UART0

Bit 0.

_230UART1

Bit 1.

Bits from register FIFOPINPOLAR

_SLWR

Bit 2.

_SLRD

Bit 3.

_SLOE

Bit 4.

_PKTEND

Bit 5.

Bits from registers EP2FIFOFLGS, EP2FIFOIE, EP2FIFOIRQ, EP4FIFOFLGS, EP4FIFOIE, EP4FIFOIRQ, EP6FIFOFLGS, EP6FIFOIE, EP6FIFOIRQ, EP8FIFOFLGS, EP8FIFOIE, EP8FIFOIRQ, FIFOPINPOLAR

_FF

Bit 0.

_EF

Bit 1.

Bits from register REVCTL

_ENH_PKT

Bit 0.

_DYN_OUT

Bit 1.

Bits from register GPIFHOLDAMOUNT

_HOLDTIME0

Bit 0.

_HOLDTIME1

Bit 1.

Bits from registers EP2CFG, EP6CFG

_BUF0

Bit 0.

_BUF1

Bit 1.

_SIZE

Bit 3.

Bits from registers EP2CFG, EP4CFG, EP6CFG, EP8CFG

_DIR

Bit 6.

Bits from registers EP1INCFG, EP1OUTCFG, EP2CFG, EP4CFG, EP6CFG, EP8CFG

_TYPE0

Bit 4.

_TYPE1

Bit 5.

_VALID

Bit 7.

Bits from registers EP2FIFOCFG, EP4FIFOCFG, EP6FIFOCFG, EP8FIFOCFG

_WORDWIDE

Bit 0.

_ZEROLENIN

Bit 2.

_AUTOIN

Bit 3.

_AUTOOUT

Bit 4.

_OEP1

Bit 5.

_INFM1

Bit 6.

Bits from register ECCCFG

_ECCM

Bit 0.

Bits from registers EP2FIFOPFH, EP4FIFOPFH, EP6FIFOPFH, EP8FIFOPFH

_PKTSTAT

Bit 6.

_DECIS

Bit 7.

Bits from registers EP2ISOINPKTS, EP4ISOINPKTS, EP6ISOINPKTS, EP8ISOINPKTS

_AADJ

Bit 7.

Bits from registers EP2BCL, EP4BCL, EP6BCL, EP8BCL, INPKTEND, OUTPKTEND

_SKIP

Bit 7.

Bits from registers EP2FIFOIE, EP4FIFOIE, EP6FIFOIE, EP8FIFOIE

_EDGEPF

Bit 3.

Bits from registers EP2FIFOFLGS, EP2FIFOIE, EP2FIFOIRQ, EP4FIFOFLGS, EP4FIFOIE, EP4FIFOIRQ, EP6FIFOFLGS, EP6FIFOIE, EP6FIFOIRQ, EP8FIFOFLGS, EP8FIFOIE, EP8FIFOIRQ

_PF

Bit 2.

Bits from registers IBNIE, IBNIRQ

_IBNI_EP0

Bit 0.

_IBNI_EP1

Bit 1.

_IBNI_EP2

Bit 2.

_IBNI_EP4

Bit 3.

_IBNI_EP6

Bit 4.

_IBNI_EP8

Bit 5.

Bits from registers NAKIE, NAKIRQ

_IBN

Bit 0.

Bits from registers USBIE, USBIRQ

_SUDAV

Bit 0.

_SOF

Bit 1.

_SUTOK

Bit 2.

_SUSP

Bit 3.

_URES

Bit 4.

_HSGRANT

Bit 5.

_EP0ACK

Bit 6.

Bits from registers EPIE, EPIRQ

_EPI_EP0IN

Bit 0.

_EPI_EP0OUT

Bit 1.

_EPI_EP1IN

Bit 2.

_EPI_EP1OUT

Bit 3.

_EPI_EP2

Bit 4.

_EPI_EP4

Bit 5.

_EPI_EP6

Bit 6.

_EPI_EP8

Bit 7.

Bits from registers GPIFIE, GPIFIRQ

_GPIFDONE

Bit 0.

_GPIFWF

Bit 1.

Bits from registers USBERRIE, USBERRIRQ

_ERRLIMIT

Bit 0.

_ISOEP2

Bit 4.

_ISOEP4

Bit 5.

_ISOEP6

Bit 6.

_ISOEP8

Bit 7.

Bits from register INTSETUP

_AV4EN

Bit 0.

_INT4SRC

Bit 1.

_AV2EN

Bit 3.

Bits from register PORTACFG

_INT0

Bit 0.

_INT1

Bit 1.

_SLCS

Bit 6.

_FLAGD

Bit 7.

Bits from register PORTCCFG

_GPIFA0

Bit 0.

_GPIFA1

Bit 1.

_GPIFA2

Bit 2.

_GPIFA3

Bit 3.

_GPIFA4

Bit 4.

_GPIFA5

Bit 5.

_GPIFA6

Bit 6.

_GPIFA7

Bit 7.

Bits from register PORTECFG

_T0OUT

Bit 0.

_T1OUT

Bit 1.

_T2OUT

Bit 2.

_RXD0OUT

Bit 3.

_RXD1OUT

Bit 4.

_INT6EX

Bit 5.

_T2EX

Bit 6.

_GPIFA8

Bit 7.

Bits from register I2CS

_DONE

Bit 0.

_ACK

Bit 1.

_BERR

Bit 2.

_ID0

Bit 3.

_ID1

Bit 4.

_LASTRD

Bit 5.

_STOP

Bit 6.

_START

Bit 7.

Bits from register I2CTL

_400KHZ

Bit 0.

_STOPIE

Bit 1.

Bits from register USBCS

_SIGRSUME

Bit 0.

_RENUM

Bit 1.

_NOSYNSOF

Bit 2.

_DISCON

Bit 3.

_HSM

Bit 7.

Bits from register WAKEUPCS

_WUEN

Bit 0.

_WU2EN

Bit 1.

_DPEN

Bit 2.

_WUPOL

Bit 4.

_WU2POL

Bit 5.

_WU

Bit 6.

_WU2

Bit 7.

Bits from register TOGCTL

_IO

Bit 4.

_R

Bit 5.

_S

Bit 6.

_Q

Bit 7.

Bits from register EP0CS

_HSNAK

Bit 7.

Bits from registers EP0CS, EP1INCS, EP1OUTCS

_BUSY

Bit 1.

Bits from registers EP2CS, EP6CS

_NPAK2

Bit 6.

Bits from registers EP2CS, EP4CS, EP6CS, EP8CS

_EMPTY

Bit 2.

_FULL

Bit 3.

_NPAK0

Bit 4.

_NPAK1

Bit 5.

Bits from registers EP0CS, EP1INCS, EP1OUTCS, EP2CS, EP4CS, EP6CS, EP8CS

_STALL

Bit 0.

Bits from register SUDPTRCTL

_SDPAUTO

Bit 0.

Bits from register GPIFWFSELECT

_FIFORD0

Bit 0.

_FIFORD1

Bit 1.

_FIFOWR0

Bit 2.

_FIFOWR1

Bit 3.

_SINGLERD0

Bit 4.

_SINGLERD1

Bit 5.

_SINGLEWR0

Bit 6.

_SINGLEWR1

Bit 7.

Bits from register GPIFIDLECS

_IDLEDRV

Bit 0.

Bits from register GPIFCTLCFG

_TRICTL

Bit 7.

Bits from registers FLOWEQ0CTL, FLOWEQ1CTL

_CTL0E0

Bit 4.

_CTL0E1

Bit 5.

_CTL0E2

Bit 6.

_CTL0E3

Bit 7.

Bits from registers FLOWEQ0CTL, FLOWEQ1CTL, GPIFCTLCFG, GPIFIDLECTL

_CTL0

Bit 0.

_CTL1

Bit 1.

_CTL2

Bit 2.

_CTL3

Bit 3.

_CTL4

Bit 4.

_CTL5

Bit 5.

Bits from register FLOWSTATE

_FS2

Bit 2.

_FSE

Bit 7.

Bits from registers EP2GPIFFLGSEL, EP4GPIFFLGSEL, EP6GPIFFLGSEL, EP8GPIFFLGSEL, FLOWSTATE

_FS0

Bit 0.

_FS1

Bit 1.

Bits from register FLOWLOGIC

_TERMB0

Bit 0.

_TERMB1

Bit 1.

_TERMB2

Bit 2.

_TERMA0

Bit 3.

_TERMA1

Bit 4.

_TERMA2

Bit 5.

_LFUNC0

Bit 6.

_LFUNC1

Bit 7.

Bits from register FLOWHOLDOFF

_HOCTL0

Bit 0.

_HOCTL1

Bit 1.

_HOCTL2

Bit 2.

_HOSTATE

Bit 3.

_HOPERIOD0

Bit 4.

_HOPERIOD1

Bit 5.

_HOPERIOD2

Bit 6.

_HOPERIOD3

Bit 7.

Bits from register FLOWSTB

_MSTB0

Bit 0.

_MSTB1

Bit 1.

_MSTB2

Bit 2.

_SUSTAIN

Bit 4.

_CTLTOGL

Bit 5.

_RDYASYNC

Bit 6.

_SLAVE

Bit 7.

Bits from register FLOWSTBEDGE

_RISING

Bit 0.

_FALLING

Bit 1.

Bits from registers EP2GPIFPFSTOP, EP4GPIFPFSTOP, EP6GPIFPFSTOP, EP8GPIFPFSTOP

_FIFOFLAG

Bit 0.

Bits from register GPIFREADYCFG

_TCXRDY5

Bit 5.

_SAS

Bit 6.

_INTRDY

Bit 7.

Bits from register GPIFREADYSTAT

_RDY0

Bit 0.

_RDY1

Bit 1.

_RDY2

Bit 2.

_RDY3

Bit 3.

_RDY4

Bit 4.

_RDY5

Bit 5.

Variables

sfr8_t _XPAGE

Alias of MPAGE used internally by sdcc.

sfr8_t IOA

Register 0x80: Port A.

sbit_t PA0

Register 0x80 bit 0: Port A bit PA0.

sbit_t PA1

Register 0x80 bit 1: Port A bit PA1.

sbit_t PA2

Register 0x80 bit 2: Port A bit PA2.

sbit_t PA3

Register 0x80 bit 3: Port A bit PA3.

sbit_t PA4

Register 0x80 bit 4: Port A bit PA4.

sbit_t PA5

Register 0x80 bit 5: Port A bit PA5.

sbit_t PA6

Register 0x80 bit 6: Port A bit PA6.

sbit_t PA7

Register 0x80 bit 7: Port A bit PA7.

sfr8_t SP

Register 0x81: Stack Pointer.

sfr8_t DPL0

Register 0x82: Data Pointer 0 L.

sfr16_t DP0

Register 0x82: Data Pointer 0.

sfr8_t DPH0

Register 0x83: Data Pointer 0 H.

sfr8_t DPL1

Register 0x84: Data Pointer 1 L.

sfr16_t DP1

Register 0x84: Data Pointer 1.

sfr8_t DPH1

Register 0x85: Data Pointer 1 H.

sfr8_t DPS

Register 0x86: Data Pointer 0/1 select.

sfr8_t PCON

Register 0x87: Power Control.

sfr8_t TCON

Register 0x88: Timer/Counter Control.

sbit_t IT0

Register 0x88 bit 0: Timer/Counter Control bit IT0.

sbit_t IE0

Register 0x88 bit 1: Timer/Counter Control bit IE0.

sbit_t IT1

Register 0x88 bit 2: Timer/Counter Control bit IT1.

sbit_t IE1

Register 0x88 bit 3: Timer/Counter Control bit IE1.

sbit_t TR0

Register 0x88 bit 4: Timer/Counter Control bit TR0.

sbit_t TF0

Register 0x88 bit 5: Timer/Counter Control bit TF0.

sbit_t TR1

Register 0x88 bit 6: Timer/Counter Control bit TR1.

sbit_t TF1

Register 0x88 bit 7: Timer/Counter Control bit TF1.

sfr8_t TMOD

Register 0x89: Timer/Counter Mode Control.

sfr8_t TL0

Register 0x8A: Timer 0 reload L.

sfr16_t T0

Register 0x8A: Timer 0 reload.

sfr8_t TL1

Register 0x8B: Timer 1 reload L.

sfr16_t T1

Register 0x8B: Timer 1 reload.

sfr8_t TH0

Register 0x8C: Timer 0 reload H.

sfr8_t TH1

Register 0x8D: Timer 1 reload H.

sfr8_t CKCON

Register 0x8E: Clock Control.

sfr8_t IOB

Register 0x90: Port B.

sbit_t PB0

Register 0x90 bit 0: Port B bit PB0.

sbit_t PB1

Register 0x90 bit 1: Port B bit PB1.

sbit_t PB2

Register 0x90 bit 2: Port B bit PB2.

sbit_t PB3

Register 0x90 bit 3: Port B bit PB3.

sbit_t PB4

Register 0x90 bit 4: Port B bit PB4.

sbit_t PB5

Register 0x90 bit 5: Port B bit PB5.

sbit_t PB6

Register 0x90 bit 6: Port B bit PB6.

sbit_t PB7

Register 0x90 bit 7: Port B bit PB7.

sfr8_t EXIF

Register 0x91: External Interrupt Flag(s)

sfr8_t MPAGE

Register 0x92: Upper Addr Byte of MOVX using @R0 / @R1.

sfr8_t SCON0

Register 0x98: Serial Port 0 Control.

sbit_t RI_0

Register 0x98 bit 0: Serial Port 0 Control bit RI_0.

sbit_t TI_0

Register 0x98 bit 1: Serial Port 0 Control bit TI_0.

sbit_t RB8_0

Register 0x98 bit 2: Serial Port 0 Control bit RB8_0.

sbit_t TB8_0

Register 0x98 bit 3: Serial Port 0 Control bit TB8_0.

sbit_t REN_0

Register 0x98 bit 4: Serial Port 0 Control bit REN_0.

sbit_t SM2_0

Register 0x98 bit 5: Serial Port 0 Control bit SM2_0.

sbit_t SM1_0

Register 0x98 bit 6: Serial Port 0 Control bit SM1_0.

sbit_t SM0_0

Register 0x98 bit 7: Serial Port 0 Control bit SM0_0.

sfr8_t SBUF0

Register 0x99: Serial Port 0 Data Buffer.

sfr8_t AUTOPTRH1

Register 0x9A: Autopointer 1 Address H.

sfr8_t AUTOPTRL1

Register 0x9B: Autopointer 1 Address L.

sfr16_t AUTOPTR1

Register 0x9B: Autopointer 1 Address.

sfr8_t AUTOPTRH2

Register 0x9D: Autopointer 2 Address H.

sfr8_t AUTOPTRL2

Register 0x9E: Autopointer 2 Address L.

sfr16_t AUTOPTR2

Register 0x9E: Autopointer 2 Address.

sfr8_t IOC

Register 0xA0: Port C.

sbit_t PC0

Register 0xA0 bit 0: Port C bit PC0.

sbit_t PC1

Register 0xA0 bit 1: Port C bit PC1.

sbit_t PC2

Register 0xA0 bit 2: Port C bit PC2.

sbit_t PC3

Register 0xA0 bit 3: Port C bit PC3.

sbit_t PC4

Register 0xA0 bit 4: Port C bit PC4.

sbit_t PC5

Register 0xA0 bit 5: Port C bit PC5.

sbit_t PC6

Register 0xA0 bit 6: Port C bit PC6.

sbit_t PC7

Register 0xA0 bit 7: Port C bit PC7.

sfr8_t INT2CLR

Register 0xA1: Interrupt 2 clear.

sfr8_t INT4CLR

Register 0xA2: Interrupt 4 clear.

sfr8_t IE

Register 0xA8: Interrupt Enable.

sbit_t EX0

Register 0xA8 bit 0: Interrupt Enable bit EX0.

sbit_t ET0

Register 0xA8 bit 1: Interrupt Enable bit ET0.

sbit_t EX1

Register 0xA8 bit 2: Interrupt Enable bit EX1.

sbit_t ET1

Register 0xA8 bit 3: Interrupt Enable bit ET1.

sbit_t ES0

Register 0xA8 bit 4: Interrupt Enable bit ES0.

sbit_t ET2

Register 0xA8 bit 5: Interrupt Enable bit ET2.

sbit_t ES1

Register 0xA8 bit 6: Interrupt Enable bit ES1.

sbit_t EA

Register 0xA8 bit 7: Interrupt Enable bit EA.

sfr8_t EP2468STAT

Register 0xAA: Endpoint 2,4,6,8 status flags.

sfr8_t EP24FIFOFLGS

Register 0xAB: Endpoint 2,4 slave FIFO status flags.

sfr8_t EP68FIFOFLGS

Register 0xAC: Endpoint 6,8 slave FIFO status flags.

sfr8_t AUTOPTRSETUP

Register 0xAF: Autopointer 1&2 setup.

sfr8_t IOD

Register 0xB0: Port D.

sbit_t PD0

Register 0xB0 bit 0: Port D bit PD0.

sbit_t PD1

Register 0xB0 bit 1: Port D bit PD1.

sbit_t PD2

Register 0xB0 bit 2: Port D bit PD2.

sbit_t PD3

Register 0xB0 bit 3: Port D bit PD3.

sbit_t PD4

Register 0xB0 bit 4: Port D bit PD4.

sbit_t PD5

Register 0xB0 bit 5: Port D bit PD5.

sbit_t PD6

Register 0xB0 bit 6: Port D bit PD6.

sbit_t PD7

Register 0xB0 bit 7: Port D bit PD7.

sfr8_t IOE

Register 0xB1: Port E.

sfr8_t OEA

Register 0xB2: Port A Output Enable.

sfr8_t OEB

Register 0xB3: Port B Output Enable.

sfr8_t OEC

Register 0xB4: Port C Output Enable.

sfr8_t OED

Register 0xB5: Port D Output Enable.

sfr8_t OEE

Register 0xB6: Port E Output Enable.

sfr8_t IP

Register 0xB8: Interrupt Priority.

sbit_t PX0

Register 0xB8 bit 0: Interrupt Priority bit PX0.

sbit_t PT0

Register 0xB8 bit 1: Interrupt Priority bit PT0.

sbit_t PX1

Register 0xB8 bit 2: Interrupt Priority bit PX1.

sbit_t PT1

Register 0xB8 bit 3: Interrupt Priority bit PT1.

sbit_t PS0

Register 0xB8 bit 4: Interrupt Priority bit PS0.

sbit_t PT2

Register 0xB8 bit 5: Interrupt Priority bit PT2.

sbit_t PS1

Register 0xB8 bit 6: Interrupt Priority bit PS1.

sfr8_t EP01STAT

Register 0xBA: Endpoint 0&1 Status.

sfr8_t GPIFTRIG

Register 0xBB: Endpoint 2,4,6,8 GPIF slave FIFO Trigger.

sfr8_t GPIFSGLDATH

Register 0xBD: GPIF Data H (16-bit mode only)

sfr8_t GPIFSGLDATLX

Register 0xBE: GPIF Data L w/ Trigger.

sfr8_t GPIFSGLDATL

Register 0xBF: GPIF Data L w/ No Trigger D7.

sfr16_t GPIFSGLDAT

Register 0xBF: GPIF Data L w/ No Trigger D7.

sfr8_t SCON1

Register 0xC0: Serial Port 1 Control.

sbit_t RI_1

Register 0xC0 bit 0: Serial Port 1 Control bit RI_1.

sbit_t TI_1

Register 0xC0 bit 1: Serial Port 1 Control bit TI_1.

sbit_t RB8_1

Register 0xC0 bit 2: Serial Port 1 Control bit RB8_1.

sbit_t TB8_1

Register 0xC0 bit 3: Serial Port 1 Control bit TB8_1.

sbit_t REN_1

Register 0xC0 bit 4: Serial Port 1 Control bit REN_1.

sbit_t SM2_1

Register 0xC0 bit 5: Serial Port 1 Control bit SM2_1.

sbit_t SM1_1

Register 0xC0 bit 6: Serial Port 1 Control bit SM1_1.

sbit_t SM0_1

Register 0xC0 bit 7: Serial Port 1 Control bit SM0_1.

sfr8_t SBUF1

Register 0xC1: Serial Port 1 Data Buffer.

sfr8_t T2CON

Register 0xC8: Timer/Counter 2 Control.

sbit_t CPRL2

Register 0xC8 bit 0: Timer/Counter 2 Control bit CPRL2.

sbit_t CT2

Register 0xC8 bit 1: Timer/Counter 2 Control bit CT2.

sbit_t TR2

Register 0xC8 bit 2: Timer/Counter 2 Control bit TR2.

sbit_t EXEN2

Register 0xC8 bit 3: Timer/Counter 2 Control bit EXEN2.

sbit_t TCLK

Register 0xC8 bit 4: Timer/Counter 2 Control bit TCLK.

sbit_t RCLK

Register 0xC8 bit 5: Timer/Counter 2 Control bit RCLK.

sbit_t EXF2

Register 0xC8 bit 6: Timer/Counter 2 Control bit EXF2.

sbit_t TF2

Register 0xC8 bit 7: Timer/Counter 2 Control bit TF2.

sfr8_t RCAP2L

Register 0xCA: Capture for Timer 2, auto-reload, up-counter.

sfr16_t RCAP2

Register 0xCA: Capture for Timer 2, auto-reload, up-counter.

sfr8_t RCAP2H

Register 0xCB: Capture for Timer 2, auto-reload, up-counter.

sfr8_t TL2

Register 0xCC: Timer 2 reload L.

sfr16_t T2

Register 0xCC: Timer 2 reload.

sfr8_t TH2

Register 0xCD: Timer 2 reload H.

sfr8_t PSW

Register 0xD0: Program Status Word.

sbit_t P

Register 0xD0 bit 0: Program Status Word bit P.

sbit_t F1

Register 0xD0 bit 1: Program Status Word bit F1.

sbit_t OV

Register 0xD0 bit 2: Program Status Word bit OV.

sbit_t RS0

Register 0xD0 bit 3: Program Status Word bit RS0.

sbit_t RS1

Register 0xD0 bit 4: Program Status Word bit RS1.

sbit_t F0

Register 0xD0 bit 5: Program Status Word bit F0.

sbit_t AC

Register 0xD0 bit 6: Program Status Word bit AC.

sbit_t CY

Register 0xD0 bit 7: Program Status Word bit CY.

sfr8_t EICON

Register 0xD8: External Interrupt Control SMOD1.

sbit_t INT6

Register 0xD8 bit 4: External Interrupt Control SMOD1 bit INT6.

sbit_t RESI

Register 0xD8 bit 5: External Interrupt Control SMOD1 bit RESI.

sbit_t ERESI

Register 0xD8 bit 6: External Interrupt Control SMOD1 bit ERESI.

sfr8_t ACC

Register 0xE0: Accumulator.

sbit_t ACC0

Register 0xE0 bit 0: Accumulator bit ACC0.

sbit_t ACC1

Register 0xE0 bit 1: Accumulator bit ACC1.

sbit_t ACC2

Register 0xE0 bit 2: Accumulator bit ACC2.

sbit_t ACC3

Register 0xE0 bit 3: Accumulator bit ACC3.

sbit_t ACC4

Register 0xE0 bit 4: Accumulator bit ACC4.

sbit_t ACC5

Register 0xE0 bit 5: Accumulator bit ACC5.

sbit_t ACC6

Register 0xE0 bit 6: Accumulator bit ACC6.

sbit_t ACC7

Register 0xE0 bit 7: Accumulator bit ACC7.

sfr8_t EIE

Register 0xE8: External Interrupt Enable(s)

sbit_t EUSB

Register 0xE8 bit 0: External Interrupt Enable(s) bit EUSB.

sbit_t EI2C

Register 0xE8 bit 1: External Interrupt Enable(s) bit EI2C.

sbit_t EX4

Register 0xE8 bit 2: External Interrupt Enable(s) bit EX4.

sbit_t EX5

Register 0xE8 bit 3: External Interrupt Enable(s) bit EX5.

sbit_t EX6

Register 0xE8 bit 4: External Interrupt Enable(s) bit EX6.

sfr8_t B

Register 0xF0: B.

sbit_t B0

Register 0xF0 bit 0: B bit B0.

sbit_t B1

Register 0xF0 bit 1: B bit B1.

sbit_t B2

Register 0xF0 bit 2: B bit B2.

sbit_t B3

Register 0xF0 bit 3: B bit B3.

sbit_t B4

Register 0xF0 bit 4: B bit B4.

sbit_t B5

Register 0xF0 bit 5: B bit B5.

sbit_t B6

Register 0xF0 bit 6: B bit B6.

sbit_t B7

Register 0xF0 bit 7: B bit B7.

sfr8_t EIP

Register 0xF8: External Interrupt Priority 1 Control.

sbit_t PUSB

Register 0xF8 bit 1: External Interrupt Priority 1 Control bit PUSB.

sbit_t PI2C

Register 0xF8 bit 2: External Interrupt Priority 1 Control bit PI2C.

sbit_t PX4

Register 0xF8 bit 3: External Interrupt Priority 1 Control bit PX4.

sbit_t PX5

Register 0xF8 bit 4: External Interrupt Priority 1 Control bit PX5.

sbit_t PX6

Register 0xF8 bit 5: External Interrupt Priority 1 Control bit PX6.

ior8_t WAVEDATA[128]

Register 0xE400: GPIF Waveform Descriptor 0, 1, 2, 3 data.

ior8_t GPCR2

Register 0xE50D: General Purpose Configuration Register 2.

ior8_t CPUCS

Register 0xE600: CPU Control & Status.

ior8_t IFCONFIG

Register 0xE601: Interface Configuration (Ports, GPIF, slave FIFOs)

ior8_t PINFLAGSAB

Register 0xE602: Slave FIFO FLAGA and FLAGB Pin Configuration.

ior8_t PINFLAGSCD

Register 0xE603: Slave FIFO FLAGC and FLAGD Pin Configuration.

ior8_t FIFORESET

Register 0xE604: Restore FIFOS to default state.

ior8_t BREAKPT

Register 0xE605: Breakpoint Control.

ior8_t BPADDRH

Register 0xE606: Breakpoint Address H.

ior8_t BPADDRL

Register 0xE607: Breakpoint Address L.

ior8_t UART230

Register 0xE608: 230 Kbaud internally generated ref. clock.

ior8_t FIFOPINPOLAR

Register 0xE609: Slave FIFO Interface pins polarity.

ior8_t REVID

Register 0xE60A: Chip Revision.

ior8_t REVCTL

Register 0xE60B: Chip Revision Control.

ior8_t GPIFHOLDAMOUNT

Register 0xE60C: MSTB Hold Time (for UDMA)

ior8_t EP1OUTCFG

Register 0xE610: Endpoint 1-OUT Configuration.

ior8_t EP1INCFG

Register 0xE611: Endpoint 1-IN Configuration.

ior8_t EP2CFG

Register 0xE612: Endpoint 2 Configuration.

ior8_t EP4CFG

Register 0xE613: Endpoint 4 Configuration.

ior8_t EP6CFG

Register 0xE614: Endpoint 6 Configuration.

ior8_t EP8CFG

Register 0xE615: Endpoint 8 Configuration.

ior8_t EP2FIFOCFG

Register 0xE618: Endpoint 2 / slave FIFO configuration.

ior8_t EP4FIFOCFG

Register 0xE619: Endpoint 4 / slave FIFO configuration.

ior8_t EP6FIFOCFG

Register 0xE61A: Endpoint 6 / slave FIFO configuration.

ior8_t EP8FIFOCFG

Register 0xE61B: Endpoint 8 / slave FIFO configuration.

ior8_t EP2AUTOINLENH

Register 0xE620: Endpoint 2 AUTOIN Packet Length H.

ior8_t EP2AUTOINLENL

Register 0xE621: Endpoint 2 AUTOIN Packet Length L.

ior8_t EP4AUTOINLENH

Register 0xE622: Endpoint 4 AUTOIN Packet Length H.

ior8_t EP4AUTOINLENL

Register 0xE623: Endpoint 4 AUTOIN Packet Length L.

ior8_t EP6AUTOINLENH

Register 0xE624: Endpoint 6 AUTOIN Packet Length H.

ior8_t EP6AUTOINLENL

Register 0xE625: Endpoint 6 AUTOIN Packet Length L.

ior8_t EP8AUTOINLENH

Register 0xE626: Endpoint 8 AUTOIN Packet Length H.

ior8_t EP8AUTOINLENL

Register 0xE627: Endpoint 8 AUTOIN Packet Length L.

ior8_t ECCCFG

Register 0xE628: ECC Configuration.

ior8_t ECCRESET

Register 0xE629: ECC Reset.

ior8_t ECC1B0

Register 0xE62A: ECC1 Byte 0 Address.

ior8_t ECC1B1

Register 0xE62B: ECC1 Byte 1 Address.

ior8_t ECC1B2

Register 0xE62C: ECC1 Byte 2 Address.

ior8_t ECC2B0

Register 0xE62D: ECC2 Byte 0 Address.

ior8_t ECC2B1

Register 0xE62E: ECC2 Byte 1 Address.

ior8_t ECC2B2

Register 0xE62F: ECC2 Byte 2 Address.

ior8_t EP2FIFOPFH

Register 0xE630: Endpoint 2 / slave FIFO Programmable Flag H.

ior8_t EP2FIFOPFL

Register 0xE631: Endpoint 2 / slave FIFO Programmable Flag L.

ior8_t EP4FIFOPFH

Register 0xE632: Endpoint 4 / slave FIFO Programmable Flag H.

ior8_t EP4FIFOPFL

Register 0xE633: Endpoint 4 / slave FIFO Programmable Flag L.

ior8_t EP6FIFOPFH

Register 0xE634: Endpoint 6 / slave FIFO Programmable Flag H.

ior8_t EP6FIFOPFL

Register 0xE635: Endpoint 6 / slave FIFO Programmable Flag L.

ior8_t EP8FIFOPFH

Register 0xE636: Endpoint 8 / slave FIFO Programmable Flag H.

ior8_t EP8FIFOPFL

Register 0xE637: Endpoint 8 / slave FIFO Programmable Flag L.

ior8_t EP2ISOINPKTS

Register 0xE640: EP2 (if ISO) IN Packets per frame (1-3)

ior8_t EP4ISOINPKTS

Register 0xE641: EP4 (if ISO) IN Packets per frame (1-3)

ior8_t EP6ISOINPKTS

Register 0xE642: EP6 (if ISO) IN Packets per frame (1-3)

ior8_t EP8ISOINPKTS

Register 0xE643: EP8 (if ISO) IN Packets per frame (1-3)

ior8_t INPKTEND

Register 0xE648: Force IN Packet End.

ior8_t OUTPKTEND

Register 0xE649: Force OUT Packet End.

ior8_t EP2FIFOIE

Register 0xE650: Endpoint 2 slave FIFO Flag Interrupt Enable.

ior8_t EP2FIFOIRQ

Register 0xE651: Endpoint 2 slave FIFO Flag Interrupt Request.

ior8_t EP4FIFOIE

Register 0xE652: Endpoint 4 slave FIFO Flag Interrupt Enable.

ior8_t EP4FIFOIRQ

Register 0xE653: Endpoint 4 slave FIFO Flag Interrupt Request.

ior8_t EP6FIFOIE

Register 0xE654: Endpoint 6 slave FIFO Flag Interrupt Enable.

ior8_t EP6FIFOIRQ

Register 0xE655: Endpoint 6 slave FIFO Flag Interrupt Request.

ior8_t EP8FIFOIE

Register 0xE656: Endpoint 8 slave FIFO Flag Interrupt Enable.

ior8_t EP8FIFOIRQ

Register 0xE657: Endpoint 8 slave FIFO Flag Interrupt Request.

ior8_t IBNIE

Register 0xE658: IN-BULK-NAK Interrupt Enable.

ior8_t IBNIRQ

Register 0xE659: IN-BULK-NAK Interrupt Request.

ior8_t NAKIE

Register 0xE65A: Endpoint Ping-NAK / IBN Interrupt Enable.

ior8_t NAKIRQ

Register 0xE65B: Endpoint Ping-NAK / IBN Interrupt Request.

ior8_t USBIE

Register 0xE65C: USB Interrupt Enables.

ior8_t USBIRQ

Register 0xE65D: USB Interrupt Requests.

ior8_t EPIE

Register 0xE65E: Endpoint Interrupt Enables.

ior8_t EPIRQ

Register 0xE65F: Endpoint Interrupt Requests.

ior8_t GPIFIE

Register 0xE660: GPIF Interrupt Enable.

ior8_t GPIFIRQ

Register 0xE661: GPIF Interrupt Request.

ior8_t USBERRIE

Register 0xE662: USB Error Interrupt Enables.

ior8_t USBERRIRQ

Register 0xE663: USB Error Interrupt Requests.

ior8_t ERRCNTLIM

Register 0xE664: USB Error counter and limit.

ior8_t CLRERRCNT

Register 0xE665: Clear Error Counter EC3:0.

ior8_t INT2IVEC

Register 0xE666: Interrupt 2 (USB) Autovector.

ior8_t INT4IVEC

Register 0xE667: Interrupt 4 (slave FIFO & 1 GPIF) Autovector.

ior8_t INTSETUP

Register 0xE668: Interrupt 2&4 setup.

ior8_t PORTACFG

Register 0xE670: I/O PORTA Alternate Configuration.

ior8_t PORTCCFG

Register 0xE671: I/O PORTC Alternate Configuration.

ior8_t PORTECFG

Register 0xE672: I/O PORTE Alternate Configuration.

ior8_t I2CS

Register 0xE678: I2C Bus Control & Status.

ior8_t I2DAT

Register 0xE679: I2C Bus Data.

ior8_t I2CTL

Register 0xE67A: I2C Bus Control.

ior8_t XAUTODAT1

Register 0xE67B: Autoptr1 MOVX access, when APTREN=1.

ior8_t XAUTODAT2

Register 0xE67C: Autoptr2 MOVX access, when APTREN=1.

ior8_t UDMACRCH

Register 0xE67D: UDMA CRC MSB.

ior8_t UDMACRCL

Register 0xE67E: UDMA CRC LSB.

ior8_t UDMACRCQUALIFIER

Register 0xE67F: UDMA CRC Qualifier.

ior8_t USBCS

Register 0xE680: USB Control & Status.

ior8_t SUSPEND

Register 0xE681: Put chip into suspend.

ior8_t WAKEUPCS

Register 0xE682: Wakeup Control & Status.

ior8_t TOGCTL

Register 0xE683: Toggle Control.

ior8_t USBFRAMEH

Register 0xE684: USB Frame count H.

ior8_t USBFRAMEL

Register 0xE685: USB Frame count L.

ior8_t MICROFRAME

Register 0xE686: Microframe count, 0-7.

ior8_t FNADDR

Register 0xE687: USB Function address.

ior8_t EP0BCH

Register 0xE68A: Endpoint 0 Byte Count H.

ior8_t EP0BCL

Register 0xE68B: Endpoint 0 Byte Count L.

ior8_t EP1OUTBC

Register 0xE68D: Endpoint 1 OUT Byte Count.

ior8_t EP1INBC

Register 0xE68F: Endpoint 1 IN Byte Count.

ior8_t EP2BCH

Register 0xE690: Endpoint 2 Byte Count H.

ior8_t EP2BCL

Register 0xE691: Endpoint 2 Byte Count L.

ior8_t EP4BCH

Register 0xE694: Endpoint 4 Byte Count H.

ior8_t EP4BCL

Register 0xE695: Endpoint 4 Byte Count L.

ior8_t EP6BCH

Register 0xE698: Endpoint 6 Byte Count H.

ior8_t EP6BCL

Register 0xE699: Endpoint 6 Byte Count L.

ior8_t EP8BCH

Register 0xE69C: Endpoint 8 Byte Count H.

ior8_t EP8BCL

Register 0xE69D: Endpoint 8 Byte Count L.

ior8_t EP0CS

Register 0xE6A0: Endpoint 0 Control and Status.

ior8_t EP1OUTCS

Register 0xE6A1: Endpoint 1 OUT Control and Status.

ior8_t EP1INCS

Register 0xE6A2: Endpoint 1 IN Control and Status.

ior8_t EP2CS

Register 0xE6A3: Endpoint 2 Control and Status.

ior8_t EP4CS

Register 0xE6A4: Endpoint 4 Control and Status.

ior8_t EP6CS

Register 0xE6A5: Endpoint 6 Control and Status.

ior8_t EP8CS

Register 0xE6A6: Endpoint 8 Control and Status.

ior8_t EP2FIFOFLGS

Register 0xE6A7: Endpoint 2 slave FIFO Flags.

ior8_t EP4FIFOFLGS

Register 0xE6A8: Endpoint 4 slave FIFO Flags.

ior8_t EP6FIFOFLGS

Register 0xE6A9: Endpoint 6 slave FIFO Flags.

ior8_t EP8FIFOFLGS

Register 0xE6AA: Endpoint 8 slave FIFO Flags.

ior8_t EP2FIFOBCH

Register 0xE6AB: Endpoint 2 slave FIFO total byte count H.

ior8_t EP2FIFOBCL

Register 0xE6AC: Endpoint 2 slave FIFO total byte count L.

ior8_t EP4FIFOBCH

Register 0xE6AD: Endpoint 4 slave FIFO total byte count H.

ior8_t EP4FIFOBCL

Register 0xE6AE: Endpoint 4 slave FIFO total byte count L.

ior8_t EP6FIFOBCH

Register 0xE6AF: Endpoint 6 slave FIFO total byte count H.

ior8_t EP6FIFOBCL

Register 0xE6B0: Endpoint 6 slave FIFO total byte count L.

ior8_t EP8FIFOBCH

Register 0xE6B1: Endpoint 8 slave FIFO total byte count H.

ior8_t EP8FIFOBCL

Register 0xE6B2: Endpoint 8 slave FIFO total byte count L.

ior8_t SUDPTRH

Register 0xE6B3: Setup Data Pointer high address byte.

ior8_t SUDPTRL

Register 0xE6B4: Setup Data Pointer low address byte.

ior8_t SUDPTRCTL

Register 0xE6B5: Setup Data Pointer Auto Mode.

ior8_t SETUPDAT[8]

Register 0xE6B8: 8 bytes of setup data.

ior8_t GPIFWFSELECT

Register 0xE6C0: Waveform Selector.

ior8_t GPIFIDLECS

Register 0xE6C1: GPIF Done, GPIF IDLE drive mode.

ior8_t GPIFIDLECTL

Register 0xE6C2: Inactive Bus, CTL states.

ior8_t GPIFCTLCFG

Register 0xE6C3: CTL Drive Type.

ior8_t GPIFADRH

Register 0xE6C4: GPIF Address H.

ior8_t GPIFADRL

Register 0xE6C5: GPIF Address L.

ior8_t FLOWSTATE

Register 0xE6C6: Flowstate Enable and Selector.

ior8_t FLOWLOGIC

Register 0xE6C7: Flowstate Logic.

ior8_t FLOWEQ0CTL

Register 0xE6C8: CTL-Pin States in Flowstate (when Logic = 0)

ior8_t FLOWEQ1CTL

Register 0xE6C9: CTL-Pin States in Flowstate (when Logic = 1)

ior8_t FLOWHOLDOFF

Register 0xE6CA: Holdoff Configuration.

ior8_t FLOWSTB

Register 0xE6CB: Flowstate Strobe Configuration.

ior8_t FLOWSTBEDGE

Register 0xE6CC: Flowstate Rising/Falling Edge Configuration.

ior8_t FLOWSTBPERIOD

Register 0xE6CD: Master-Strobe Half-Period.

ior8_t GPIFTCB3

Register 0xE6CE: GPIF Transaction Count Byte 3.

ior8_t GPIFTCB2

Register 0xE6CF: GPIF Transaction Count Byte 2.

ior8_t GPIFTCB1

Register 0xE6D0: GPIF Transaction Count Byte 1.

ior8_t GPIFTCB0

Register 0xE6D1: GPIF Transaction Count Byte 0.

ior8_t EP2GPIFFLGSEL

Register 0xE6D2: Endpoint 2 GPIF Flag Select.

ior8_t EP2GPIFPFSTOP

Register 0xE6D3: Endpoint 2 GPIF Stop Transaction on Programmable flag.

ior8_t EP2GPIFTRIG

Register 0xE6D4: Endpoint 2 GPIF Trigger.

ior8_t EP4GPIFFLGSEL

Register 0xE6DA: Endpoint 4 GPIF Flag Select.

ior8_t EP4GPIFPFSTOP

Register 0xE6DB: Endpoint 4 GPIF Stop Transaction on Programmable Flag.

ior8_t EP4GPIFTRIG

Register 0xE6DC: Endpoint 4 GPIF Trigger.

ior8_t EP6GPIFFLGSEL

Register 0xE6E2: Endpoint 6 GPIF Flag Select.

ior8_t EP6GPIFPFSTOP

Register 0xE6E3: Endpoint 6 GPIF Stop Transaction on Programmable flag.

ior8_t EP6GPIFTRIG

Register 0xE6E4: Endpoint 6 GPIF Trigger.

ior8_t EP8GPIFFLGSEL

Register 0xE6EA: Endpoint 8 GPIF Flag Select.

ior8_t EP8GPIFPFSTOP

Register 0xE6EB: Endpoint 8 GPIF Stop Transaction on Programmable flag.

ior8_t EP8GPIFTRIG

Register 0xE6EC: Endpoint 8 GPIF Trigger.

ior8_t XGPIFSGLDATH

Register 0xE6F0: GPIF Data H (16-bit mode only)

ior8_t XGPIFSGLDATLX

Register 0xE6F1: Read/Write GPIF Data L & trigger transaction.

ior8_t XGPIFSGLDATLNOX

Register 0xE6F2: Read GPIF Data L, no transaction trigger.

ior8_t GPIFREADYCFG

Register 0xE6F3: Internal RDY, Sync/Async, RDY pin states.

ior8_t GPIFREADYSTAT

Register 0xE6F4: GPIF Ready Status.

ior8_t GPIFABORT

Register 0xE6F5: Abort GPIF Waveforms.

ior8_t EP0BUF[64]

Register 0xE740: EP0-IN/-OUT buffer.

ior8_t EP1OUTBUF[64]

Register 0xE780: EP1-OUT buffer.

ior8_t EP1INBUF[64]

Register 0xE7C0: EP1-IN buffer.

ior8_t EP2FIFOBUF[1024]

Register 0xF000: 512/1024 byte EP 2 / slave FIFO buffer (IN or OUT)

ior8_t EP4FIFOBUF[512]

Register 0xF400: 512 byte EP 4 / slave FIFO buffer (IN or OUT)

ior8_t EP6FIFOBUF[1024]

Register 0xF800: 512/1024 byte EP 6 / slave FIFO buffer (IN or OUT)

ior8_t EP8FIFOBUF[512]

Register 0xFC00: 512 byte EP 8 / slave FIFO buffer (IN or OUT)

fx2ints.h

The fx2ints.h header contains interrupt handler declarations for the Cypress FX2 series.

Interrupt handler resolution

By including the fx2ints.h header, which declares every interrupt handler, your firmware requests the linker to locate a handler for every interrupt. If you provide a handler explicitly, this handler will be used; if you do not, the linker will go through the list of libraries, looking for the first one that includes a handler. The library fx2isrs.lib provides a default empty handler for every interrupt (as well as autovectoring jump tables) and should be linked last into every firmware.

Core interrupt handlers

To define a core interrupt handler, override the corresponding isr_ function and provide the interrupt number in the __interrupt attribute, e.g. for the TF0 interrupt:

void isr_TF0() __interrupt(_INT_TF0) {
  // TIMER0 has overflowed
}

Interrupts with flags in the EXIF register need to be reset manually:

void isr_I2C() __interrupt(_INT_I2C) {
  // I2C is done or errored
  CLEAR_I2C_IRQ();
}

Autovectored interrupt handlers

To define an autovectored interrupt handler, override the corresponding isr_ function and provide the __interrupt attribute without a number, e.g. for the SOF interrupt:

void isr_SOF() __interrupt {
  // Start of Frame packet has been received
  CLEAR_USB_IRQ();
  USBIRQ = _SOF;
}

Note

The order of clearing of the IRQ flags is important.

Reference

8051 core interrupts

CLEAR_I2C_IRQ()

Clears the I2C interrupt request.

CLEAR_INT4_IRQ()

Clears the INT4# interrupt request.

CLEAR_INT5_IRQ()

Clears the INT5# interrupt request.

void isr_IE0 () __interrupt(_INT_IE0)
void isr_TF0 () __interrupt(_INT_TF0)
void isr_IE1 () __interrupt(_INT_IE1)
void isr_TF1 () __interrupt(_INT_TF1)
void isr_RI_TI_0 () __interrupt(_INT_RI_TI_0)
void isr_TF2 () __interrupt(_INT_TF2)
void isr_RESUME () __interrupt(_INT_RESUME)
void isr_RI_TI_1 () __interrupt(_INT_RI_TI_1)
void isr_USB () __interrupt(_INT_USB)
void isr_I2C () __interrupt(_INT_I2C)
void isr_GPIF_IE4 () __interrupt(_INT_GPIF_IE4)
void isr_IE5 () __interrupt(_INT_IE5)
void isr_IE6 () __interrupt(_INT_IE6)

Autovectored USB interrupts

ENABLE_USB_AUTOVEC()

Enables the autovectored USB interrupt and the corresponding jump table.

CLEAR_USB_IRQ()

Clears the main USB interrupt request. This must be done before clearing the individual USB interrupt request latch.

void isr_SUDAV () __interrupt
void isr_SOF () __interrupt
void isr_SUTOK () __interrupt
void isr_SUSPEND () __interrupt
void isr_USBRESET () __interrupt
void isr_HISPEED () __interrupt
void isr_EP0ACK () __interrupt
void isr_EP0IN () __interrupt
void isr_EP0OUT () __interrupt
void isr_EP1IN () __interrupt
void isr_EP1OUT () __interrupt
void isr_EP2 () __interrupt
void isr_EP4 () __interrupt
void isr_EP6 () __interrupt
void isr_EP8 () __interrupt
void isr_IBN () __interrupt
void isr_EP0PING () __interrupt
void isr_EP1PING () __interrupt
void isr_EP2PING () __interrupt
void isr_EP4PING () __interrupt
void isr_EP6PING () __interrupt
void isr_EP8PING () __interrupt
void isr_ERRLIMIT () __interrupt
void isr_EP2ISOERR () __interrupt
void isr_EP4ISOERR () __interrupt
void isr_EP6ISOERR () __interrupt
void isr_EP8ISOERR () __interrupt

Autovectored GPIF interrupts

ENABLE_GPIF_AUTOVEC()

Enables the autovectored GPIF interrupt and the corresponding jump table. Note that this makes it impossible to provide an INT4 handler.

CLEAR_GPIF_IRQ()

Clears the main GPIF interrupt request. This must be done before clearing the individual GPIF interrupt request latch.

void isr_EP2PF () __interrupt
void isr_EP4PF () __interrupt
void isr_EP6PF () __interrupt
void isr_EP8PF () __interrupt
void isr_EP2EF () __interrupt
void isr_EP4EF () __interrupt
void isr_EP6EF () __interrupt
void isr_EP8EF () __interrupt
void isr_EP2FF () __interrupt
void isr_EP4FF () __interrupt
void isr_EP6FF () __interrupt
void isr_EP8FF () __interrupt
void isr_GPIFDONE () __interrupt
void isr_GPIFWF () __interrupt

Enums

enum fx2_core_interrupt

Values:

enumerator _INT_IE0
enumerator _INT_TF0
enumerator _INT_IE1
enumerator _INT_TF1
enumerator _INT_RI_TI_0
enumerator _INT_TF2
enumerator _INT_RESUME
enumerator _INT_RI_TI_1
enumerator _INT_USB
enumerator _INT_I2C
enumerator _INT_GPIF_IE4
enumerator _INT_IE5
enumerator _INT_IE6

fx2lib.h

The fx2lib.h header contains library routines that use the Cypress FX2 series architectural extensions. When using this header, the fx2 library must be linked in.

Reference

Defines

ARRAYSIZE(x)

A macro that returns the statically known size of the array.

Functions

void *xmemcpy(void *dest, void *src, uint16_t length)

A fast memory copy routine that uses the FX2-specific architecture extensions. This routine clobbers the value of all autopointer registers. Both pointers should be in the __xdata address space. Returns destination, like memcpy.

void *xmemclr(void *dest, uint16_t length)

A fast memory clear routine that uses the FX2-specific architecture extensions. This routine clobbers the value of all autopointer registers. The pointer should be in the __xdata. Returns destination, like memclr.

uint16_t bswap16(uint16_t value)

An endianness swap routine for 16-bit integers.

uint32_t bswap32(uint32_t value)

An endianness swap routine for 32-bit integers.

Variables

uint8_t scratch[512]

0.5KB of general purpose scratch RAM.

fx2delay.h

The fx2delay.h header contains delay routines for the Cypress FX2 series. When using this header, the fx2 library must be linked in.

Reference

Defines

SYNCDELAYLEN

Synchronization delay length.

This value defaults to 3, and should be overridden using a compiler flag -DSYNCDELAYLEN=n if running with non-default IFCLK or CLKOUT clock frequency. Delay length can be calculated using the following Python code:

import math
math.ceil(1.5 * ((ifclk_period / clkout_period) + 1))

See TRM 15.15 for details.

SYNCDELAY

Synchronization delay for access to certain registers.

See TRM 15.15 for details.

This macro produces very compact code, using only 2 or 3 bytes per instance.

Functions

void delay_ms(uint16_t count_ms)

Spin for the given number of milliseconds.

void delay_us_overhead(uint16_t count_us, uint8_t overh_c)

Spin for the given number of microseconds, minus overh_c processor cycles. count_us must be no greater than 21845, and overh_c must be no greater than 128.

This function is cycle-accurate at any CPU clock frequency provided that the delay is not less than the intrinsic overhead of up to 100 processor cycles (9..33 microseconds).

void delay_us(uint16_t count_us)

Equivalent to delay_us_overhead(count_us, 3) where 3 is the number of cycles of overhead when delay_us is called with a constant argument.

void delay_4c(uint16_t count_4c)

Spin for count * 4 processor cycles, or count * 16 clock cycles. Takes exactly 24 processor cycles (2..8 microseconds) if count is less than 6.

fx2debug.h

The fx2debug.h header contains templated debug serial port bitbang routines for the Cypress FX2 series implemented in assembly. This header is the complete implementation of the debug serial port and does not have a corresponding library.

Reference

Defines

DEFINE_DEBUG_FN(name, tx, baud)

This macro defines a function void name(uint8_t c) that implements a robust blocking serial transmitter for debug output. The tx parameter may point to any pin, and is defined in the format Pxn. The serial format is fixed at 8 data bits, no parity, 1 stop bit, and the baud rate is configurable, up to 230400 at 48 MHz, up to 115200 at 24 MHz, and up to 57600 at 12 MHz.

For example, invoking the macro as DEFINE_DEBUG_FN(tx_byte, PA0, 57600) defines a routine void tx_byte(uint8_t c) that assumes an UART receiver’s RX pin is connected to A0.

DEFINE_DEBUG_PUTCHAR_FN(tx, baud)

Same as DEFINE_DEBUG_FN(), but defines an int putchar(int c) routine that can be used with the printf family of functions. (The C standard requires putchar to have the specified signature).

fx2i2c.h

The fx2i2c.h header contains I2C and EEPROM routines for the Cypress FX2 series. When using this header, the fx2 library must be linked in.

Reference

Functions

bool i2c_wait(bool need_ack)

This function waits until the current I2C transfer terminates, or until i2c_cancel is set. In the latter case, i2c_cancel is cleared. Returns false in case of bus contention, or if need_ack was set and the transfer was not acknowledged, true otherwise. The BERR bit in the I2CS register should be checked if false is returned.

Note that i2c_wait is not meant to be used directly; it is documented to explain the behavior of i2c_start, i2c_write and i2c_read.

bool i2c_start(uint8_t chip)

This function generates a start condition and writes the address chip to the bus. See i2c_wait for description of return value.

bool i2c_stop()

This function generates a stop condition.

bool i2c_write(const uint8_t *buf, uint16_t len)

This function writes len bytes from buf to the I2C bus. See i2c_wait for description of return value.

bool i2c_read(uint8_t *buf, uint16_t len)

This function reads len bytes to buf from the I2C bus, responds with NAK to the last byte read, and generates a stop condition. See i2c_wait for description of return value.

Variables

bool i2c_cancel

A flag that terminates the current I2C transfer.

fx2eeprom.h

The fx2eeprom.h header contains EEPROM routines for the Cypress FX2 series. When using this header, the fx2 library must be linked in.

Reference

Functions

bool eeprom_read(uint8_t chip, uint16_t addr, uint8_t *buf, uint16_t len, bool double_byte)

This function reads len bytes at memory address addr from EEPROM chip with bus address chip to buf. It writes two address bytes if double_byte is true.

Returns true if the read is successful, false otherwise.

bool eeprom_write(uint8_t chip, uint16_t addr, uint8_t *buf, uint16_t len, bool double_byte, uint8_t page_size, uint8_t timeout)

This function writes len bytes at memory address addr to EEPROM chip with bus address chip from buf. It writes two address bytes if double_byte is true.

Data is written in chunks up to 2 ** page_size bytes, with each chunk ending on an address that is a multiple of 2 ** page_size. Use the page size specified in the EEPROM datasheet for significantly higher write performance.

timeout specifies the number of polling attempts after a write; 0 means wait forever. At 100 kHz, one polling attempt is ~120 us, at 400 kHz, ~30 us, so for typical wait cycles of up to 5 ms, a timeout of 166 should be sufficient in all cases.

Returns true if the write is successful, false otherwise.

fx2spi.h

The fx2spi.h header contains templated SPI bitbang routines for the Cypress FX2 series implemented in assembly. This header is the complete implementation of the SPI interface and does not have a corresponding library.

Reference

Defines

DEFINE_SPI_WR_FN(name, sck, si)

This macro defines a function void name(const __xdata uint8_t *data, uint16_t len) that implements an optimized (76 clock cycles per iteration; ~5 MHz at 48 MHz CLKOUT) SPI Mode 3 write routine. The sck and si parameters may point to any pins, and are defined in the format Pxn.

For example, invoking the macro as DEFINE_SPI_WR_FN(flash_write, PA1, PB6) defines a routine void flash_write() that assumes an SPI device’s SCK pin is connected to A1 and MOSI pin is connected to B6.

DEFINE_SPI_RD_FN(name, sck, so)

This macro defines a function void name(__xdata uint8_t *data, uint16_t len) that implements an optimized (76 clock cycles per iteration; ~5 MHz at 48 MHz CLKOUT) SPI Mode 3 read routine. The sck and so parameters may point to any pins, and are defined in the format _Pxn (note the underscore).

For example, invoking the macro as DEFINE_SPI_RD_FN(flash_read, PA1, PB5) defines a routine void flash_read() that assumes an SPI device’s SCK pin is connected to A1 and MISO pin is connected to B5.

fx2spiflash.h

The fx2spiflash.h header contains templated 25C-compatible SPI flash routines for the Cypress FX2 series. This header is the complete implementation of the SPI flash interface and does not have a corresponding library.

Reference

Defines

SPIFLASH_WIP

Write-in-Progress status register bit.

SPIFLASH_WEL

Write Enable Latch status register bit.

DEFINE_SPIFLASH_FNS(name, cs, sck, si, so)

This macro defines a number of functions that implement common operations on 25C-compatible SPI flashes. They are optimized and run at ~5 MHz SCK frequency at 48 MHz CLKOUT. The cs, sck, so, and si parameters may point to any pins, and are defined in the format Pxn.

The defined routines are:

  • void name_init(), to set outputs to their idle state. (Note that output enables must be configured by the user before calling name_init.)

  • void name_rdp(), to leave deep power-down mode (command AB).

  • void name_dp(), to enter deep power-down mode (command B9).

  • void name_read(uint32_t addr, __xdata uint8_t *data, uint16_t length), to read data at the given address, with wraparound at array boundary (command 03).

  • void name_wren(), to latch the write enable bit (command 06).

  • uint8_t name_rdsr(), to read the status register (command 05).

  • void name_ce(), to erase the entire chip (command 60).

  • void name_se(uint32_t addr), to erase a sector at the given address (command 20).

  • void name_pp(uint32_t addr, const __xdata uint8_t *data, uint16_t length), to program up to a whole page at the given address, with wraparound at page boundary (command 02).

For example, invoking the macro as DEFINE_SPIFLASH_FNS(flash, PA0, PB0, PB1, PB2) defines the routines void flash_init(), void flash_read(), etc that assume an SPI flash’s CS# pin is connected to A0, SCK pin is connected to B0, MISO pin is connected to B1, and MOSI pin is connected to B2.

fx2usb.h

The fx2usb.h header contains USB support code for the Cypress FX2 series. When using this header, the fx2 and fx2usb libraries must be linked in.

Callback resolution

This header defines a number of callback functions, which requests the linker to locate a implementation for every of them. If you provide a callback explicitly, this callback will be used; if you do not, the linker will use the default one from the fx2usb library. Not all callbacks have default implementations.

Reference

Defines

SETUP_EP0_IN_DESC(addr)

Configure EP0 for an IN transfer from RAM of an USB descriptor of the following types:

  • Device

  • Device Qualifier

  • Configuration

  • Other Speed Configuration

  • String

Note that addr must be word-aligned.

SETUP_EP0_IN_DATA(addr, length)

Configure EP0 for an IN transfer from RAM of data of arbitrary length. Note that addr must be word-aligned.

SETUP_EP0_BUF(length)

Configure EP0 for an IN or OUT transfer from or to EP0BUF. For an OUT transfer, specify length as 0.

ACK_EP0()

Acknowledge an EP0 SETUP or OUT transfer.

STALL_EP0()

Indicate an error in response to a EP0 transfer.

Typedefs

typedef const char *const usb_ascii_string_c
typedef const struct usb_configuration usb_configuration_c
typedef const struct usb_configuration *const usb_configuration_set_c
typedef const struct usb_descriptor_set usb_descriptor_set_c

Functions

void usb_init(bool disconnect)

Initialize the firmware USB stack. This performs the following:

  • enables USB interrupts handled by the support code,

  • takes EP0 under software control,

  • disconnects (if requested) and connects (if necessary).

uint8_t *EPnCS_for_n(uint8_t n)

Return a EPnCS register for given USB endpoint index, or 0 if no such endpoint exists.

void usb_serve_descriptor(usb_descriptor_set_c *set, enum usb_descriptor type, uint8_t index)

Helper function for returning descriptors from a set of C structure definitions. This function relaxes all hardware restrictions on descriptor layout by copying the requested descriptor(s) into the scratch RAM. Sets up an EP0 IN transfer if a descriptor is found, stalls EP0 otherwise.

void usb_reset_data_toggles(usb_descriptor_set_c *set, uint8_t interface, uint8_t alt_setting)

Helper function for resetting the endpoint data toggles for a subset of endpoints defined by the configuration value or interface number and alternate setting, which is necessary when processing a Set Configuration or Set Interface request. This function resets the endpoint toggles for the configuration value usb_config_value, and (if interface == 0xff && alt_setting == 0xff) all endpoints, or (otherwise) all endpoints assigned to interface with fields bInterfaceNumber == interface && bAlternateSetting == alt_setting.

void handle_usb_get_descriptor(enum usb_descriptor type, uint8_t index)

Callback for the standard Get Descriptor request. This callback has a default implementation that returns descriptors from a global const struct usb_descriptor_set usb_descriptor_set = { ... };. See usb_serve_descriptor.

bool handle_usb_set_configuration(uint8_t config_value)

Callback for the standard Set Configuration request. This callback has a default implementation that sets usb_config_value to config_value and returns true if config_value is 0 or 1, and returns false otherwise.

The default implementation resets the data toggles using usb_reset_data_toggles and the global descriptor set; see handle_usb_get_descriptor.

void handle_usb_get_configuration()

Callback for the standard Get Configuration request. This callback has a default implementation that sets up an EP0 IN transfer with value usb_config_value.

bool handle_usb_set_interface(uint8_t interface, uint8_t alt_setting)

Callback for the standard Set Interface request. This callback has a default implementation that returns true if alt_setting == 0, and returns false otherwise.

The default implementation resets the data toggles using usb_reset_data_toggles and the global descriptor set; see handle_usb_get_descriptor.

void handle_usb_get_interface(uint8_t interface)

Callback for the standard Get Interface request. This callback has a default implementation that sets up an EP0 IN transfer with alternate setting number 0.

bool handle_usb_clear_endpoint_halt(uint8_t endpoint)

Callback for the standard Clear Feature - Endpoint - Endpoint Halt request. This callback has a default implementation that acknowledges the transfer and returns true.

The data toggle and the stall bit are reset by the interrupt handler if the handler returns true.

void handle_usb_setup(struct usb_req_setup *request)

Callback for non-standard setup requests. This callback has a default implementation that stalls EP0.

Variables

bool usb_self_powered

Status variable indicating whether the device is currently self-powered. The value of this variable is returned via the standard Get Status - Device request.

bool usb_remote_wakeup

Status variable indicating whether the device is configured for remote wakeup. The value of this variable is returned via the standard Get Status - Device request.

uint8_t usb_config_value

Status variable indicating whether the device is in Address state (if the value is 0) or Configured state (the value corresponds to bConfigurationValue field of the descriptor of the selected configuration).

struct usb_configuration
#include <fx2usb.h>

An USB configuration descriptor. The USB configuration descriptor is followed by the interface, endpoint, and functional descriptors; these are laid out in the way they should be returned in response to the Get Configuration request.

Public Members

struct usb_desc_configuration desc
union usb_configuration::usb_config_item items[]
union usb_config_item
#include <fx2usb.h>

Public Members

usb_desc_generic_c *generic
usb_desc_interface_c *interface
usb_desc_endpoint_c *endpoint
struct usb_descriptor_set
#include <fx2usb.h>

A group of USB descriptors for a single device.

Public Members

usb_desc_device_c *device
usb_desc_device_qualifier_c *device_qualifier
uint8_t config_count
usb_configuration_set_c *configs
uint8_t string_count
usb_ascii_string_c *strings

fx2usbdfu.h

The fx2usbdfu.h header contains USB DFU interface support code for the Cypress FX2 series. When using this header, the fx2, fx2usb, and fx2usbdfu libraries must be linked in.

Reference

Typedefs

typedef struct usb_dfu_iface_state usb_dfu_iface_state_t

Functions

bool usb_dfu_setup(usb_dfu_iface_state_t *state, struct usb_req_setup *request)

Handle USB Device Firmware Update interface SETUP packets. This function makes the appropriate changes to the state and returns true if a SETUP packet addressed this interface, or returns false otherwise.

void usb_dfu_setup_deferred(usb_dfu_iface_state_t *state)

Handle USB Device Firmware Update interface SETUP packets that perform lengthy operations (i.e. actual firmware upload/download).

Variables

usb_dfu_iface_state_t usb_dfu_iface_state

The global DFU configuration, defined in the application code. It only makes sense for a single device to expose a single DFU interface at a time.

struct usb_dfu_iface_state
#include <fx2usbdfu.h>

State of an USB Device Firmware Upgrade interface.

Public Members

uint8_t interface

The bInterfaceNumber field corresponding to this interface in runtime mode. (In upgrade mode, only one interface must be exported, so this field is ignored.)

usb_dfu_status_t (*firmware_upload)(uint32_t offset, uint8_t *data, uint16_t *length)

Firmware upload function. This function reads the firmware block at offset of requested length into data. When end of firmware is reached, this function should report this a block size shorter than provided length by changing it.

The offset argument is maintained internally by this library and is increased after each firmware_upload call by length; it is not related to the wBlockNum field from DFU_UPLOAD request.

The firmware read out by this function must be in a format identical to that accepted by the firmware_dnload function to be DFU compliant.

This function should return USB_DFU_STATUS_OK if the firmware could be read, and one of the other enum usb_dfu_status values otherwise.

usb_dfu_status_t (*firmware_dnload)(uint32_t offset, uint8_t *data, uint16_t length)

Firmware download function. This function writes the firmware block at offset from data that is length bytes long, which may be no greater than wTransferSize field in the DFU functional descriptor. If this function receives a block lenght of zero, it must validate whether it has received the complete firmware.

The offset argument is maintained internally by this library and is increased after each firmware_dnload call by length; it is not related to the wBlockNum field from DFU_DNLOAD request.

This function should return USB_DFU_STATUS_OK if the firmware could be written (or, in case of length == 0, if the complete firmware was downloaded), and one of the other enum usb_dfu_status values otherwise.

usb_dfu_status_t (*firmware_manifest)()

Firmware manifestation function. This function could perform any application-specific actions required to finish updating firmware, such as changing the boot address.

This function should return USB_DFU_STATUS_OK if the firmware could be manifested, and one of the other enum usb_dfu_status values otherwise.

If this callback is set to NULL, the behavior is the same as if the callback was implemented as an empty function returning USB_DFU_STATUS_OK.

enum usb_dfu_state state

State of the DFU interface, as per DFU specification.

fx2usbmassstor.h

The fx2usbmassstor.h header contains USB Mass Storage Bulk-Only Transfer interface class support code for the Cypress FX2 series. When using this header, the fx2 and fx2usb libraries must be linked in.

Reference

Typedefs

typedef struct usb_mass_storage_bbb_state usb_mass_storage_bbb_state_t

Functions

bool usb_mass_storage_bbb_setup(usb_mass_storage_bbb_state_t *state, struct usb_req_setup *request)

Handle USB Mass Storage Bulk-Only Transport interface SETUP packets. This function makes the appropriate changes to the state and returns true if a SETUP packet addressed this interface, or returns false otherwise.

bool usb_mass_storage_bbb_bulk_out(usb_mass_storage_bbb_state_t *state, const uint8_t *data, uint16_t length)

Process USB Mass Storage Bulk-Only Transport interface BULK OUT packets.

This function should be called each time a BULK OUT packet is received.

It returns a result flag. If the result is true, a packet should be ended. If the result is false, both the BULK OUT and BULK IN endpoint should be stalled.

bool usb_mass_storage_bbb_bulk_in(usb_mass_storage_bbb_state_t *state, uint8_t *data, uint16_t *length)

Emit USB Mass Storage Bulk-Only Transport interface BULK IN packets.

This function should be called each time an IN BULK NAK interrupt occurs.

It returns a result flag. If the result is true, a packet should be committed if length is nonzero. If the result is false, the BULK IN endpoint should be stalled.

struct usb_mass_storage_bbb_state
#include <fx2usbmassstor.h>

State of an USB Mass Storage Bulk-Only Transport interface.

Public Members

uint8_t interface

The bInterfaceNumber field corresponding to this interface.

uint16_t max_in_size

The value of the wMaxPacketSize field of the BULK IN endpoint of this interface.

uint8_t max_lun

The maximum LUN number of this interface. Most interfaces will only use a single LUN, and so will have max_lun set to zero.

bool (*command)(uint8_t lun, uint8_t *command, uint8_t length)

The Command callback. This function is called for each CBW. It should return true if the command is recognized and well-formed, which either proceeds to the Data callbacks (if there is any data to be transferred) or returns a Passed CSW immediately; or false, in which case the data callbacks are never called and a Failed CSW is returned.

bool (*data_out)(uint8_t lun, const uint8_t *data, uint16_t length)

The Data-Out callback. This function is called with chunks of data that follow a CBW that specifies an OUT transfer. It can read exactly length bytes from the data buffer. If data is processed successfully, this function should return true, which will eventually return a Passed CSW to the host; otherwise, the rest of the transfer is skipped (this callback is not invoked again), and a Failed CSW is returned.

bool (*data_in)(uint8_t lun, uint8_t *data, uint16_t length)

The Data-In callback. This function is called each time a chunk of data is necessary following a CBW that specifies an IN transfer. It should fill exactly length bytes into the data buffer. If data is processed successfully, this function should return true, which will eventually return a Passed CSW to the host; otherwise, the rest of the transfer is skipped (this callback is not invoked again), and a Failed CSW is returned.

fx2uf2.h

The fx2uf2.h header contains USB UF2 interface support code for the Cypress FX2 series. See the Microsoft UF2 specification for details. When using this header, the fx2, fx2usb, fx2usbmassstor and fx2uf2 libraries must be linked in.

Reference

Typedefs

typedef const struct uf2_configuration uf2_configuration_c

Variables

uf2_configuration_c uf2_config

The global UF2 configuration, defined in the application code. It only makes sense for a single device to expose a single UF2 interface at a time.

struct uf2_configuration
#include <fx2uf2.h>

Configuration of USB UF2 interface.

Public Members

uint32_t total_sectors

Total number of sectors on the virtual USB Mass Storage device. The optimal number depends on the size of the firmware, but in general, 65536 sectors (32 MiB) is a reasonable size.

const char *info_uf2_txt

Contents of the INFO_UF2.TXT file on the virtual USB Mass Storage device. Should be at most one sector (512 bytes) long.

const char *index_htm

Contents of the INDEX.HTM file on the virtual USB Mass Storage device. Should be at most one sector (512 bytes) long.

uint32_t firmware_size

Size of the firmware. Currently rounded up to the nearest UF2 payload size, 256, but this should not be relied on.

bool (*firmware_read)(uint32_t address, uint8_t *data, uint16_t length)

Firmware read function. This function should accept any address and length arguments that read bytes between 0 and firmware_size (after rounding). It should return true if the firmware could be read, and false otherwise.

bool (*firmware_write)(uint32_t address, uint8_t *data, uint16_t length)

Firmware write function. This function is passed the UF2 blocks directly without further verification of address and length against firmware_size. It should return true if the firmware could be written, and false otherwise.

FAQ

Why not just use fx2lib?

I wrote all of the code in libfx2 from scratch using the USB specification and Cypress datasheets for two reasons: the fx2lib code quality is very low, and it is licensed under LGPL, which is absurd for chip support packages.