Multiple HID reports

Question: How can we implement multiple HID reports using the USBFS user module in PSoC1?

 

Answer:

If you enable optional HID class support, the USBFS Setup Wizard creates a fixed-size report storage area for data reports from the HID class device. It creates separate report areas for IN, OUT, and FEATURE reports. This area is sufficient for the case where no Report ID item tags are present in the Report descriptor and therefore only one Input, Output, and Feature report structure exists. If you want better control over the report storage size or want to support multiple report IDs, you will need to do the following:

1. Use the wizard to specify your device description, endpoints, and HID reports then generate the application.
2. Disable the wizard defined report storage area in USB_descr.asm.
3. Copy the wizard created code that defines the report storage area.
4. Paste it into the protected user code area in USB_descr.asm or a separate assembly language file.
5. Customize the code to define the report storage area.

Specify Your Device and Generate Application
Use the USB setup wizard to specify your device description, endpoints, and HID reports. Click the Generate Application button in PSoC Designer.

Disable the Wizard Defined Report Storage Area
In the USB_descr.asm file, disable the wizard defined storage area by uncommenting the WIZARD_DEFINED_REPORT_STORAGE line in the custom code area as shown.

WIZARD: equ 1
WIZARD_DEFINED_REPORT_STORAGE: equ 1
;---------------------------------------------------
;@PSoC_UserCode_BODY_1@ (Do not change this line.)
;---------------------------------------------------
; Insert your custom code below this banner
;---------------------------------------------------
; Redefine the WIZARD equate to 0 below by
; uncommenting the WIZARD: equ 0 line
; to allow your custom descriptor to take effect
;---------------------------------------------------
; WIZARD: equ 0
WIZARD_DEFINED_REPORT_STORAGE: equ 0
;---------------------------------------------------
; Insert your custom code above this banner
;---------------------------------------------------
;@PSoC_UserCode_END@ (Do not change this line.)

Copy the Wizard Created Code.

Find this code in USB_descr.asm.
;----------------------------------------------------------------------
; HID IN Report Transfer Descriptor Table for ()
;----------------------------------------------------------------------
IF WIZARD_DEFINED_REPORT_STORAGE
AREA func_lit (ROM,REL,CON)
.LITERAL
USB_D0_C1_I0_IN_RPTS:
TD_START_TABLE 1 ; Only 1 Transfer Descriptor
TD_ENTRY USB_DS_RAM, USB_HID_RPT_3_IN_RPT_SIZE, USB_INTERFACE_0_IN_RPT_DATA, NULL_PTR
.ENDLITERAL
ENDIF ; WIZARD_DEFINED_REPORT_STORAGE

There are three sections, one each for the IN, OUT, and FEATURE reports. Copy all three sections.

Paste the Code Into the Protected User Code Area
You can paste the code into the protected user code area of USB_descr.asm shown or a separate assembly language file.
;---------------------------------------------------
;@PSoC_UserCode_BODY_2@ (Do not change this line.)
;---------------------------------------------------
; Redefine your descriptor table below. You might
; cut and paste code from the WIZARD descriptor
; above and then make your changes.
;---------------------------------------------------

;---------------------------------------------------
; Insert your custom code above this banner
;---------------------------------------------------
;@PSoC_UserCode_END@ (Do not change this line.)
; End of File USB_descr.asm

Customize the Code to Define the Report Storage Area
To define the report storage area, you will write your own transfer descriptor table entries. The table contains entries to define storage space for the reqired data items. Each transfer descriptor entry in the table creates a new Report ID. IDs are numbered consecutively, starting with zero. Report ID 0 is not used; you cannot specify a Report ID of 0, but the transfer descriptor entry specified for the ID 0 will be used in the case that no Report IDs are present in the Report descriptor. For the sake of code effeciency, you should use Report IDs in order starting with ID 1.

The following example sets up the unused Report ID 0, and two other IN reports with different sizes. Note Conditional assembly statements are only necessary if you place the code in the protected user code area of USB_descr.asm.
;----------------------------------------------------------------------
; HID IN Report Transfer Descriptor Table for ()
;----------------------------------------------------------------------
IF WIZARD_DEFINED_REPORT_STORAGE
ELSE
_ID0_RPT_SIZE: EQU 8 ; 7 data bytes + report ID = 8 bytes (unused)
_SM_RPT_SIZE: EQU 3 ; 2 data bytes + report ID = 3 bytes
_LG_RPT_SIZE: EQU 5 ; 4 data bytes + report ID = 5 bytes
AREA data (RAM, REL, CON)
EXPORT _ID0_RPT_PTR
_ID0_RPT_PTR: BLK 8 ; Allocates space for report ID0 (unused)
EXPORT _SM_RPT_PTR
_SM_RPT_PTR: BLK 3 ; Allocates space for report ID1
EXPORT _LG_RPT_PTR
_LG_RPT_PTR: BLK 5 ; Allocates space for report ID2
AREA bss (RAM, REL, CON)
EXPORT _SM_RPT_STS_PTR
_SM_RPT_STS_PTR: USBFS_XFER_STATUS_BLOCK
EXPORT _LG_RPT_STS_PTR
_LG_RPT_STS_PTR: USBFS_XFER_STATUS_BLOCK
AREA func_lit (ROM,REL,CON)
.LITERAL
EXPORT USB_D0_C1_I0_IN_RPTS:
TD_START_TABLE 3
TD_ENTRY USBFS_DS_RAM, _ID0_RPT_SIZE, _ID0_RPT_PTR, NULL_PTR ; ID0 unused
TD_ENTRY USBFS_DS_RAM, _SM_RPT_SIZE, _SM_RPT_PTR, _SM_RPT_STS_PTR ; ID1
TD_ENTRY USBFS_DS_RAM, _LG_RPT_SIZE, _LG_RPT_PTR, _LG_RPT_STS_PTR ; ID2
.ENDLITERAL
ENDIF ; WIZARD_DEFINED_REPORT_STORAGE