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:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment