⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enchid.asm

📁 USB主控器固件程序源码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;******************************************************
;
;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 + -