📄 enchid.asm
字号:
;******************************************************
;
;File: encorhid.asm
;adapted from Cypress Semiconductor's logo.asm by Jan Axelson
;Date: 02/19/2001
;Chip: Cypress Semiconductor CY7C637xx Encore series USB Microcontroller
;Assembler: cyasm.exe
;Purpose: demonstrates USB communications with a HID-class device
;Description:
;Handles standard USB and HID-class requests.
;Receives data from the host in Output reports
;using interrupt transfers on Endpoint 1.
;Sends data to the host in Input reports
;using control transfers on Endpoint 0.
;I used Cypress Semiconductor's logo.asm example code as a base
;in creating this program.
;The companion host software is the Visual-Basic project usbhidio.vbp
;or the Visual C++ project usbhidioc.
;For more information, visit Lakeview Research at http://www.lvr.com .
;Send comments, bug reports, etc. to jan@lvr.com .
;2/19/2001
;Changed endpoint 1 ISR so it doesn't toggle the data toggle on NAK.
; Target: Cypress CY7C63743
;
; Overview: There is only one task handled by this
; firmware, and that is USB.
;
; USB
; At bus reset the USB interface is re-initialized,
; and the firmware soft reboots. We are then able to
; handle the standard chapter nine requests on
; endpoint zero (the control endpoint). After this
; device enumerates as a HID mouse on the USB, the
; requests come to endpoint one (the data endpoint).
; Endpoint one is used to send Input reports.
; Endpoint zero is used to receive Output reports
; in Set_Report requests.
;
; Pin Connections
;
; -------------------
; | P0[0] P0[4] |
; | P0[1] P0[5] |
; | P0[2] P0[6] |
; | P0[3] P0[7] |
; | P1[0] P1[1] |
; | P1[2] P1[3] |
; | P1[4] P1[5] |
; | P1[6] P1[7] |
; GND | VSS D+/SCLK | USB D+ / PS2 SCLK
; GND | VPP D-/SDATA| USB D- / PS2 SDATA
; PULLUP | VREG VCC | +5
; | XTALIN XTALOUT |
; -------------------
;
; Revisions:
; 9-25-2000 Creation
;
;To do (things to be added):
;Add ability to send and receive Feature reports.
;Add ability to receive Output reports > 8 bytes.
;Add ability to receive interrupt Out reports.
;Move watchdog reset out of 1-ms timer routine.
;
;**********************************************************
;
; Copyright 2000 Cypress Semiconductor and Lakeview Research
; Portions of this code are provided by Cypress and by
; Lakeview Research as a reference. Cypress and Lakeview
; make no claims or warranties to this firmware's
; suitability for any application.
;
;**********************************************************
;**************** assembler directives *****************
CPU 63743
XPAGEON
INCLUDE "637xx.inc"
INCLUDE "USB.inc"
ep1_dmabuff: equ F0h
ep1_dmabuff0: equ ep1_dmabuff+0
ep1_dmabuff1: equ ep1_dmabuff+1
ep1_dmabuff2: equ ep1_dmabuff+2
ep1_dmabuff3: equ ep1_dmabuff+3
ep1_dmabuff4: equ ep1_dmabuff+4
ep1_dmabuff5: equ ep1_dmabuff+5
ep1_dmabuff6: equ ep1_dmabuff+6
ep1_dmabuff7: equ ep1_dmabuff+7
ep0_dmabuff: equ F8h
ep0_dmabuff0: equ ep0_dmabuff+0
ep0_dmabuff1: equ ep0_dmabuff+1
ep0_dmabuff2: equ ep0_dmabuff+2
ep0_dmabuff3: equ ep0_dmabuff+3
ep0_dmabuff4: equ ep0_dmabuff+4
ep0_dmabuff5: equ ep0_dmabuff+5
ep0_dmabuff6: equ ep0_dmabuff+6
ep0_dmabuff7: equ ep0_dmabuff+7
bmRequestType: equ ep0_dmabuff0
bRequest: equ ep0_dmabuff1
wValuelo: equ ep0_dmabuff2
wValuehi: equ ep0_dmabuff3
wIndexlo: equ ep0_dmabuff4
wIndexhi: equ ep0_dmabuff5
wLengthlo: equ ep0_dmabuff6
wLengthhi: equ ep0_dmabuff7
; DATA MEMORY VARIABLES
;
suspend_count: equ 20h ; counter for suspend/resume
ep1_data_toggle: equ 21h ; data toggle for INs on endpoint one
ep0_data_toggle: equ 22h ; data toggle for INs on endpoint zero
data_start: equ 23h ; address of request response data, as an offset
data_count: equ 24h ; number of bytes to send back to the host
maximum_data_count: equ 25h ; request response size
ep0_in_machine: equ 26h
ep0_in_flag: equ 27h
configuration: equ 28h
ep1_stall: equ 29h
idle: equ 2Ah
protocol: equ 2Bh
temp: equ 2Ch ; temporary register
event_machine: equ 2Dh
pending_data: equ 2Eh
int_temp: equ 2Fh
idle_timer: equ 30h
idle_prescaler: equ 31h
logo_index: equ 32h
ep0_transtype: equ 33h
data_byte_0: equ 34h
data_byte_1: equ 35h
; STATE MACHINE CONSTANTS
;EP0 IN TRANSACTIONS
EP0_IN_IDLE: equ 00h
CONTROL_READ_DATA: equ 02h
NO_DATA_STATUS: equ 04h
EP0_IN_STALL: equ 06h
; FLAG CONSTANTS
;EP0 NO-DATA CONTROL FLAGS
ADDRESS_CHANGE_PENDING: equ 00h
NO_CHANGE_PENDING: equ 02h
; RESPONSE SIZES
DEVICE_STATUS_LENGTH: equ 2
DEVICE_CONFIG_LENGTH: equ 1
ENDPOINT_STALL_LENGTH: equ 2
INTERFACE_STATUS_LENGTH: equ 2
INTERFACE_ALTERNATE_LENGTH: equ 1
INTERFACE_PROTOCOL_LENGTH: equ 1
NO_EVENT_PENDING: equ 00h
EVENT_PENDING: equ 02h
;***** TRANSACTION TYPES
TRANS_NONE: equ 00h
TRANS_CONTROL_READ: equ 02h
TRANS_CONTROL_WRITE: equ 04h
TRANS_NO_DATA_CONTROL: equ 06h
;Additional notes:
;ep0_mode is the Endpoint 0 mode register (12h).
;*************** interrupt vector table ****************
ORG 00h
jmp reset ; reset vector
jmp bus_reset ; bus reset interrupt
jmp error ; 128us interrupt
jmp 1ms_timer ; 1.024ms interrupt
jmp endpoint0 ; endpoint 0 interrupt
jmp endpoint1 ; endpoint 1 interrupt
jmp error ; endpoint 2 interrupt
jmp error ; reserved
jmp error ; Capture timer A interrupt Vector
jmp error ; Capture timer B interrupt Vector
jmp error ; GPIO interrupt vector
jmp error ; Wake-up interrupt vector
;************** program listing ************************
ORG 1Ah
error: halt
;*******************************************************
;
; Interrupt handler: reset
; Purpose: The program jumps to this routine when
; the microcontroller has a power on reset.
;
;*******************************************************
reset:
; set for use with external oscillator
mov A, (LVR_ENABLE | EXTERNAL_CLK)
iowr clock_config
; setup data memory stack pointer
mov A, 68h
swap A, dsp
; clear variables
mov A, 00h
mov [ep0_in_machine], A ; clear ep0 state machine
mov [configuration], A
mov [ep1_stall], A
mov [idle], A
mov [suspend_count], A
mov [ep1_dmabuff0], A
mov [ep1_dmabuff1], A
mov [ep1_dmabuff2], A
mov [int_temp], A
mov [idle_timer], A
mov [idle_prescaler], A
mov [event_machine], A
mov [logo_index], A
mov [ep0_transtype], A
mov A, 01h
mov [protocol], A
; enable global interrupts
mov A, (1MS_INT | USB_RESET_INT)
iowr global_int
; enable endpoint 0 interrupt
mov A, EP0_INT
iowr endpoint_int
; enable USB address for endpoint 0
mov A, ADDRESS_ENABLE
iowr usb_address
; enable all interrupts
ei
; enable USB pullup resistor
mov A, VREG_ENABLE
iowr usb_status
task_loop:
mov A, [event_machine]
jacc event_machine_jumptable
no_event_pending:
; if not configured then skip data transfer
mov A, [configuration]
cmp A, 01h
jnz no_event_task
; if stalled then skip data transfer
mov A, [ep1_stall]
cmp A, FFh
jz no_event_task
mov A, 02h ; set endpoint 1 to send 2 bytes
or A, [ep1_data_toggle]
iowr ep1_count
mov A, ACK_IN ; set to ack on endpoint 1
iowr ep1_mode
mov A, EVENT_PENDING ; clear pending events
mov [event_machine], A
event_task_done:
no_event_task:
jmp task_loop
;*******************************************************
;
; Interrupt handler: bus_reset
; Purpose: The program jumps to this routine when
; the microcontroller has a bus reset.
;
;*******************************************************
bus_reset:
mov A, STALL_IN_OUT ; set to STALL INs&OUTs
iowr ep0_mode
mov A, ADDRESS_ENABLE ; enable USB address 0
iowr usb_address
mov A, DISABLE ; disable endpoint1
iowr ep1_mode
mov A, 00h ; reset program stack pointer
mov psp,a
jmp reset
;*******************************************************
;
; Interrupt: 1ms_clear_control
; Purpose: Every 1ms this interrupt handler clears
; the watchdog timer.
;
;*******************************************************
1ms_timer:
push A
; clear watchdog timer
iowr watchdog
; check for no bus activity/usb suspend
1ms_suspend_timer:
iord usb_status ; read bus activity bit
and A, BUS_ACTIVITY ; mask off activity bit
jnz bus_activity
inc [suspend_count] ; increment suspend counter
mov A, [suspend_count]
cmp A, 04h ; if no bus activity for 3-4ms,
jz usb_suspend ; then go into low power suspend
jmp ms_timer_done
usb_suspend:
; enable wakeup timer
mov A, (USB_RESET_INT)
iowr global_int
iord control
or A, SUSPEND ; set suspend bit
ei
iowr control
nop
; look for bus activity, if none go back into suspend
iord usb_status
and A, BUS_ACTIVITY
jz usb_suspend
; re-enable interrupts
mov A, (1MS_INT | USB_RESET_INT)
iowr global_int
bus_activity:
mov A, 00h ; reset suspend counter
mov [suspend_count], A
iord usb_status
and A, ~BUS_ACTIVITY ; clear bus activity bit
iowr usb_status
ms_timer_done:
pop A
reti
;*******************************************************
;
; Interrupt: endpoint0
; Purpose: Usb control endpoint handler. This interrupt
; handler formulates responses to SETUP and
; CONTROL READ, and NO-DATA CONTROL transactions.
;
; Jump table entry formulation for bmRequestType and bRequest
;
; 1. Add high and low nibbles of bmRequestType.
; 2. Put result into high nibble of A.
; 3. Mask off bits [6:4].
; 4. Add bRequest to A.
; 5. Double value of A (jmp is two bytes).
;
;*******************************************************
endpoint0:
push X
push A
;Reading ep0_mode enables writing to the endpoint's buffer.
iord ep0_mode
;If EP0_ACK isn't set, the transaction didn't complete with an Ack,
;so exit the ISR.
and A, EP0_ACK
jz ep0_done
;Bit 5, 6, or 7 is set to indicate whether the transaction is
;Setup, In, or Out. Find out which it is and jump to a routine to handle it.
iord ep0_mode
asl A
jc ep0_setup_received
asl A
jc ep0_in_received
asl A
jc ep0_out_received
ep0_done:
pop A
pop X
reti
ep0_setup_received:
mov A, NAK_IN_OUT ; clear setup bit to enable
iowr ep0_mode ; writes to EP0 DMA buffer
mov A, [bmRequestType] ; compact bmRequestType into 5 bit field
and A, E3h ; clear bits 4-3-2, these unused for our purposes
push A ; store value
asr A ; move bits 7-6-5 into 4-3-2's place
asr A
asr A
mov [int_temp], A ; store shifted value
pop A ; get original value
or A, [int_temp] ; or the two to get the 5-bit field
and A, 1Fh ; clear bits 7-6-5 (asr wraps bit7)
asl A ; shift to index jumptable
;Use bmRequestType to find out whether the request is host-to-device (h2d)
;or device-to-host (d2h), and whether the request is for the device, an ;interface, or an endpoint.
jacc bmRequestType_jumptable ; jump to handle bmRequestType
;Use the request's value to decide where to jump.
;Shift left to double the request's value because the entries in the jumptable
;are two bytes each.
h2d_std_device:
mov A, [bRequest]
asl A
jacc h2d_std_device_jumptable
h2d_std_interface:
mov A, [bRequest]
asl A
jacc h2d_std_interface_jumptable
h2d_std_endpoint:
mov A, [bRequest]
asl A
jacc h2d_std_endpoint_jumptable
;I added this jump for set_report requests
h2d_class_interface:
mov A, [bRequest]
asl A
jacc h2d_class_interface_jumptable
d2h_std_device:
mov A, [bRequest]
asl A
jacc d2h_std_device_jumptable
d2h_std_interface:
mov A, [bRequest]
asl A
jacc d2h_std_interface_jumptable
d2h_std_endpoint:
mov A, [bRequest]
asl A
jacc d2h_std_endpoint_jumptable
;;************ DEVICE REQUESTS **************
set_device_address: ; SET ADDRESS
mov A, ADDRESS_CHANGE_PENDING ; set flag to indicate we
mov [ep0_in_flag], A ; need to change address on
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -