Loading...
 

MIDI USB HID Descriptor

' ************************************************************
' * Auto generated EasyHID file. PBP 2.60 and above          *
' ************************************************************

' include the HID descriptor
INCLUDE "DESCUSB_MIDI.bas"
DEFINE WRITE_INT 1
Define	LOADER_USED	1
DEFINE RESET_ORG 800h ' For Microchip USB Bootloader
DEFINE INTERRUPT_ORG 808h ' For Microchip USB Bootloader

DEFINE OSC 48                   ' tell program we are using a 20mhz oscillator
DEFINE HSER_RCSTA 90h           ' enable serial receive 
DEFINE HSER_TXSTA 24h           ' enable serial transmit
DEFINE HSER_BAUD 31250          ' set baud rate for MIDI transmission
DEFINE ADC_BITS 8              ' set the number of bits in the sample
DEFINE ADC_SAMPLEUS 50          ' set the sample time
I2C_Data    var PORTD.1
I2C_CLK     var PORTD.0


USBBufferSizeMax   CON 16  ' maximum buffer size
USBBufferSizeTX    CON 16  ' input
USBBufferSizeRX    CON 16  ' output

' the USB buffer...
USBBuffer        VAR BYTE[USBBufferSizeMax]
USBBufferCount   VAR BYTE


Portb = %11111111
ADCON1 = %00000101              ' AN0 - AN9 analog
TRISA = %00101111               ' Set PORTA to inputs
TRISB = %00001100
TRISC = %00000000
TRISD = %11110000
TRISE = %00000111  ' Porte 1,2 ,3 inputs, 
CMCON = 7         'PortA Digital
INTCON2.7 = 0     'weak pullups portB  = 0, disable = 1
PORTE.7 = 1        '  weak pullups portd enabled

'======================================================================================
' Port A Registers (8 Bit Mode)
IODIRA             con   $00          ' Direction Bit Control Reg
IOBITSA            con	%11111111	' Direction Bit Settings Reg (0 = output, 1 = input)
IPOLA              con	$01			' Interrupt Polarity Control Reg
GPINTENA           con	$02			'Interrupt Enable Reg
DEFVALA            con	$03
INTCONA	           con	$04
IOCONA	           con	$05			' I/O Configuration Reg
IOCONSETA          con	%10111000	' IOCON register setting
GPPUA	           con	$06			' Pull-Up Control Reg
INTFA	           con	$07			' Interrupt Flag Register
INTCAPA	           con	$08
GPIOA	           con	$09			' General Purpose I/O
IOLATA	           con	$0A			' Output Latch Reg

'Port B Registers (8 Bit Mode)
IODIRB	          con	$10			' Port B Direction Bit Control Address
IOBITSB	          con	%00000000		' Port B Direction Bit Settings (0 = output, 1 = input)
IPOLB	          con	$11			' Interrupt Polarity Control
GPINTENB          con	$12			' Interrupt Enable Reg
DEFVALB	          con	$13
INTCONB	          con	$14
IOCONB	          con	$15			' I/O Configuration Reg
IOCONSETB         con	%10111000		' IOCON register setting
GPPUB	          con	$16			' Pull-Up Control Reg
INTFB	          con	$17			' Interrupt Flag Register
INTPOLB	          con	$18
GPIOB	          con	$19			' General Purpose I/O Reg
IOLATB	          con	$1A			' Output Latch Reg

'========================================================================================
' Port A Reguisters (16 Bit Mode)
IODIRA16            con	    $00
IODIRB16            con	    $01
IOCONA16            con	    $0A
IOCONB16            con	    $0B
GPIOA16             con		$12
GPIOB16             con		$13
OLATA16             con		$14
OLATB16             con		$15

IO_EXP0WR           con	    $40		' MCP23017  Write
IO_EXP0RD           con	    $40		' MCP23017  Read
IO_DAT              var     byte    ' MCP23017  Data read
IO_DAT_OLD          var     byte
IO_DATA             var     byte    ' MCP23017  Data read
IO_DAT_OLDA         var     byte
IO_DATB             var     byte    ' MCP23017  Data read
IO_DAT_OLDB         var     byte
Out_Dat             var     byte
Enc1                var     byte
Enc1_Old            var     byte
Enc1_Mask           con     %00000011
Enc2                var     byte
Enc2_Old            var     byte
Enc2_Mask           con     %00001100
Enc3                var     byte
Enc3_Old            var     byte
Enc3_Mask           con     %00110000
Enc4                var     byte
Enc4_Old            var     byte
Enc4_Mask           con     %11000000
EncTemp             var     byte
Enc1_val            var     byte
Enc2_val            var     byte
Enc3_val            var     byte
Enc4_val            var     byte

CPS1                var     byte
CPS2                var     byte
CPS3                var     byte
CPS4                var     byte
CPS5                var     byte
CPS6                var     byte

'=============================================================================
'             The control code assignments for the 6 switches
'=============================================================================
CPS1_CC  VAR    BYTE    '           con     30
CPS2_CC  VAR    BYTE    '           con     31
CPS3_CC  VAR    BYTE    '           con     66
CPS4_CC  VAR    BYTE    '           con     41
CPS5_CC  VAR    BYTE    '           con     42
CPS6_CC  VAR    BYTE    '           con     43
'=============================================================================
'             The control code assignments for the 4 encoders
'=============================================================================
CPENC1_CC  VAR    BYTE    '         con     84
CPENC2_CC  VAR    BYTE    '         con     76
CPENC3_CC  VAR    BYTE    '         con     68
CPENC4_CC  VAR    BYTE    '         con     80

       '  Flags
SW1_Flag            var     bit
CPS1_Flag           var     bit
CPS2_Flag           var     bit
CPS3_Flag           var     bit
CPS4_Flag           var     bit
CPS5_Flag           var     bit
CPS6_Flag           var     bit

sl_ADC  var word[9]
sl_Old  var byte[9]
Channel var byte
Control var byte
Value   var byte
j   var byte
C0 Var word	     	            
C1 Var word                     
EXP var word
EXP1    var byte
EXPOld  var byte
EXP_CC  var byte
volout Var byte                 
Channel = 176
Control = 0
Upper  var byte
Lower  VAR BYTE
Bass   VAR BYTE
SwitchBank  var byte
SwitchBank1  var byte
SwitchBankOld  var byte
RSS var byte
RSSOld  var byte
CounterA var Byte
RawData var Byte [16]
k var byte
i   var byte
LED1    var PORTC.2

upper = 12
lower = 0   '9
bass = 0    '
PORTD = $FF
    FOR j = 0 TO 15
       READ j, USBBuffer[j]
    NEXT j
    CPS1_CC =  USBBuffer[0]
    CPS2_CC =  USBBuffer[1]
    CPS3_CC =  USBBuffer[2]
    CPS4_CC =  USBBuffer[3]
    CPS5_CC =  USBBuffer[4]
    CPS6_CC =  USBBuffer[5]
    CPENC1_CC = USBBuffer[6]
    CPENC2_CC = USBBuffer[7]
    CPENC3_CC = USBBuffer[8]
    CPENC4_CC = USBBuffer[9]
PAUSE 500


gosub InitMPC23017
goto MainLoop        'jump over subs to main loop


' ************************************************************
'              Start of Subs
' ************************************************************
' * receive data from the USB bus                            *
' ************************************************************
DoUSBIn:
   USBBufferCount = USBBufferSizeRX              ' RX buffer size
   USBIN 1, USBBuffer, USBBufferCount, DoUSBIn  ' read data, if available
   RETURN

' ************************************************************
' * wait for USB interface to attach                         *
' ************************************************************
DoUSBOut:
   USBBufferCount = USBBufferSizeTX              ' TX buffer size
   USBOUT 1, USBBuffer, USBBufferCount, DoUSBOut ' if bus available, transmit data
   RETURN
' ************************************************************
' *  USB Attach detach                        *
' ************************************************************
Program:
          led1 = 1
          INCLUDE "USB_ASM_Service.pbp"
          PAUSE 500
          GOSUB DoUSBIn

       
        FOR k = 0 TO 15
            READ k , USBBuffer[k]
        NEXT k
        PAUSE 250
        GOSUB DoUSBOut
        PAUSE 250
        GOSUB DoUSBIn
        FOR k = 0 TO 15
            WRITE k, USBBuffer[k]
        NEXT k
            CPS1_CC =  USBBuffer[0]
            CPS2_CC =  USBBuffer[1]
            CPS3_CC =  USBBuffer[2]
            CPS4_CC =  USBBuffer[3]
            CPS5_CC =  USBBuffer[4]
            CPS6_CC =  USBBuffer[5]
            CPENC1_CC = USBBuffer[6]
            CPENC2_CC = USBBuffer[7]
            CPENC3_CC = USBBuffer[8]
            CPENC4_CC = USBBuffer[9]
        
        
        
        
        PAUSE  1000
        GOSUB DoUSBOut

PAUSE 1000
            UCON.3 = 0

             for i = 0 to 20
                toggle led1
                pause 200
             next i
             led1 = 0



RETURN
'*******************************************************************************
'******************************************************************************

   
InitMPC23017:
Pause 100
'=================== PORTA  ====================================================
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOCONA,IOCONSETA]     'IOCON register setting
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IODIRA,$FF]           'PortA inputs
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOLATA,$FF]           'PortA = 0
'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IPOLA,0]             'Input polarity 1= opposite 0 =  normal
'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[DEFVALA,0]           'Default value register
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPPUA,$FF]           'pull-ups enabled   1 = enable 0 = disable
'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[INTCONA,0]           'INTERRUPT-ON-CHANGE CONTROL REGISTER
'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPINTENA,$FF]        'interupt on change  1= enable 0 = disable
'==================== PORTB   ====================================================
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOCONB,IOCONSETB]
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IODIRB,$FF]           'PortB inputs
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOLATB,$FF]
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPPUB,$FF]           'pull-ups enabled   1 = enable 0 = disable
'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IPOLB,0]
'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[DEFVALB,0]
'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[INTCONB,0]
'i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPINTENB,0]
return
ReInitPortA:
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IOCONA,IOCONSETA]
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[IODIRA,$FF] 
i2cwrite  I2C_Data,I2C_CLK,IO_EXP0WR,[GPPUA,$FF]           'pull-ups enabled

return
'******************************************************************************

Scale:
   select case sl_ADC[j]
   case 126
   volout = 0
   case  114
    volout = 15
   case 110, 112
   volout = 30
   case 104, 106
    volout = 45   
    case 98
   volout = 60
   case 86
    volout = 75
   case 62
   volout = 90
   case 38
    volout = 105
   case 0
    volout = 125   
    case else
    
   end select
 
   
   Control = j + Upper + lower +  bass ' drawbars are CC 12-20
   HSEROUT [channel,control,volout]       ' send data out serial port as midi information
   sl_old[j] = sl_ADC[j] 
 
return
'*******************************************************************************
SortArray:           'Soer data small to large
	CounterA=0
SortLoop:
	If RawData(CounterA+1) < RawData(CounterA) then
		RawData(CounterA)     = RawData(CounterA) ^ RawData(CounterA+1)
		RawData(CounterA+1+0) = RawData(CounterA) ^ RawData(CounterA+1)
		RawData(CounterA)     = RawData(CounterA) ^ RawData(CounterA+1)
		If CounterA > 0 then CounterA=CounterA-2
		endif
	CounterA=CounterA+1
	If CounterA < 15 then goto SortLoop

    ' Take the middle eight and average
'    C1 = (RAWDATA[4] + RAWDATA[5] + RAWDATA[6] + RAWDATA[7] + RAWDATA[8] + RAWDATA[9] + RAWDATA[10] + RAWDATA[11]) / 8
    c1 = 0
    for i = 6 to 9
        c1 = c1 + rawdata[i]
    next i
    c1 = c1 / 4
Return
'******************************************************************************
'
'                             Main Loop
'
'******************************************************************************

MainLoop:

            'SLIDERS 1-9
for j = 0 to 8
                                          'Take 16 samoles
    for k = 0 to 15
        ADCIN j,c0                       ' read Volume pot and place value in C0
        rawdata[k] = c0
    next k
    gosub sortarray
    sl_ADC[j] = (C1 >>2)*2                    ' convert reading to a midi value from 1-127
    If sl_ADC[j] <> sl_old[j] Then           ' check to see if the value has changed
    gosub scale
    Endif
next j
     ' EXPRESSION Pedal
     ADCIN 9,exp 
     exp1 = exp >> 1
      if expold <> exp1 then
      HSEROUT [177,11,exp1]
      expold = exp1
      endif
switchbank = PORTD & %11110000
if switchbank <> switchbankold   then
        if switchbank.7 = 0 then         ' 
           if sw1_flag = 0 then
                sw1_flag = 1: led1 = 1: exp_cc = 127
            elseif sw1_flag = 1 then
                sw1_flag = 0: led1 = 0: exp_cc = 0
            endif 
    HSEROUT [177,1,EXP_CC]
 endif
            
             'Slider bank selection
    if switchbank.4 = 0 then                   
    Upper = 12:  lower = 0:  bass = 0         'Select upper bank
        elseif switchbank.5 = 0 then
        Upper = 12:  lower = 9:  bass = 0       'select lower bank
            elseif switchbank.6 = 0 then
            Upper = 12:  lower = 9:  bass = 12    'select bass bank
    endif            
            
  
  
switchbankold = switchbank
endif
'================ MCP23017 Decoder ============================================
i2cread I2C_Data,I2C_CLK,IO_EXP0rd,gpioa,[IO_data]      'read 23017
if io_data != io_dat_olda then
'----------------------------------------------------------------------------- 
   if io_data.0 = 0 and io_data.5 = 0 then
   
   gosub program
   endif

'-----------------------------------------------------------------------------    
    if io_data.0 = 0 then
        if cps1_flag = 0 then
            cps1_flag = 1:  CPS1 = 127
        elseif cps1_flag = 1 then
            cps1_flag = 0: CPS1 = 0
        endif 
    HSEROUT [177,cps1_cc, CPS1]  '"SW1"
   endif
'-----------------------------------------------------------------------------
   if io_data.1 = 0 then
           if cps2_flag = 0 then
            cps2_flag = 1:  CPS2 = 127
        elseif cps2_flag = 1 then
            cps2_flag = 0: CPS2 = 0
        endif 

       HSEROUT [177,cps2_cc, cps2]   '"SW2"
   endif
'----------------------------------------------------------------------------- 
  if io_data.2 = 0 then
        if cps3_flag = 0 then
            cps3_flag = 1:  CPS3 = 127
        elseif cps3_flag = 1 then
            cps3_flag = 0: CPS3 = 0
        endif 

        HSEROUT [177,cps3_cc, cps3]  '"SW3"
  endif
'-----------------------------------------------------------------------------
  if io_data.3 = 0 then
        if cps4_flag = 0 then
            cps4_flag = 1:  CPS4 = 127
        elseif cps4_flag = 1 then
            cps4_flag = 0: CPS4 = 0
        endif 
         HSEROUT [177,cps4_cc, cps4]  '"SW4"
  endif
'-----------------------------------------------------------------------------
  if io_data.4 = 0 then
        if cps5_flag = 0 then
            cps5_flag = 1:  CPS5 = 127
        elseif cps5_flag = 1 then
            cps5_flag = 0: CPS5 = 0
        endif 


        HSEROUT [177,cps5_cc, cps5]  ' "SW5"
  endif
'-----------------------------------------------------------------------------
  if io_data.5 = 0 then
        if cps6_flag = 0 then
            cps6_flag = 1:  CPS6 = 127
        elseif cps6_flag = 1 then
            cps6_flag = 0: CPS6 = 0
        endif 
HSEROUT [177,cps6_cc, cps6]  ' "SW6"
  endif
  pause 250
endif

'-----------------------------------------------------------------------------
i2cread I2C_Data,I2C_CLK,IO_EXP0rd,gpiob,[IO_datb]      'read 23017

if io_datb != io_dat_oldb then

    enc1 = io_datb & enc1_mask
    if enc1_old = enc1   then goto Encoder2
    enctemp = enc1.bit1 ^ enc1_old.bit0
    if enctemp = 1 then goto Inc1
    Enc1_val = Enc1_val - 1
    if enc1_val < 1 then enc1_val = 1
    HSEROUT [177,cpenc1_cc,enc1_val]
    goto Encoder2
Inc1:    
   Enc1_val = Enc1_val + 1 
   if enc1_val => 127 then enc1_val = 127
   HSEROUT [177,cpenc1_cc,enc1_val]
'---------------------------------------------------------------------------
Encoder2:

    enc2 = io_datb & enc2_mask
    if enc2_old = enc2   then goto Encoder3
    enctemp = enc2.bit3 ^ enc2_old.bit2
    if enctemp = 1 then goto Inc2
    Enc2_val = Enc2_val - 1
    if enc2_val < 1 then enc2_val = 1
    HSEROUT [177,cpenc2_cc,enc2_val]
    goto encoder3
Inc2:    
   Enc2_val = Enc2_val + 1 
   if enc2_val => 127 then enc2_val = 127
   HSEROUT [177,cpenc2_cc,enc2_val]

'---------------------------------------------------------------------------
Encoder3:

    enc3 = io_datb & enc3_mask
    if enc3_old = enc3   then goto Encoder4
    enctemp = enc3.bit5 ^ enc3_old.bit4
    if enctemp = 1 then goto Inc3
    Enc3_val = Enc3_val - 1
    if enc3_val < 1 then enc3_val = 1
    HSEROUT [177,cpenc3_cc,enc3_val]
    goto encoder4
Inc3:    
   Enc3_val = Enc3_val + 1 
   if enc3_val => 127 then enc3_val = 127
    HSEROUT [177,cpenc3_cc,enc3_val]

'---------------------------------------------------------------------------
Encoder4:

    enc4 = io_datb & enc4_mask
    if enc4_old = enc4   then goto Encend
    enctemp = enc4.bit7 ^ enc4_old.bit6
    if enctemp = 1 then goto Inc4
    Enc4_val = Enc4_val - 1
    if enc4_val < 1 then enc4_val = 1
    HSEROUT [177,cpenc4_cc,enc4_val]
    goto encend
Inc4:    
   Enc4_val = Enc4_val + 1
   if enc4_val => 127 then enc4_val = 127
   HSEROUT [177,cpenc4_cc,enc4_val]
EncEnd:

'-----------------------------------------------------------------------------
    enc1_old = enc1
    enc2_old = enc2
    enc3_old = enc3
    enc4_old = enc4

io_dat_olda = io_data
io_dat_oldb = io_datb
endif

'===============================================================================


goto MainLoop
end



xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


' USB descriptors for a HID device
'USBMEMORYADDRESS Con	$400	' USB RAM starts here (set in device header file)
USBMEMORYSIZE	Con	256	' USB RAM size in bytes
USBReservedMemory Var Byte[USBMEMORYSIZE] USBMEMORYADDRESS	' Reserve memory used by USB assembler code

goto	hid_desc_end	' Skip over all of the USB assembler code
asm

#define	USB_EP0_BUFF_SIZE 	64	; 8, 16, 32, or 64
#define	USB_MAX_NUM_INT		1	; For tracking Alternate Setting
#define	USB_MAX_EP_NUMBER  	1	; UEP1
#define	NUM_CONFIGURATIONS	1
#define	NUM_INTERFACES		1

#define UCFG_VAL	USB_PULLUP_ENABLE|USB_INTERNAL_TRANSCEIVER|USB_FULL_SPEED|USB_PING_PONG__NO_PING_PONG
;#define UCFG_VAL	USB_PULLUP_ENABLE|USB_INTERNAL_TRANSCEIVER|USB_LOW_SPEED|USB_PING_PONG__NO_PING_PONG

;#define USE_SELF_POWER_SENSE_IO
;#define USE_USB_BUS_SENSE_IO

#define USB_POLLING

; HID
; Endpoints Allocation
#define	HID_INTF_ID		  0x00
#define	HID_EP			  1
#define	HID_INT_OUT_EP_SIZE	  64
#define	HID_INT_IN_EP_SIZE	  64
#define	HID_NUM_OF_DSC		  1

   include	"usb_hid.asm"	; Include rest of USB files, starting with HID class code

; ******************************************************************
; This table is polled by the host immediately after USB Reset has been released.
; This table defines the maximum packet size EP0 can take.
; See section 9.6.1 of the Rev 1.0 USB specification.
; These fields are application DEPENDENT. Modify these to meet
; your specifications.
; ******************************************************************
DeviceDescriptor
	retlw	(EndDeviceDescriptor-DeviceDescriptor)/2	; bLength Length of this descriptor
	retlw	USB_DESCRIPTOR_DEVICE ; bDescType This is a DEVICE descriptor
	retlw	0x10		; bcdUSBUSB Revision 1.10 (low byte)
	retlw	0x01		; high byte
	retlw	0x00		; bDeviceClass zero means each interface operates independently
	retlw	0x00		; bDeviceSubClass
	retlw	0x00		; bDeviceProtocol
	retlw	USB_EP0_BUFF_SIZE ; bMaxPacketSize for EP0

        ; idVendor (low byte, high byte)
	retlw	0xA6
	retlw	0x01

        ; idProduct (low byte, high byte)
	retlw	0xDB
	retlw	0x07

        retlw	0x00		; bcdDevice (low byte)
	retlw	0x00		; (high byte)
	retlw	0x01		; iManufacturer (string index)
	retlw	0x02		; iProduct      (string index)

        ; iSerialNumber (string index)
	retlw	0x03
	retlw	NUM_CONFIGURATIONS ; bNumConfigurations
EndDeviceDescriptor

; ******************************************************************
; This table is retrieved by the host after the address has been set.
; This table defines the configurations available for the device.
; See section 9.6.2 of the Rev 1.0 USB specification (page 184).
; These fields are application DEPENDENT. 
; Modify these to meet your specifications.
; ******************************************************************
; Configuration pointer table
USB_CD_Ptr
Configs
	db	low Config1, high Config1
	db	upper Config1, 0

; Configuration Descriptor
Config1
	retlw	(Interface1-Config1)/2	; bLength Length of this descriptor
	retlw	USB_DESCRIPTOR_CONFIGURATION ; bDescType 2=CONFIGURATION
Config1Len
	retlw	low ((EndConfig1 - Config1)/2)	; Length of this configuration
	retlw	high ((EndConfig1 - Config1)/2)
	retlw	0x01		; bNumInterfaces Number of interfaces
	retlw	0x01		; bConfigValue Configuration Value
	retlw	0x00		; iConfig (string index)
	retlw	_DEFAULT|_SELF	; bmAttributes attributes - bus powered

        ; Max power consumption (2X mA)
	retlw	0x32
Interface1
	retlw	(HIDDescriptor1-Interface1)/2	; length of descriptor
	retlw	USB_DESCRIPTOR_INTERFACE
	retlw	0x00		; number of interface, 0 based array
	retlw	0x00		; alternate setting
	retlw	0x02		; number of endpoints used in this interface
	retlw	0x03		; interface class - assigned by the USB
	retlw	0x00		; boot device
	retlw	0x00		; interface protocol
	retlw 	0x00		; index to string descriptor that describes this interface
HIDDescriptor1
	retlw	(Endpoint1In-HIDDescriptor1)/2	; descriptor size (9 bytes)
        retlw	DSC_HID		; descriptor type (HID)
	retlw	0x11		; HID class release number (1.11)
	retlw	0x01
        retlw	0x00		; Localized country code (none)
        retlw	0x01		; # of HID class descriptor to follow (1)
        retlw	0x22		; Report descriptor type (HID)
ReportDescriptor1Len
	retlw	low ((EndReportDescriptor1-ReportDescriptor1)/2)
	retlw	high ((EndReportDescriptor1-ReportDescriptor1)/2)
Endpoint1In
	retlw	(EndPoint1Out-Endpoint1In)/2	; length of descriptor
	retlw	USB_DESCRIPTOR_ENDPOINT
	retlw	HID_EP|_EP_IN		; EP1, In
	retlw	_INT		; Interrupt
	retlw	low (HID_INT_IN_EP_SIZE)		; This should be the size of the endpoint buffer
	retlw	high (HID_INT_IN_EP_SIZE)
	retlw	0x0A                        ; Polling interval
EndPoint1Out
	retlw	(EndConfig1-EndPoint1Out)/2	; Length of this Endpoint Descriptor
	retlw	USB_DESCRIPTOR_ENDPOINT		; bDescriptorType = 5 for Endpoint Descriptor
	retlw	HID_EP|_EP_OUT		; Endpoint number & direction
	retlw	_INT		; Transfer type supported by this Endpoint
	retlw	low (HID_INT_OUT_EP_SIZE)		; This should be the size of the endpoint buffer
	retlw	high (HID_INT_OUT_EP_SIZE)
	retlw	0x0A                        ; Polling interval
EndConfig1

ReportDescriptor1
    ; vendor defined usage page
    retlw	0x06		
    retlw	0x00
    retlw	0xFF

    ; vendor defined usage
    retlw	0x09
    retlw	0x00

    ; collection(application)
    retlw	0xA1
    retlw	0x01

    ; *** INPUT REPORT ***

    ; vendor defined usage
    retlw	0x09
    retlw	0x01

    retlw	0x15 	; logical minimum (-128)
    retlw	0x80    ;
    retlw	0x25 	; logical maximum (127)
    retlw	0x7F    ;
    retlw	0x35 	; Physical Minimum (0)
    retlw	0x00    ;
    retlw	0x45 	; Physical Maximum (255)
    retlw	0xFF    ;

    ; report size in bits
    retlw	0x75
    retlw	0x08

    ; report count (number of fields)
    retlw	0x95
    retlw	0x10

    ; Input (Data, Variable, Absolute)
    retlw	0x81
    retlw	0x02

    ; *** OUTPUT REPORT ***

    ; vendor defined usage
    retlw	0x09	    ; usage (Vendor Defined)
    retlw	0x02        ;

    retlw	0x15	    ; logical minimum (-128)
    retlw	0x80        ;
    retlw	0x25	    ; logical maximum (127)
    retlw	0x7F        ;
    retlw	0x35	    ; Physical Minimum (0)
    retlw	0x00        ;
    retlw	0x45	    ; Physical Maximum (255)
    retlw	0xFF        ;

    ; report size in bits
    retlw	0x75
    retlw	0x08

    ; report count (number of fields)
    retlw	0x95
    retlw	0x10

    ; Output (Data, Variable, Absolute)
    retlw	0x91
    retlw	0x02

    retlw   0xC0       	   ; end collection

EndReportDescriptor1

; String pointer table
USB_SD_Ptr
Strings
	db	low String0, high String0
        db	upper String0, 0
	db	low String1, high String1
        db	upper String1, 0
	db	low String2, high String2
       	db	upper String2, 0
	db	low String3, high String3
	db	upper String3, 0

String0
	retlw	(String1-String0)/2	; Length of string
	retlw	USB_DESCRIPTOR_STRING   ; Descriptor type 3
	retlw	0x09		        ; Language ID (as defined by MS 0x0409)
	retlw	0x04

; company name
String1
	retlw	(String2-String1)/2
	retlw	USB_DESCRIPTOR_STRING
	
        retlw   'D'
        retlw   0x00
        retlw   'L'
        retlw   0x00
        retlw   'C'
        retlw   0x00
        retlw   'I'
        retlw   0x00
        retlw   'N'
        retlw   0x00
        retlw   'C'
        retlw   0x00

	
; product name	
String2
	retlw	(String3-String2)/2
	retlw	USB_DESCRIPTOR_STRING
	
        retlw   'U'
        retlw   0x00
        retlw   'S'
        retlw   0x00
        retlw   'B'
        retlw   0x00
        retlw   '_'
        retlw   0x00
        retlw   'M'
        retlw   0x00
        retlw   'I'
        retlw   0x00
        retlw   'D'
        retlw   0x00
        retlw   'I'
        retlw   0x00


; serial number
String3
	retlw	(String4-String3)/2
	retlw	USB_DESCRIPTOR_STRING
	
        retlw   '1'
        retlw   0x00
        retlw   '0'
        retlw   0x00
        retlw   '0'
        retlw   0x00
        retlw   '2'
        retlw   0x00

String4


endasm
hid_desc_end