Skip to content

Instantly share code, notes, and snippets.

@tai
Created July 5, 2015 02:36
Show Gist options
  • Select an option

  • Save tai/acd59b125a007ad47767 to your computer and use it in GitHub Desktop.

Select an option

Save tai/acd59b125a007ad47767 to your computer and use it in GitHub Desktop.
Sample USB descriptor definition for USB-CDC with Cypress EZ-USB FX2/FX2LP + SDCC
;;; -*- mode: asm; coding: utf-8 -*-
;;;
;;; USB descriptor definition for virtual COM port implementation
;;; with Cypress EZ-USB FX2 (CY7C68013) and FX2LP (CY7C68013A).
;;;
;;; NOTE:
;;; - Works with sdcc, but may need recent version due to use of
;;; assembler macros.
;;;
.module DEV_DSCR
;; descriptor types
DSCR_DEVICE_TYPE=1
DSCR_CONFIG_TYPE=2
DSCR_STRING_TYPE=3
DSCR_INTERFACE_TYPE=4
DSCR_ENDPOINT_TYPE=5
DSCR_DEVQUAL_TYPE=6
;; for the repeating interfaces
DSCR_INTERFACE_LEN=9
DSCR_ENDPOINT_LEN=7
;; endpoint types
ENDPOINT_TYPE_CONTROL=0
ENDPOINT_TYPE_ISO=1
ENDPOINT_TYPE_BULK=2
ENDPOINT_TYPE_INT=3
;; ENDPOINT DIRECTION
EP_IN = 0x80
EP_OUT = 0x00
;;
EP1 = 1
EP2 = 2
EP3 = 3
EP4 = 4
EP5 = 5
EP6 = 6
EP7 = 7
EP8 = 8
;; function descriptor
CS_INTERFACE = 0x24
CS_ENDPOINT = 0x25
;; Symbols used in setupdat.c
.globl _dev_dscr, _dev_qual_dscr, _highspd_dscr, _fullspd_dscr, _dev_strings, _dev_strings_end
;; Edit makefile to place this area in code memory (SUDPTRH:L requirement)
.area DSCR_AREA (CODE)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Device Descriptor
;;;
;;; @see CDC120-20101103-track.pdf in http://www.usb.org/developers/docs/devclass_docs/CDC1.2_WMC1.1_012011.zip
;;; - 5.1.1 Device Descriptor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_dev_dscr:
.db dev_dscr_end - _dev_dscr ; descriptor size
.db DSCR_DEVICE_TYPE ; descriptor device type
.dw 0x0002 ; USB version (0x02 0x00, LSB-first)
.db 0x02 ; device class = Communication Device Class (CDC)
.db 0x00 ; subclass = unused
.db 0x00 ; protocol = unused
.db 64 ; packet size (ep0)
.dw 0xB404 ; vendor id
.dw 0x4717 ; product id
.dw 0x0001 ; version id (1.0 = 0x01 0x00, LSB-first)
.db 1 ; manufacturure string index
.db 2 ; product string index
.db 3 ; serial string index
.db 1 ; n configurations
dev_dscr_end:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Device Qualifier Descriptor
;;;
;;; A high-speed capable device that has different device information
;;; for full-speed and high-speed must have a Device Qualifier
;;; Descriptor (USB_DEVICE_QUALIFIER_DESCRIPTOR). For example, if
;;; the device is currently operating at full-speed, the Device
;;; Qualifier returns information about how it would operate at
;;; high-speed and vice-versa.
;;;
;;; @see http://www.keil.com/pack/doc/mw/usb/html/_u_s_b__device__qualifier__descriptor.html
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_dev_qual_dscr:
.db dev_qualdscr_end - _dev_qual_dscr
.db DSCR_DEVQUAL_TYPE
.dw 0x0002 ; USB version (0x02 0x00, LSB-first)
.db 0x00 ; device class = 0x00:use interface class
.db 0x00 ; device sub-class
.db 0x00 ; device sub-sub-class
.db 64 ; max packet
.db 1 ; n configs
.db 0 ; extra reserved byte
dev_qualdscr_end:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Configuration for High-Speed mode
;;;
;;; [CDC] 5.1.2 Configuration Descriptor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_highspd_dscr:
.db highspd_dscr_end-_highspd_dscr ; descriptor length
.db DSCR_CONFIG_TYPE ; descriptor type
;; NOTE: can't use .dw because byte order is different
.db (highspd_dscr_realend-_highspd_dscr) % 256 ; total length of config (LSB)
.db (highspd_dscr_realend-_highspd_dscr) / 256 ; total length of config (MSB)
.db 2 ; n interfaces
.db 1 ; config number
.db 4 ; config string index
.db 0x80 ; attriubutes (see spec for bit description)
.db 50 ; max power = $val * 2[mA]
highspd_dscr_end:
.macro ifdesc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Interface #0.0 - Communications Class
;;;
;;; @see CDC120-20101103-track.pdf
;;; - 4 Class-Specific Codes
;;; - 5.1.3 Interface Descriptor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.db DSCR_INTERFACE_LEN
.db DSCR_INTERFACE_TYPE
.db 0 ; interface index
.db 0 ; altsetting index
.db 1 ; n endpoints
.db 0x02 ; interface class = Communication Interface Class
.db 0x02 ; interface sub-class = Abstract Control Model
.db 0x01 ; interface protocol code class = AT Commands V.250
.db 5 ; interface descriptor string index
;;
;; 5.2.3 Functional Descriptors
;;
;; This is based on a sample functional descriptor described in
;;
;; USB Class Definition for Communication Devices
;; - Table 18: Sample Communications Class Specific Interface Descriptor
;; - http://www.usb.org/developers/docs/devclass_docs/CDC1.2_WMC1.1_012011.zip
;; - CDC120-20101103-track.pdf
;;
;; Header Functional Descriptor
.db 0x05 ; size
.db CS_INTERFACE
.db 0x00 ; subtype = Header FD
.dw 0x1001 ; bcdCDC release number (0110h, LSB-first)
;; Abstract Control Model Functional Descriptor
;; @see PSTN120.pdf, Table 4: Abstract Control Management Functional Descriptor
.db 0x04 ; size
.db CS_INTERFACE
.db 0x02 ; subtype = ACM-FD
.db 0x02 ; bmCapabilities
;; Union Functional Descriptor
.db 0x05 ; size
.db CS_INTERFACE
.db 0x06 ; subtype = Union FD
.db 0 ; bControlInterface (I/F# of Communication Class Interface)
.db 1 ; bSubordinateInterface0 (I/F# of Data Class Interface)
;; Call Management Functional Descriptor
;; @see PSTN120.pdf, Table 3: Call Management Functional Descriptor
.db 0x05 ; size
.db CS_INTERFACE
.db 0x01 ; subtype = CM-FD
.db 0x00 ; bmCapabilities
.db 0x01 ; bDataInterface
;; EP1
.db DSCR_ENDPOINT_LEN
.db DSCR_ENDPOINT_TYPE
.db EP1 + EP_IN
.db ENDPOINT_TYPE_INT
.db 0x10 ; max packet size (LSB)
.db 0x00 ; max packet size (MSB)
.db 0x02 ; polling interval
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Interface #1.0 - Data Class Interface
;;;
;;; [CDC] 4.5 Data Class Interface Codes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.db DSCR_INTERFACE_LEN
.db DSCR_INTERFACE_TYPE
.db 1 ; interface index
.db 0 ; altsetting index
.db 2 ; n endpoints
.db 0x0A ; interface class = CDC-Data
.db 0x00 ; interface sub-class = unused
.db 0x00 ; interface protocol code class = None
.db 6 ; interface descriptor string index
;; EP1
.db DSCR_ENDPOINT_LEN
.db DSCR_ENDPOINT_TYPE
.db EP1 + EP_OUT
.db ENDPOINT_TYPE_BULK
.db 0x40 ; max packet size (LSB)
.db 0x00 ; max packet size (MSB)
.db 0x00 ; polling interval
;; EP8
.db DSCR_ENDPOINT_LEN
.db DSCR_ENDPOINT_TYPE
.db EP8 + EP_IN
.db ENDPOINT_TYPE_BULK
.db 0x00 ; max packet size (LSB)
.db 0x02 ; max packet size (MSB)
.db 0x00 ; polling interval
.endm
ifdesc
highspd_dscr_realend:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Configuration for Full-Speed mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.even
_fullspd_dscr:
.db fullspd_dscr_end - _fullspd_dscr ; descriptor size
.db DSCR_CONFIG_TYPE ; descriptor type
;; can't use .dw because byte order is different
.db (fullspd_dscr_realend - _fullspd_dscr) % 256 ; total length of config (LSB)
.db (fullspd_dscr_realend - _fullspd_dscr) / 256 ; total length of config (MSB)
.db 2 ; n interfaces
.db 1 ; config number
.db 4 ; config string index
.db 0x80 ; attributes = bus powered, no wakeup
.db 50 ; max power = $val * 2[mA]
fullspd_dscr_end:
;; use macro to insert same descriptor as high-speed
;;
;; TODO:
;; - Enhance macro, so it can use different EP packet size
ifdesc
fullspd_dscr_realend:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; String Tables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.even
_dev_strings:
.macro usbstring mystr
.nchr len, mystr
.db 2 + len * 2
.db DSCR_STRING_TYPE
.irpc c, mystr
.strz ''c''
.endm
.endm
;; First entry is a language id, not a string data.
;; @see http://www.usb.org/developers/docs/USB_LANGIDs.pdf
.db 4
.db DSCR_STRING_TYPE
.db 0x09, 0x04 ; 0x0409: U.S. English
;; Actual string data.
;; NOTE: In decsriptor, string index #0 means "No string to use"
str1: usbstring ^!^/Mfg X/!
str2: usbstring ^!^/Prd X/!
str3: usbstring ^!^/Ser X/!
str4: usbstring ^!^/Cfg1/!
str5: usbstring ^!^/CommIF/!
str6: usbstring ^!^/DataIF/!
;; Last entry is a sentinel to mark END-OF-STRING-TABLE
.dw 0x0000
_dev_strings_end:
@0wwafa
Copy link
Copy Markdown

0wwafa commented Feb 1, 2026

Thanks for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment