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

📄 usbjoy32.asm

📁 HID规范和一个基于CYPRESS FX2 的例子
💻 ASM
📖 第 1 页 / 共 4 页
字号:
        iowr Global_Interrupt   

	jmp TaskLoop

;========================================
;	Task 14: Read Resistor Value for z_R2
;========================================

Task14:

	mov a, 30h
        iowr Global_Interrupt		;Enable only Capture interrupts

     ;**********************************************
     ;P0.0 = CMOS Hi-Z
     ;P0.1 = TTL Hi-Z
     ;P0.5 = High Sink
     ;P0.2/P0.3/P0.4/P0.6/P0.7 = CMOS Hi-Z
     ;Port0_Mode0 = 10000000
     ;Port0_Mode1 = 10000000
     ;Port0       = 00000010
     ;**********************************************
        mov a, 80h			;Set port and port mode values to discharge capacitor
        iowr Port0_Mode0		;See table above
        iowr Port0_Mode1
        mov a, 02h
        iowr Port0
        
	mov a, 00h			;wait about 500usec (6000 cycles) for Capture_timer A & B ISRs, then recharge cap and do math below
	mov [discharge_cnt], a
	.discharge_loop:
	    inc [discharge_cnt]
	    mov a, CCh
	    cmp a, [discharge_cnt]
	    iowr Watchdog
	    jnz .discharge_loop 

	mov a, 00h
	iowr Global_Interrupt		;Disable global interrupts

	mov a, 00h
	mov [rollover_bit], a		;rollover_bit set to 00h, but may need to change to 01h, if TTL value is < CMOS value

	iord Capture_TimerA_Falling	;Read CaptureTimerA 8 bits, CMOS captured time value (always earlier and usually the smaller value)
	mov [capture_a_temp], a
	iord Capture_TimerB_Falling	;Read CaptureTimerB 8 bits, TTL captured time value (always earlier and usually the larger value)
	mov [capture_b_temp], a

	sub a, [capture_a_temp]		;Subtract CMOS time from TTL time to see if timer rolled over
	jnc .no_timer_rollover		;If TTL value is > CMOS value, the timer did not roll over and we keep rollover_bit = 00h

	mov a, 01h			;In the exception that TTL time value is < CMOS time value, we make rollover_bit = 01h
	mov [rollover_bit], a	
	
	.no_timer_rollover:
        mov a, FEh			;Recharges the capacitor, P0.0 is Hi-Z CMOS always, others set to Strong Drive CMOS
        iowr Port0_Mode0
        iowr Port0_Mode1
        iowr Port0    
                
	SUB16x16 rollover_bit, capture_b_temp, 00h, capture_a_temp, always_zero, z_R2_diff2_new

	; perform calculations to average the joystick readings (R_1st + R_2nd)/2

	AVERAGE8x8 z_R1_diff1_new, z_R1_diff2_new, z_R1_diff1_old, z_R1_diff2_old, RunningCarry, RunningSum, z_R1_average
	AVERAGE8x8 z_R2_diff1_new, z_R2_diff2_new, z_R2_diff1_old, z_R2_diff2_old, RunningCarry, RunningSum, z_R2_average

	; perform calculations below to average and normalize the joystick position for more accuracy (R1*256)/(R1+R2)

	ADD8x8wCarry z_R1_average, z_R2_average, divider_bottom_hi, divider_bottom_lo, z_R12_Sum_MSB,  z_R12_Sum_LSB
	mov a, [z_R1_average]		;Top of division equation gets R1, then it is "multiplied" by 256
	mov [divider_top_hi], a
	mov a, 00h
	mov [divider_top_lo], a		;This is the LSByte of R1 in div equation, effectively "multiplies" it by 256
	DIV16x16 divider_bottom_hi, divider_bottom_lo, divider_top_hi, divider_top_lo	; (R1*256)/(R1+R2)
	mov a, [divider_top_lo]		; this is actually the joystick z position
	mov [z_position], a

        mov a, 05h          		;Re-Enable 1ms,USBReset interrupts
        iowr Global_Interrupt   

	jmp TaskLoop

;==========================================================
;	Task 15:
;
;	Fill endpoint buffer FIFO with Axis & button data
;==========================================================

Task15:

	mov a, [00h]		; Fill endpoint buffer for sending to host
	mov [ep1_dmabuff+0], a
	mov a, [x_position]
	mov [ep1_dmabuff+1], a
	mov a, [00h]
	mov [ep1_dmabuff+2], a
	mov a, [y_position]
	mov [ep1_dmabuff+3], a
	mov a, [00h]
	mov [ep1_dmabuff+4], a
	mov a, [z_position]
	mov [ep1_dmabuff+5], a
	mov a, [hat_buttons]
	mov [ep1_dmabuff+6], a
	mov a, [fire_buttons] 
	mov [ep1_dmabuff+7], a

	mov a, [x_R1_diff1_new]		;move new X resitor values to old X values for next calculations
	mov [x_R1_diff1_old], a				
	mov a, [x_R2_diff1_new]
	mov [x_R2_diff1_old], a				
	mov a, [x_R1_diff2_new]
	mov [x_R1_diff2_old], a				
	mov a, [x_R2_diff2_new]
	mov [x_R2_diff2_old], a
				
	mov a, [y_R1_diff1_new]		;move new Y resitor values to old Y values for next calculations
	mov [y_R1_diff1_old], a				
	mov a, [y_R2_diff1_new]
	mov [y_R2_diff1_old], a				
	mov a, [y_R1_diff2_new]
	mov [y_R1_diff2_old], a				
	mov a, [y_R2_diff2_new]
	mov [y_R2_diff2_old], a
				
	mov a, [z_R1_diff1_new]		;move new Z resitor values to old Z values for next calculations
	mov [z_R1_diff1_old], a				
	mov a, [z_R2_diff1_new]
	mov [z_R2_diff1_old], a				
	mov a, [z_R1_diff2_new]
	mov [z_R1_diff2_old], a				
	mov a, [z_R2_diff2_new]
	mov [z_R2_diff2_old], a				

	mov 	A, [ep1_data_toggle]		; preserve data toggle bit
	or 	A, 08h				; send back 8 words to host
	iowr 	Ep1_Count
	
        mov 	a, ACK_IN			;Set to ack on endpoint 1
        iowr 	Ep1_Mode	    		;USB mode is ACK in - Status Out, data is ready, send it to host

	jmp 	TaskLoop


;*******************************************************
;
;	Interrupt handler: BusResetISR
;	Purpose: The program jumps to this routine when
;		   the microcontroller has a bus reset.
;
;*******************************************************

BusResetISR:
	; At this point, endpoint 0 does not expect any packet except a SETUP. 
	; Set endpoint 0 mode to STALL INs&OUTs.
	mov		A, STALL_IN_OUT		
	iowr		Ep0_Mode

	; Enable USB address 0. If not enabled, the device's SIE does not respond
	; to USB traffic sent to the device's address.
	mov		A, ADDRESS_ENABLE		
	iowr		Usb_Address
	
	; At this point, data endpoints (endpoint 1/or 2) does not respond to any 
	; USB traffic. A SetConfiguation at the end of the enumeration will enable the endpoint.
	mov		A, DISABLE				
	iowr		Ep1_Mode

	; Bus Reset is an interrupt. Upon entering the BusResetISR, the hardware 
	; automatically pushes the pc onto the psp. The "reti" or "ret" instruction at the end
	; of the ISR will "pop" the pc back. In this case, the BusResetISR does not
	; perform a "reti" but a "jmp" to the "Reset" vector. Therefore, firmware must reset 
	; program stack pointer to clear the 2 bytes pc that the hardware "pushes" on the psp.
	mov		A, 00h
	mov		psp,a

	jmp		Reset


;*******************************************************
;
;	Interrupt handler: 1msTimerISR
;	Purpose: Every 1ms this interrupt handler clears
;		   the Watchdog timer. If there's no bus
;              activity for 3-4ms. This ISR puts the 
;              microcontroller into suspend mode.
;
;*******************************************************

1msTimerISR:

  push A

  ; clear Watchdog timer
  iowr Watchdog

  ; Clear [new_task] to zero to flag the main program loop (TaskLoop) that
  ; the 1ms time slice for the current task has been used up. Go execute 
  ; the next task. 
  mov a, 00h						
  mov [new_task], a
  
  ; Each task is allocated 1ms. Every 1ms, the firmware increases [task_number] to
  ; tell the main loop what the next task is.
  inc [task_number]
						
  ; check for no bus activity. Increase [suspend_count] if there's no bus activity since 
  ; the last 1ms interrupt. The main loop will put the part into suspend if [suspend_count]==4.

  1ms_suspend_timer:
	iord	Usb_Status_Control			; 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_Interrupt

  		iord		Processor_Status_Control
  		or		A, SUSPEND		; set suspend bit
 		ei
 		iowr		Processor_Status_Control
 		nop

		; look for bus activity, if none go back into suspend
		iord	Usb_Status_Control
		and		A, BUS_ACTIVITY
		jz		usb_suspend		

		; re-enable interrupts
		mov		A, (1MS_INT | USB_RESET_INT)
		iowr 		Global_Interrupt

	bus_activity:

		mov		A, 00h			; reset suspend counter
		mov		[suspend_count], A
		iord		Usb_Status_Control
		and		A, ~BUS_ACTIVITY	; clear bus activity bit
		iowr		Usb_Status_Control

	ms_timer_done:
		pop A

		reti

;*******************************************************
;
;	Interrupt: Endpoint0ISR
;	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).
;
;*******************************************************

Endpoint0ISR:
	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
	call 		EP0IntHandler
	
  ep0_done:					;ParseSetup returns here. Exit ISR
	pop		A
	pop		X

	reti

;*******************************************************
;
;	Interrupt handler: endpoint1_ISR
;	Purpose: This interrupt routine handles the specially
;		 reserved data endpoint 1 (for a mouse).  This
;		 interrupt happens every time a host sends an
;		 IN on endpoint 1.  The data to send (NAK or 3
;		 byte packet) is already loaded, so this routine
;		 just prepares the dma buffers for the next packet
;
;*******************************************************

Endpoint1ISR:

	push	A

	iord    Ep1_Mode                ; if the interrupt was caused by a NAK, set the mode to NAK
	and     A, EP_ACK              	; and exit the isr.                                     
	jz      endpoint1_NAK
	
	; change data toggle
	mov	A, 80h
	xor	[ep1_data_toggle], A

	; set response
	mov	A, [ep1_stall]		; if endpoint is set to stall, then set
	cmp	A, FFh			; endpoint mode to stall
	jnz	endpoint1_NAK		; if not, set ep mode to NAK
	
	mov	A, STALL_IN_OUT
	iowr	Ep1_Mode
	jmp     endpoint1_done

	endpoint1_NAK:
        	mov     A, NAK_IN       ; clear the ACK bits
        	iowr    Ep1_Mode                

	endpoint1_done:
		pop		A

	reti


;*******************************************************
;
;	Interrupt handler: endpoint2_ISR
;	Purpose: This interrupt is not implemented in the 
;              frameworks.
;*******************************************************

Endpoint2ISR:

	reti

;*******************************************************
;
;	Interrupt handler: 128us_ISR
;	Purpose: This interrupt is not implemented in the 
;              frameworks.
;*******************************************************

128usTimerISR:

	reti


;*******************************************************
;
;	Interrupt handler: SPI_ISR
;	Purpose: This interrupt is not implemented in the 
;              frameworks.
;*******************************************************

SpiISR:

	reti

;*******************************************************
;
;	Interrupt handler: CaptureTimerAISR
;	Purpose: CMOS captured time related to cap discharge thru pot.
;*******************************************************

CaptureTimerAISR:		   ;This is the CMOS capture timer ISR
   
	reti

;*******************************************************
;
;	Interrupt handler: CaptureTimerBISR
;	Purpose: TTL captured time related to cap discharge thru pot.
;*******************************************************

CaptureTimerBISR:		    ;This is the TTL capture timer ISR
	mov a, 00h
	iowr Global_Interrupt	    ;Disable global interrupts

	reti

;*******************************************************
;
;	Interrupt handler: GpioISR
;	Purpose: This interrupt is not implemented in the 
;              frameworks.
;*******************************************************

GpioISR:

	reti

;*******************************************************
;
;	Interrupt handler: wake_up_ISR
;	Purpose: This interrupt is not implemented in the 
;              frameworks.
;*******************************************************

WakeUpISR:

	reti

INCLUDE	"EP0IntHandler.asm"
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -