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

📄 mjoy.asm

📁 用于AVR的USB
💻 ASM
📖 第 1 页 / 共 5 页
字号:
CheckUSBReset:
		ldi	temp0,255		;counter duration of reset (according to specification is that cca 10ms - here is cca 100us)
WaitForUSBReset:
		sbic	inputport,DATAminus	;waiting till change D+ to 0
		rjmp	Main
		dec	temp0
		brne	WaitForUSBReset
		rcall	USBReset
		rjmp	Main

ProcPrepareOutContinuousBuffer:
		rcall	PrepareOutContinuousBuffer	;prepare next sequence of answer to buffer
		ldi	ActionFlag,DoReadySendAnswer
		rjmp	Main
ProcReceiveSetupData:
		ldi	USBBufptrY,InputBufferBegin	;pointer to begin of receiving buffer
		mov	ByteCount,InputBufferLength	;length of input buffer
		rcall	DecodeNRZI		;transfer NRZI coding to bits
		rcall	MirrorInBufferBytes	;invert bits order in bytes
		rcall	BitStuff		;removal of bitstuffing
		;rcall	CheckCRCIn		;rcall	CheckCRCIn		;check CRC
		rcall	PrepareUSBOutAnswer	;prepare answers to transmitting buffer
		ldi	ActionFlag,DoReadySendAnswer
		rjmp	Main


;********************************************************************
;*  Joystick Initialization Routine
;********************************************************************

InitJoystickAxis:

		call	BackupUpperRegisters

		ldi r16, 0xFF
		sts	ADCChanStarted,r16	; reset last ADC  channel number

		ldi r16, XAxisChannel	;
		call ReadADC10
		ldi	ZH, high(XAxisRAM)	
		ldi	ZL,  low(XAxisRAM)
		ldi	YH, high(XAxisEE)	
		ldi	YL,  low(XAxisEE)
		call Init10SymAxis

		ldi r16, YAxisChannel	;
		call ReadADC10
		ldi	ZH, high(YAxisRAM)	
		ldi	ZL,  low(YAxisRAM)
		ldi	YH, high(YAxisEE)	
		ldi	YL,  low(YAxisEE)
		call Init10SymAxis

		ldi r16, RudderAxisChannel	;
		call ReadADC10
		ldi	ZH, high(RudderAxisRAM)	
		ldi	ZL,  low(RudderAxisRAM)
		ldi	YH, high(RudderAxisEE)	
		ldi	YL,  low(RudderAxisEE)
		call Init10SymAxis

		ldi	ZH, high(ThrottleAxisRAM)	
		ldi	ZL,  low(ThrottleAxisRAM)
		ldi	YH, high(ThrottleAxisEE)	
		ldi	YL,  low(ThrottleAxisEE)
		call Init8AsymAxis

		ldi	ZH, high(ZAxisRAM)	
		ldi	ZL,  low(ZAxisRAM)
		ldi	YH, high(ZAxisEE)	
		ldi	YL,  low(ZAxisEE)
		call Init8AsymAxis

		ldi	ZH, high(RxAxisRAM)	
		ldi	ZL,  low(RxAxisRAM)
		ldi	YH, high(RxAxisEE)	
		ldi	YL,  low(RxAxisEE)
		call Init8AsymAxis


		call RestoreUpperRegisters

		ret

;********************************************************************
;*  Joystick Calibration Ranges Update Routine
;********************************************************************
CheckAxisRanges:
		call	BackupUpperRegisters
		
; ----- check if some axis range was changed and is needed to be written to EEPROM
		ldi	ZH, high(XAxisRAM)	
		ldi	ZL,  low(XAxisRAM)
		ldi	YH, high(XAxisEE)	
		ldi	YL,  low(XAxisEE)
		call CheckAxisRangeUpdate
		breq CheckRangeEnd			; skip everything else if we have written to eeprom


		ldi	ZH, high(YAxisRAM)	
		ldi	ZL,  low(YAxisRAM)
		ldi	YH, high(YAxisEE)	
		ldi	YL,  low(YAxisEE)
		call CheckAxisRangeUpdate
		breq CheckRangeEnd


		ldi	ZH, high(RudderAxisRAM)	
		ldi	ZL,  low(RudderAxisRAM)
		ldi	YH, high(RudderAxisEE)	
		ldi	YL,  low(RudderAxisEE)
		call CheckAxisRangeUpdate
		breq CheckRangeEnd

		ldi	ZH, high(ThrottleAxisRAM)	
		ldi	ZL,  low(ThrottleAxisRAM)
		ldi	YH, high(ThrottleAxisEE)	
		ldi	YL,  low(ThrottleAxisEE)
		call CheckAxisRangeUpdate
		breq CheckRangeEnd

		ldi	ZH, high(ZAxisRAM)	
		ldi	ZL,  low(ZAxisRAM)
		ldi	YH, high(ZAxisEE)	
		ldi	YL,  low(ZAxisEE)
		call CheckAxisRangeUpdate
		breq CheckRangeEnd

		ldi	ZH, high(RxAxisRAM)	
		ldi	ZL,  low(RxAxisRAM)
		ldi	YH, high(RxAxisEE)	
		ldi	YL,  low(RxAxisEE)
		call CheckAxisRangeUpdate
		breq CheckRangeEnd

rjmp	CheckRangeEnd


CheckRangeEnd:
		call 	RestoreUpperRegisters
		ret

;*********************************************************************		
;* Check if axis range was updated and write updated values to EEPROM if needed
;*
;* Input: 	Z 		- Axis structure RAM address
;* 			Y		- Axis structure EEPROM address
;*
;* Registers used:
;*			r16, r17, Y, Z
;*********************************************************************

CheckAxisRangeUpdate:
		ldd r25, Z + s_UpdateCntH
		ldd r24, Z + s_UpdateCntL
		adiw	r25:r24,0	; just to set the flags
		breq	Ret10SARU	; if no update then return
		adiw	r25:r24,1	; increment update delay counter
		std Z + s_UpdateCntH, r25
		std Z + s_UpdateCntL, r24

		ldi	r19, high(UpdEEThd)
		ldi r18, low(UpdEEThd)
		cp	r24, r18			; check if value exceeds  MINIMUM range
		cpc	r25, r19
		brlo	Ret10SARU		; return if threshold not reached
		; reset the update counter to 0
		ldi	r16, 0
		std Z + s_UpdateCntL, r16	; store the 0
		std Z + s_UpdateCntH, r16

		cli		; disable interrupts
		; write axis structure to EEPROM
		movw	r19:r18, ZH:ZL 	; backup structure pointer
		adiw	ZH:ZL, s_EEPROMStructStart	; point to start of EEPROM part
		ldi	r17, Sym10EEStructSize
		call SaveStructToEEPROM
		sez		; set to mark that we have written to eeprom
		sei		;enable interrupts
		ret
Ret10SARU:
		clz		
		sei		;enable interrupts
		ret



;*********************************************************************		
;* Load structure from EEPROM to Data memory
;*
;* Input: 	Y 		- EEPROM address (source)
;*			Z 		- Data address (destination)
;*			r17		- Number of bytes to load
;* 
;*
;* Registers used:
;*			r16, r17, Y, Z
;*********************************************************************
LoadStructFromEEPROM:
			
		sbic EECR,EEWE	; Wait for completion of previous write ( if there was one)
		rjmp LoadStructFromEEPROM
		out	EEARL,YL		;set the address EEPROM Lo
		out	EEARH,YH		;set the address EEPROM Hi
		sbi	EECR,EERE		;read EEPROM to register EEDR
		in	R16,EEDR			;load from EEDR to R0
		st	Z+,R16			;R0 save to buffer and increment buffer
		adiw	YH:YL,1			;increment index to EEPROM
		dec	R17		;till are not all bytes
		brne	LoadStructFromEEPROM;then load next
		ret

;*******************************************************************		
; Save structure from Data memory to EEPROM
;
; Input: 	Y 		- EEPROM address (destination)
;			Z 		- Data address (source)
;			r17		- Number of bytes to save
; 
;
; Registers used:
;			r16, r17, Y, Z
;*********************************************************************
SaveStructToEEPROM:
		sbic EECR,EEWE		; Wait for completion of previous write
		rjmp SaveStructToEEPROM
		out	EEARL,YL		;set the address EEPROM Lo
		out	EEARH,YH		;set the address EEPROM Hi
		ld	R16, Z+			;load value from RAM to R16
		out EEDR,r16		; Write data (r16) to data register
		sbi EECR,EEMWE		; Write logical one to EEMWE
		sbi EECR,EEWE		; Start eeprom write by setting EEWE
		adiw	YH:YL,1			;increment index to EEPROM
		dec	R17				;till are not all bytes
		brne	SaveStructToEEPROM	;then load next
		ret




;********************************************************************
;*  Joystick Requests Processing Routine
;********************************************************************

ProcJoystickRequest:

		call BackupUpperRegisters
	; clear ready flag to avoid data conflict
		mov		temp0, JoystickFlags
		ldi		temp0,0xFF
		andi		temp0,~JoystickDataReady
		andi	temp0,~JoystickDataRequest ; clear request flag to avoid call on next cycle
		and		JoystickFlags,temp0 

		sbrc	JoystickFlags,JoystickReportIDBit
		rjmp	ProcessJoystickReport_2

ProcessJoystickReport_1:
		;save report ID
		ldi		temp0, 1
		sts		JoystickBufferBegin+2,temp0 

;;;;;;;;;;;;;;;;;;;;;;;;
; Read value from ADC X channel

		ldi		r18, XAxisChannel	; initiate ADC conversion for next axis
		rcall	StartADC10
		ldi		r16, XAxisChannel
		rcall	ReadADC10
		ldi		r18, YAxisChannel	; initiate ADC conversion for next axis
		rcall	StartADC10
		ldi	ZH, high(XAxisRAM)	
		ldi	ZL,  low(XAxisRAM)
		call Process10SymAxis

	; Store X value
		sts		JoystickBufferBegin+3,r16
		sts		JoystickBufferBegin+4,r17


;;;;;;;;;;;;;;;;;
; Read value from ADC Y channel
		ldi		r16, YAxisChannel
		rcall	ReadADC10
		ldi		r18, RudderAxisChannel	; initiate ADC conversion for next axis
		rcall	StartADC10
		ldi	ZH, high(YAxisRAM)	
		ldi	ZL,  low(YAxisRAM)
		call Process10SymAxis

	; shift for Y value
		lsl		r16
		rol		r17
		lsl		r16
		rol		r17
		lds		r18, JoystickBufferBegin+4 ; to combine with X
		or		r18, r16
		sts		JoystickBufferBegin+4,r18
		sts		JoystickBufferBegin+5,r17

;;;;;;;;;;;;;;;;;
; Read value from ADC Rudder channel
		ldi		r16, RudderAxisChannel
		rcall	ReadADC10
		ldi		r18, ThrottleAxisChannel	; initiate ADC conversion for next axis
		rcall	StartADC10
		ldi	ZH, high(RudderAxisRAM)	
		ldi	ZL,  low(RudderAxisRAM)
		call Process10SymAxis
		mov		temp1, r17
		mov		temp0, r16

	; shift for Rudder value
		
		lsl		r16
		rol		r17
		lsl		r16
		rol		r17
		lsl		r16
		rol		r17
		lsl		r16
		rol		r17
		lds		r18, JoystickBufferBegin+5 ; to combine with Y
		or		r18, r16
		sts		JoystickBufferBegin+5,r18
		sts		JoystickBufferBegin+6,r17
	

;;;;;;;;;;;;;;;;;
; Read value from ADC Throttle channel
		ldi		r16, ThrottleAxisChannel
		rcall	ReadADC10
		ldi		r18, ZAxisChannel	; initiate ADC conversion for next axis
		rcall	StartADC10
		ldi	ZH, high(ThrottleAxisRAM)	
		ldi	ZL,  low(ThrottleAxisRAM)
		call Process10AsymAxis

		mov		temp1, r17
		mov		temp0, r16

		lsl		temp0
		rol		temp1
		lsl		temp0
		rol		temp1
		lsl		temp0
		rol		temp1
		lsl		temp0
		rol		temp1
		lsl		temp0
		rol		temp1
		lsl		temp0
		rol		temp1

		lds		temp3, JoystickBufferBegin+6 ; to combine with Rudder
		or		temp3, temp0
		sts		JoystickBufferBegin+6,temp3
		sts		JoystickBufferBegin+7,temp1

;;;;;;;;;;;;;;;;;
; Read value from Z ADC channel
		ldi		r16, ZAxisChannel
		rcall	ReadADC10
		ldi		r18, RxAxisChannel	; initiate ADC conversion for next axis
		rcall	StartADC10
		ldi	ZH, high(ZAxisRAM)	
		ldi	ZL,  low(ZAxisRAM)
		call Process8AsymAxis
		sts		JoystickBufferBegin+8,r16 


;;;;;;;;;;;;;;;;;
; Read value from Rx ADC channel
		ldi		r16, RxAxisChannel
		rcall	ReadADC10
		ldi	ZH, high(RxAxisRAM)	
		ldi	ZL,  low(RxAxisRAM)
		call Process8AsymAxis
		sts		JoystickBufferBegin+9,r16 
		call 	RestoreUpperRegisters
		ldi		temp3,JoystickReport1Size		;Joystick report size
		rjmp	SendJoystickReport

ProcessJoystickReport_2:
		;save report ID
		ldi		temp0, 2
		sts		JoystickBufferBegin+2,temp0 	; write Report ID

	; Read row 1
		sbi		DDRB,3
		cbi		PORTB,3
		rcall	ReadButtonsRow
		sbi		PORTB,3
		cbi		DDRB,3			;return to tristate
		mov		temp3,temp0

	; Read row 2
		sbi		DDRB,4
		cbi		PORTB,4
		rcall	ReadButtonsRow
		sbi		PORTB,4
		cbi		DDRB,4			;return to tristate
		ror		temp0			; shift down
		ror		temp1			; get lowest bit to top
		andi	temp1,0b10000000
		or		temp3, temp1
		sts		JoystickBufferBegin+3,temp3 
		andi	temp0,0b00111111
		mov		temp3,temp0

	;Read row 3
		sbi		DDRB,5
		cbi		PORTB,5
		rcall	ReadButtonsRow
		sbi		PORTB,5
		cbi		DDRB,5			;return to tristate
		ror		temp0			; shift down
		ror		temp1			; get lowest bit to top
		ror		temp0			; shift down
		ror		temp1			; get lowest bit to top
		andi	temp1,0b11000000
		or		temp3, temp1
		sts		JoystickBufferBegin+4,temp3 
		andi	temp0,0b00011111
		mov		temp3,temp0

	;Read row 4
		sbi		DDRD,7
		cbi		PORTD,7
		rcall	ReadButtonsRow
		sbi		PORTD,7
		cbi		DDRC,7			;return to tristate
		mov		temp2, temp0
		ror		temp0			; shift down
		ror		temp1			; get lowest bit to top
		ror		temp0			; shift down
		ror		temp1			; get lowest bit to top
		ror		temp0			; shift down

⌨️ 快捷键说明

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