www.pudn.com > windows2000XP_WDM_DeviceDriverDevelopment_WuAnHe_C > Counter.ASM
; Port Usage
; P1.0 -
; .1 -
; .2 - Button (0=pushed) (input)
; .3 - LED (0=on) (output)
;
;*******************************************************************************
;//$PAGE
; Directives
FillROM 0
; Microprocessor definitions
include "63x0x.inc"
;*************************************************
; Data Segment (RAM)
;*************************************************
; Program Stack
gbSysProgramStack :equ 00h ; [00h-1Fh] Stack 0x20h
gbSysDataStack :equ 50h ; [50h-6Fh] Stack 0x70h
gbSysFIFO :equ 70h ; [70h-7Fh] EP0 and EP1 FIFO's
; Global Interrupt
gbSysInterruptMask :equ 20h ; Holds the current interrupt mask
; USB management data
gbUSBSendSequence :equ 28h ; Buffer send data 0/1 line
gbUSBSendBytes :equ 29h ; Buffer bytes left to send
gbUSBSendBuffer :equ 2Ah ; Offset into current buffer
gbSuspendCount :equ 2Bh ; # of msec bus has been IDLE
; Button management
gbButtonDebounce :equ 2Ch ; Debounce count down value
gbButtonClicks :equ 2Dh ; Button count value
Button_Pin :equ 04h ; Pin the switch is on, P12
LED_ON :equ 08h ; P13 is used to indicate Enumeration
;//$PAGE
;*************************************************
; Code Segment (ROM)
;*************************************************
; Vector Table
org 00h
jmp main ; Reset of some type
jmp SysUnUsed ; 128us timer (not used)
jmp SysTimer1024usEvent ; 1024us timer
jmp USBEndPoint0Event ; EP0
jmp USBEndPoint1Event ; EP1 (not used)
jmp SysUnUsed ; Reserved
jmp SysGPIOEvent ; Button
jmp SysUnUsed ; CExt (not used)
;*************************************************
; Unused event
; Do nothing, restore machine to prior state
;*************************************************
SysUnUsed:
push a
mov a,[gbSysInterruptMask]
ipret SysInterrupt
;//$PAGE
;*******************************************************************************
; main()
; @func Entry point after PowerOn, WatchDog timeout or WakeUp from sleeping.
; @comm Never returns
;*******************************************************************************
main:
; This portion of Main is only executed after a RESET (Power-On or USB)
; Setup data stack in high order RAM, just below EP0 FIFO
; It will grow down from here
mov a,70h ; USBEndP0FIFO
swap a,dsp
; Initialize both Ports high
mov a,FFh
iowr SysPort0 ; Port 0 Data reg
iowr SysPort1 ; Port 1 Data reg
; 1 on P13 is needed to make sure enumerate LED is off
; 1 on any port that needs to be an input
; Enable Pullups (0=enable)
mov a,0
iowr SysPort0PullUp
mov a,Button_Pin
iowr SysPort1PullUp ; 1 on P12 is needed to make sure GPIO interrupt
; occurs on LOW to HIGH transistion. This
; disables it's pull up
; Enable or disable interrupts on appropriate pins
mov a,0
iowr SysPort0IntEnable ; All pins irq's are disabled on Port 0
mov a,Button_Pin
iowr SysPort1IntEnable ; Enable P12, the button pin.
; No interrupts will occur until the device
; is enumerated. Then GPIO's will be enabled and
; we will allow P12 to generate interrupts
; Initialize USB variables
mov a,0
mov [gbUSBSendSequence],a ; Start with a 0
; Initialize Counter
mov a,0
mov [gbButtonClicks],a ; Initial state of 0, no button pushed
; Initialize variables
mov a,0
mov [gbUSBSendBytes],a ; No bytes to send in FIFO buffers
mov [gbSuspendCount],a ; Reset bus activity to 0
mov [gbButtonDebounce],a ; We are not debouncing
; Set interrupt mask
mov a,SysIntTimer1024us | SysIntUSBEndP0
mov [gbSysInterruptMask],a
;*********************************************
MainLoop:
; Enable interrupts to current mask
mov a,[gbSysInterruptMask]
iowr SysInterrupt
; Loop
jmp MainLoop
;********************************************************
; SysTimer1024usEvent()
; @func Timer interrupt event ocurring every 1.024 mSec
; using 6Mhz crystal.
;********************************************************
SysTimer1024usEvent:
; Save accumulator
push a
; Clear watchdog timer
; Clearing it here effectively disables the timer
iowr SysWatchDog
; Keep track of length of any IDLE conditions (No bus activity)
iord USBControl ; Read the USB Status and Control Reg
and a,01h ; Check bit 0
cmp a,0h
jz Inc_Counter ; Hmm! No activity. Branch and keep track of it.
iord USBControl ; Ah! There was activity,
; clear the bus activity bit
and a,0feh
iowr USBControl
mov a,0 ; Clear the suspend counter
mov [gbSuspendCount],a
jmp Suspend_End
Inc_Counter: ; Monitor the IDLE count
mov a,[gbSuspendCount] ; Get # of mSec we have been IDLE
inc a ; Increment the count
mov [gbSuspendCount],a
cmp a,03h ; Has it been 3msec yet?
jnz Suspend_End ; Not yet, branch
mov a,0h ; Yes, clear the suspend counter
mov [gbSuspendCount],a
iord SysStatus
or a,08h ; Set the suspend bit to cause a suspend
iowr SysStatus ; We will enter the suspend state during
; the next instruction.
Suspend_End:
; Are we counting down a button debounce
mov a,0
cmp a,[gbButtonDebounce]
jz STimerNoDebounce ; Not debouncing, branch
; Yes, we're debouncing. Let's see if we are timed out.
dec [gbButtonDebounce]
mov a,0
cmp a,[gbButtonDebounce]
; has debounce timed out?
jnz STimerNoDebounce ; No, still debouncing, branch.
; The debounce timer has timed out
; check if the button pin is at a 1. If not, the button is either still
; bouncing or still pushed
iord SysPort1 ; check the port the button is on
and a,Button_Pin ; check the pin
jz STimerNoDebounce ; branch if it is not pushed
; Reset debounce since the button is not yet released or is bouncing
mov a,[gbButtonClicks]
inc a;
mov [gbButtonClicks],a
mov [USBEndP1FIFO_0],a
iord USBEndP1TxConfig
and a,40h
or a,91h
iowr USBEndP1TxConfig
; Debounce must be over
STimerNoDebounce:
; Enable interrupts and return
mov a,[gbSysInterruptMask]
ipret SysInterrupt
;//$PAGE
;********************************************************
; SysGPIOEvent()
; @func General purpose port event
; @comm Which pin?
;********************************************************
SysGPIOEvent:
; Save accumulator
push a
; Reset debounce any time we are here
mov a,50
mov [gbButtonDebounce],a
SysGPIOButtonDebouncing:
; Enable interrupts and return
mov a,[gbSysInterruptMask]
ipret SysInterrupt
USBEndPoint1Event:
; Save accumulator
push a
iord USBEndP1TxConfig
xor a,40h
iowr USBEndP1TxConfig
; Enable interrupts and return
mov a,[gbSysInterruptMask]
ipret SysInterrupt
;*******************************************************************************
;
; This section of code responds to activity on End Point 0 and determines
; what needs to be done.
;
;*******************************************************************************
;//$PAGE
;********************************************************
; USBEndPoint0Event()
; @func End Point zero USB event.
; @comm Default end point.
;********************************************************
USBEndPoint0Event:
; This code checks to see what type of packet was received
; (Setup, Out, or In) and jumps to the correct routine to decode the
; specifics. After the code to which the jump points is through, it jumps
; back to USBEventEP0End.
; Save accumulator
push a
; Is this a SETUP packet?
iord USBEndP0RxStatus
and a,USBEndP0RxSetup ; Check the setup bit
jnz USBEventEP0_SETUP ; Yes it's a setup, branch
USBEventEP0End:
; OK. We're done with the packet.
; Let's enable interrupts and return
mov a,[gbSysInterruptMask]
ipret SysInterrupt ; done with EP0 irq service routine
USBEventEP0Stall:
; Stall any subsequent IN's or OUT's until the
; stall bit (bit 5) is cleard by an I/O write to
; the USB End Point 0 TX Configuration Register (0x10)
; or any SETUP is received.
iord USBEndP0TxConfig
or a,USBEndP0TxStall
iowr USBEndP0TxConfig
; OK. We've set the stall condition for Endpoint 0.
; Now let's complete the routine.
jmp USBEventEP0End
;*******************************************************************************
;
; We know we have received a Setup token. Now we need to parse it to
; determine what command it is.
;
;*******************************************************************************
;//$PAGE
;*******************************************************************************
; USBEventEP0_SETUP()
; @func End point event SETUP packet handler.
; @devnote Runs in interrupt enabled context.
;********************************************************
USBEventEP0_SETUP:
; Well, we have a SETUP packet. Let's find out what to do.
mov A,[gbSysInterruptMask]
iowr SysInterrupt
; If we are here and are and we are processing a previous Setup,
; we need to abort the processing of the previous Setup
mov a,0 ; Clear any indication that we have bytes left to transfer
mov [gbUSBSendBytes],a
; Clear EP0 RxReg (including the Setup flag)
; The Data toggle bit remains unchanged, however.
mov a,0
iowr USBEndP0RxStatus
;*********************************************
; Setup Event
;*********************************************
; Check the request type and branch to the correct location to handle it.
mov a,[USBEndP0FIFO_0]
USBEventEP0SetupTargetDeviceOUT:
; Target Device?
cmp a,USBRqstTargetDevice
jz USBEventEP0SetupIsSetAddress ; Yes
USBEventEP0SetupTargetInterfaceOUT:
cmp a,USBRqstTargetInterface
jz USBEventEP0Stall ; Yes. Oops! We don't have an interface.
USBEventEP0SetupTargetEndpointOUT:
cmp a,USBRqstTargetEndPoint
jz USBEventEP0Stall ; Yes
USBEventEP0SetupTargetDeviceIN:
cmp a,USBRqstTargetDevice | USBRqstTypeDirection
jz USBEventEP0SetupGetDescriptor ; Yes
USBEventEP0SetupTargetInterfaceIN:
cmp a,USBRqstTargetInterface | USBRqstTypeDirection
jz USBEventEP0Stall ; Yes Oops! We don't have an interface.
USBEventEP0SetupTargetEndpointIN:
cmp a,USBRqstTargetEndPoint | USBRqstTypeDirection
jz USBEventEP0Stall ; Yes
; Vendor specific commands
USBEventEP0SetupTargetVendorIN_OUT:
; Check request (IN packet OK, OUT packet ERR)
mov a,[USBEndP0FIFO_0]
and a,USBRqstTypeVendor | USBRqstTargetEndPoint | USBRqstTypeDirection
cmp a,USBRqstTypeVendor | USBRqstTargetEndPoint | USBRqstTypeDirection
jz USBEventEP0VendorRqst
; Unsupported request !!!
jmp USBEventEP0Stall ; Oops! We don't support whatever
; request was made.
;//$PAGE
;********************************************************
; USBEventEP0SetupIsSet()
; @func End point event SETUP to set address.
; @devnote Runs in interrupt enabled context.
;********************************************************
USBEventEP0SetupIsSetAddress:
; Set device address?
mov a,[USBRqstMessage]
cmp a,USBRqstSetAddress
jz USBEventEP0SetupSetAddress ; Yes
; Set device configuration?
mov a,[USBRqstMessage]
cmp a,USBRqstSetConfiguration
jz USBEventEP0SetupSetConfig ; Yes
; Unsupported set request !!!
jmp USBEventEP0Stall ; No. Stall
;********************************************************
; USBEventEP0SetupSetAddress()
; @func End point zero event SETUP to set address.
; @devnote Runs in interrupt enabled context.
; @comm
; The status token of the SetAddress is an IN. So, we send status manually.
;********************************************************
USBEventEP0SetupSetAddress:
; Send ACK
call USBSendACK
; Now that we have been acknowleged, we actually set the address.
; This is different from all other commands which execute first
; and then acknowlege (_________________)
; Set Address
mov a,[USBRqstWordValueLo]
iowr USBDeviceAddress
; Done
jmp USBEventEP0End
;********************************************************
; USBEventEP0SetupSetConfig()
; @func End point zero event SETUP to Set Configuration.
; @devnote Runs in interrupt enabled context.
; 1
; set enumerated (gbSysEnumerated) state,
; enable GPIO (and EP1, if appropriate)
; Enable P0 and P1
; 0
; Reset enumerated (gbSysEnumerated) state,
; Turn off LED
; Reset variables
; Disable GPIO and EP1
; Disable dallas chip and P0 and P1
;********************************************************
USBEventEP0SetupSetConfig:
; Enumerated !
; Write a 0 to the LED on P13 to turn it on
mov a,~(LED_ON)
iowr SysPort1
mov a,10h
iowr USBEndP1TxConfig;NAK
; enable all appropriate irq's
mov a,SysIntTimer1024us | SysIntGPIO | SysIntUSBEndP0 | SysIntUSBEndP1
mov [gbSysInterruptMask],a
; Send ACK
call USBSendACK
jmp USBEventEP0End
;//$PAGE
;********************************************************
; USBEventEP0SetupGetDescriptor()
; @func End point zero event SETUP to Get Descriptor.
; @devnote Runs in interrupt enabled context.
;********************************************************
USBEventEP0SetupGetDescriptor:
; Get descriptor type
mov a,[USBRqstWordValueHi]
USBEventEP0SetupGetDescriptorDevice:
; Device Descriptor?
cmp a,USBDescriptorTypeDevice
jnz USBEventEP0SetupGetDescriptorConfig ; No
;*********************************************
; Get Device Descriptor Event
;*********************************************
; Descriptor pointer
mov a,(USBDeviceDescription -USBSendROMBufferBase)
mov [gbUSBSendBuffer],a
; Descriptor size
mov a,12h ;[USBDeviceDescription]
mov [gbUSBSendBytes],a
; Check request size field
call USBSendDescriptorCheckLength
; Send buffer
call USBSendROMBuffer
jmp USBEventEP0End
USBEventEP0SetupGetDescriptorConfig:
; Configuration Descriptor?
cmp a,USBDescriptorTypeConfig
jnz USBEventEP0SetupGetDescriptorString ; No
;*********************************************
; Get Configuration Descriptor Event
;*********************************************
; Descriptor pointer
mov a,(USBConfigurationDescription -USBSendROMBufferBase)
mov [gbUSBSendBuffer],a
; Descriptor size
mov a,09h ;[USBConfigurationDescription]
add a,09h ;[USBInterfaceDescription]
add a,07h ;[USBEndPointDescriptionInt]
mov [gbUSBSendBytes],a
; Check request size field
call USBSendDescriptorCheckLength
; Send buffer
call USBSendROMBuffer
jmp USBEventEP0End
USBEventEP0SetupGetDescriptorString:
; Get String Descriptor?
cmp a,USBDescriptorTypeString
jnz USBEventEP0SetupGetDescriptorEnd ; No
;*********************************************
; Get String Descriptor Event
;*********************************************
; Get string descriptor index
mov a,[USBRqstWordValueLo]
USBEventEP0SetupGetDescriptorString0:
cmp a,0h
jnz USBEventEP0SetupGetDescriptorString1 ; No
;*********************************************
; Get String Language(s) Descriptor Event
;*********************************************
; Descriptor pointer
mov a,(USBStringLanguageDescription -USBSendROMBufferBase)
mov [gbUSBSendBuffer],a
; Descriptor size
mov a,4h ;[USBStringLanguageDescription]
mov [gbUSBSendBytes],a
; Check request size field
call USBSendDescriptorCheckLength
; Send buffer
call USBSendROMBuffer
jmp USBEventEP0End
USBEventEP0SetupGetDescriptorString1:
cmp a,1
jnz USBEventEP0SetupGetDescriptorString2 ; No
;*********************************************
; Get String 1 Descriptor Event
;*********************************************
; Descriptor pointer
mov a,(USBStringDescription1 -USBSendROMBufferBase)
mov [gbUSBSendBuffer],a
; Descriptor size
mov a,10h ;[USBStringDescription1]
mov [gbUSBSendBytes],a
; Check request size field
call USBSendDescriptorCheckLength
; Send buffer
call USBSendROMBuffer
jmp USBEventEP0End
USBEventEP0SetupGetDescriptorString2:
cmp a,2
jnz USBEventEP0SetupGetDescriptorString3 ; No
;*********************************************
; Get String 2 Descriptor Event
;*********************************************
; Descriptor pointer
mov a,(USBStringDescription2 -USBSendROMBufferBase)
mov [gbUSBSendBuffer],a
; Descriptor size
mov a,10h ;[USBStringDescription2]
mov [gbUSBSendBytes],a
; Check request size field
call USBSendDescriptorCheckLength
; Send buffer
call USBSendROMBuffer
jmp USBEventEP0End
USBEventEP0SetupGetDescriptorString3:
cmp a,3
jnz USBEventEP0SetupGetDescriptorString4 ; No
;*********************************************
; Get String 3 Descriptor Event
;*********************************************
; Descriptor pointer
mov a,(USBStringDescription3 -USBSendROMBufferBase)
mov [gbUSBSendBuffer],a
; Descriptor size
mov a,0Ah ;[USBStringDescription3]
mov [gbUSBSendBytes],a
; Check request size field
call USBSendDescriptorCheckLength
; Send buffer
call USBSendROMBuffer
jmp USBEventEP0End
USBEventEP0SetupGetDescriptorString4:
cmp a,4
jnz USBEventEP0SetupGetDescriptorString5 ; No
;*********************************************
; Get String 4 Descriptor Event
;*********************************************
; Descriptor pointer
mov a,(USBStringDescription4 -USBSendROMBufferBase)
mov [gbUSBSendBuffer],a
; Descriptor size
mov a,28h ;[USBStringDescription4]
mov [gbUSBSendBytes],a
; Check request size field
call USBSendDescriptorCheckLength
; Send buffer
call USBSendROMBuffer
jmp USBEventEP0End
USBEventEP0SetupGetDescriptorString5:
cmp a,5
jnz USBEventEP0SetupGetDescriptorEnd ; No
;*********************************************
; Get String 5 Descriptor Event
;*********************************************
; Descriptor pointer
mov a,(USBStringDescription5 -USBSendROMBufferBase)
mov [gbUSBSendBuffer],a
; Descriptor size
mov a,3Eh ;[USBStringDescription5]
mov [gbUSBSendBytes],a
; Check request size field
call USBSendDescriptorCheckLength
; Send buffer
call USBSendROMBuffer
jmp USBEventEP0End
USBEventEP0SetupGetDescriptorEnd:
; Unsupported Get request !!!
jmp USBEventEP0Stall
;//$PAGE
;********************************************************
; USBSendDescriptorCheckLength()
; @func Check and update send length for Get Descriptor
; requests on end point 0.
; @parm BYTE | gbUSBSendBytes | Number of bytes to send.
;********************************************************
USBSendDescriptorCheckLength:
; High byte set? (Assume <255 bytes)
mov a,[USBEndP0FIFO_7]
cmp a,0
jnz USBSendDescriptorCheckLengthEnd ; Yes
; Check size
mov a,[USBEndP0FIFO_6]
cmp a,[gbUSBSendBytes]
jz USBSendDescriptorCheckLengthEnd ; equal
jnc USBSendDescriptorCheckLengthEnd ; greater than
; New size
mov [gbUSBSendBytes],a
USBSendDescriptorCheckLengthEnd:
ret
;//$PAGE
;********************************************************
; USBSendROMBuffer()
; @func Send a number of ROM bytes on end point 0.
; @parm BYTE | gbUSBSendBytes | Number of bytes to send.
; @parm BYTE | gbUSBSendBuffer | Offset from ROM base
; of data to send.
; @comm assumes IN packets are ignored in the interrupt routine
; @devnote Enables interrupts
;********************************************************
USBSendROMBuffer:
; Clear flag
mov a,0h
iowr USBEndP0RxStatus
; Enable interrupts
mov a,[gbSysInterruptMask]
and a,~SysIntUSBEndP0
iowr SysInterrupt
; Auto ACK OUT packet (This would be a Status Out)
mov a,USBControlAckStatusData
iowr USBControl
; Initialize sequence
mov a,0h
mov [gbUSBSendSequence],a
; Send count
mov a,[gbUSBSendBytes]
USendROMBufferLoop:
; One 8-byte chunk or less left?
cmp a,08h
jz USendROMBufferLoopDone ; exactly 8 bytes left, branch
jc USendROMBufferLoopDone ; less than 8 bytes left, branch
; more than 8 bytes left, fall through and loop
; until there are 8 bytes or less.
; Save count
push a
; Send 8 byte chunk
mov a,08h
mov [gbUSBSendBytes],a
call _USBSendROMBuffer
; Check for OUT packet cancelling send
iord USBEndP0RxStatus
and a,USBEndP0RxOut
; Restore count
pop a
; Handle exception: OUT packet cancel send
jnz USendROMBufferLoopExit ; Cancelled
; Save bytes left
sub a,08h
mov [gbUSBSendBytes],a
jmp USendROMBufferLoop
USendROMBufferLoopDone:
; Send last 8 or less bytes
call _USBSendROMBuffer
USendROMBufferLoopExit:
ret
;//$PAGE
;********************************************************
; _USBSendROMBuffer()
; @func Buffer and inialize USB send of up
; to 8 bytes of ROM data on end point 0.
; @comm affects gbUSBSendBytes &amt; gbUSBSendBuffer
;********************************************************
_USBSendROMBuffer:
; Save x
push x
; Initialize
mov x,0h
_USendROMBufferLoop:
; Any more?
mov a,0h
cmp a,[gbUSBSendBytes]
jz _USendROMBufferLoopDone ; No more
dec [gbUSBSendBytes]
; Move bytes to FIFO
mov a,[gbUSBSendBuffer]
index USBSendROMBufferBase
mov [x +USBEndP0FIFO],a
inc x
; Next byte
inc [gbUSBSendBuffer]
jmp _USendROMBufferLoop
_USendROMBufferLoopDone:
; Re-enable reception
mov a,0h
iowr USBEndP0RxStatus
; Toggle sequence
mov a,USBEndP0TxSequence
xor [gbUSBSendSequence],a
; Send bytes
push x
pop a
or a,[gbUSBSendSequence]
or a,USBEndP0TxRespond
iowr USBEndP0TxConfig
; The FIFO is loaded, go and wait untill it's read
call USBSendWaitForComplete
_USendROMBufferEnd:
; Restore and exit
pop x
ret
;//$PAGE
;********************************************************
; USBSendACK()
; func Respond to a "USB Status In" with a zero byte buffer with
; Sequence field set) on end point 0.
; Called by SetAddress and SetConfig commands
;********************************************************
USBSendACK:
; Status response to Status In is to send a zero byte packet
mov a,USBEndP0TxRespond | USBEndP0TxSequence
iowr USBEndP0TxConfig
; Enable interrupts
mov a,[gbSysInterruptMask]
iowr SysInterrupt
; Wait for send complete
jmp USBSendWaitForComplete
;********************************************************
; USBSendWaitForComplete()
; @func Wait for send to complete on end point 0.
;********************************************************
; At some point, either the 0 data will be ACK'd or a SETUP
; will come in.
; Either event will cause the "Enable Respond
; to In Packets" to be reset, and we will fall out of the loop.
; In either case, an EP0 IRQ will be generated (5.9.2.2 in Cyp
; device spec) if EP0 irq is enabled.
USBSendWaitForComplete:
; Poll the send complete bit
; This will be reset when the data has been sent to the host
; and the host has ACK's, or the host has sent another SETUP
; which should terminate this activity in any case.
iord USBEndP0TxConfig
and a,USBEndP0TxRespond
jz USBSendWaitComplete
; Check for OUT packet cancelling send. A STATUS OUT should
; terminate any pending IN's. A Setup could also set the Out bit.
iord USBEndP0RxStatus
and a,USBEndP0RxOut
jnz USBSendWaitComplete ; Cancelled
; Keep waiting
jmp USBSendWaitForComplete
USBSendWaitComplete:
ret
;********************************************************
; USBEventEP0VendorRqst()
; @func Vendor request on end point zero.
; @devnote Runs in interrupt disabled context.
;********************************************************
USBEventEP0VendorRqst:
; Save it
push x
; Check Protocol
mov a,[USBEndP0FIFO_1]
cmp a,0h
jnz USBEventEP0Stall ; No
;*********************************************
; Reset Counter Event
;*********************************************
; Initialize Counter
mov a,0
mov [gbButtonClicks],a ; Initial state of 0, no button pushed
mov [USBEndP1FIFO_0],a
iord USBEndP1TxConfig
and a,40h
or a,91h
iowr USBEndP1TxConfig
;USBEventEP0VendorRqstFinish:
; Protocol ACK
mov a,42h
mov [USBEndP0FIFO_0],a
; Auto ACK OUT packet
mov a,USBControlAckStatusData
iowr USBControl
; Send bytes as Data1
mov a,8
or a,USBEndP0TxSequence
or a,USBEndP0TxRespond
iowr USBEndP0TxConfig
;call USBSendWaitForComplete
; Restore it
pop x
; Return
jmp USBEventEP0End
;********************************************************
; Data Segment (ROM)
;********************************************************
USBSendROMBufferBase:
USBDeviceDescription:
db 12h ; Length
db 01h ; Type (1=device)
db 10h,01h ; Complies to USB Spec. v1.10
db 00h ; Class code (0=??)
db 00h ; SubClass code (0=??)
db 00h ; Protocol (0=none)(9.6.1)
db 08h ; Max. packet size for port0
db 34h,12h ; Vendor ID: (0x1234=WahBook)
db 78h,56h ; Product ID (0x01=USB Counter)
db 00h,01h ; Device release v1.00
db 01h ; Manufacturer string descriptor index (0=none)
db 02h ; Product string descriptor index (0=none)
db 03h ; Serial number string descriptor index (0=none)
db 01h ; Number of possible configurations
USBDeviceDescriptionEnd:
;*************************************************
;
USBConfigurationDescription:
db 09h ; Length
db 02h ; Type (2=config)
db 19h,00h ; Total data length (1 config,1 interface,1 endpoints)
db 01h ; Interface supported (1=???)
db 01h ; Configuration value (1=???)
db 04h ; Confituration string descriptor index (0=none)
db 80h ; Configuration (bus powered)
db 32h ; Maximum power consumption in 2mA units
USBConfigurationDescriptionEnd:
;*************************************************
;
USBInterfaceDescription:
db 09h ; Length
db 04h ; Type (4=interface)
db 00h ; Number of interfaces (0 based)
db 00h ; Alternate settings
db 01h ; Number of endpoints (1 based) (9.6.3)
db 00h ; Class code (0=non-specified,1=kb,2=mouse,3=joystick ???)
db 00h ; Subclass code (0=???)
db 00h ; Protocol code (0=non-specified)
db 05h ; Interface string index (0=non-specified, 1,2,3,...)
USBInterfaceDescriptionEnd:
;*************************************************
; Never used for EP0
USBEndPointDescriptionInt:
db 07h ; Length
db 05h ; Type (5=endpoint)
db 81h ; Address (EP#=1 | [0x80=IN, 0=OUT])
db 03h ; Attribute (0=control,1=isochronous,2=bulk,3=interrupt)
db 08h,00h ; Max packet size
db B8h ; Interval (200 ms)
USBEndPointDescriptionIntEnd:
;*************************************************
;
USBStringLanguageDescription:
db 04h ; Length
db 03h ; Type (3=string)
db 09h ; Language: English
db 01h ; Sub-language: US
USBStringDescription1:
db 10h ; Length
db 03h ; Type (3=string)
dsu "WAHBOOK"
USBStringDescription2:
db 10h ; Length
db 03h ; Type (3=string)
dsu "Counter"
USBStringDescription3:
db 0Ah ; Length
db 03h ; Type (3=string)
dsu "0001"
USBStringDescription4:
db 28h ; Length
db 03h ; Type (3=string)
dsu "Count Button Clicks"
USBStringDescription5:
db 3Eh ; Length
db 03h ; Type (3=string)
dsu "EndPoint1 200ms Interrupt Pipe"