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

📄 mjoy.asm

📁 用于AVR的USB
💻 ASM
📖 第 1 页 / 共 5 页
字号:

Check_MaxA10:
		ldd r19, Z + s_MaxH
		ldd r18, Z + s_MaxL
		cp	r18, r16		; check if value exceeds MAXIMUM  range
		cpc	r19, r17
		brsh	Check_EndA10
		std Z + s_MaxH, r17
		std Z + s_MaxL, r16
		sbr	r20, 	1		; update required

Check_EndA10:
		sbrs	r20,0		; skip recalculation if update is not required
		rjmp	ProcA10Offset
		sts  ADCValueH, r17 ; backup ADC value
		sts  ADCValueL, r16
		ldi r17, 0				; mark that update was made
		ldi	r16, 1
		std Z + s_UpdateCntH, r17
		std Z + s_UpdateCntL, r16
		call CalcCoef
		lds r17, ADCValueH	; restore ADC value
		lds r16, ADCValueL
		
; Step 2 : Offset

ProcA10Offset:
		ldd r19, Z + s_MinH
		ldd r18, Z + s_MinL
		sub r16, r18		; subtract 16-bit minimum value
		sbc r17, r19


; Step 3 : Multiply by coeficient
		movw r23:r22, r17:r16
		ldd r21, Z + s_CoefH	; range coeficient
		ldd r20, Z + s_CoefL
		movw	r19:r18, r1:r0	; backup r1, r0
		call mul16x16_16
		movw	r1:r0, r19:r18	; restore r1, r0
		
; Step 4: Divide by 128
		
		lsl r16		
		rol r17
		rol r18
		lsl r16		
		rol r17
		rol r18
		mov r16, r17
		mov r17, r18	; the result is in r17:r16 register
		andi	r17, 3
		subi	r16, 0
		sbci	r17, 2
		andi r17, 3
					; the result is in r17:r16 register
		ret 




;*******************************************************************
; Calculate 10 bit symmetrical axis negative coeficient
;
; Input: Z - address of 10 bit symmetric axis structure
;*******************************************************************
CalcNegCoef:
		; Calculate Negative range Coeficient
		ldd r19, Z + s_CenterH
		ldd r18, Z + s_CenterL
		ldd r17, Z + s_MinH
		ldd r16, Z + s_MinL
		sub r18, r16
		sbc r19, r17	; the result in r19:r18 is negative range width
		;---------- check for zero range
		brne	ProceedCalcNegCoef
		;-- if zero just make a coeficient = 1, which produces 0 value on end output
		ldi r17, 0
		ldi	r16, 1
		std Z + s_NegCoefH, r17
		std Z + s_NegCoefL, r16
		ret
		
ProceedCalcNegCoef:		

		ldi r17, 255
		ldi r16, 255
		movw	r21:r20, r15:r14	; backup r14 and r15
		call div16u
		movw	r15:r14, r21:r20 	; restore r14 and r15
		std Z + s_NegCoefH, r17
		std Z + s_NegCoefL, r16
		ret
;*******************************************************************
; Calculate 10 bit symmetric axis positive coeficient
;
; Input: Z - address of 10 bit symmetric axis structure
;*******************************************************************
CalcPosCoef:
		; Calculate Positive range Coeficient  
		ldd r19, Z + s_MaxH
		ldd r18, Z + s_MaxL
		ldd r17, Z + s_CenterH
		ldd r16, Z + s_CenterL
		sub r18, r16
		sbc r19, r17	; the result in r19:r18 is positive range width

		;---------- check for zero range
		brne	ProceedCalcPosCoef
		;-- if zero just make a coeficient = 1, which produces 0 value on end output
		ldi r17, 0
		ldi	r16, 1
		std Z + s_PosCoefH, r17
		std Z + s_PosCoefL, r16
		ret

ProceedCalcPosCoef:		
		ldi r17, 255
		ldi r16, 112
		movw	r21:r20, r15:r14	; backup r14 and r15
		call div16u
		movw	r15:r14, r21:r20 	; restore r14 and r15
		std Z + s_PosCoefH, r17
		std Z + s_PosCoefL, r16

		ret


;*******************************************************************
; Calculate 8 bit ssymmetric axis coeficient
;
; Input: Z - address of 8 bit asymmetric axis structure
;*******************************************************************
CalcCoef:
		; Calculate Positive range Coeficient  
		ldd r19, Z + s_MaxH
		ldd r18, Z + s_MaxL
		ldd r17, Z + s_MinH
		ldd r16, Z + s_MinL
		sub r18, r16
		sbc r19, r17	; the result in r19:r18 is a range width
		;---------- check for zero range
		brne	ProceedCalcCoef
		;-- if zero just make a coeficient = 1, which produces 0 value on end output
		ldi r17, 0
		ldi	r16, 1
		std Z + s_CoefH, r17
		std Z + s_CoefL, r16
		ret



ProceedCalcCoef:		
		ldi r17, 255
		ldi r16, 128;255

		movw	r21:r20, r15:r14	; backup r14 and r15
		call div16u
		movw	r15:r14, r21:r20 	; restore r14 and r15

		std Z + s_CoefH, r17
		std Z + s_CoefL, r16

		ret




;***********************************************************************

ReadADC_10: ; Input:	temp0 contains number of ADC input to read
			; Return:	temp0 contains bits 0-7
			;			temp1 contains bits 8-9
		andi temp0, 0b00000111
		ori	 temp0, 0b01000000	;AVCC refernce, clear ADLAR for 10 bit conversion
		out ADMUX, temp0
		sbi		ADCSRA, ADSC	; start conversion
WaitForADC_10:
		sbic	ADCSRA, ADSC
		rjmp	WaitForADC_10
		in	temp0,ADCL
		in	temp1,ADCH

		cpi	temp0,0
		brne	Subtract512
		cpi	temp1,0
		brne	Subtract512
		ldi	temp0,1
Subtract512:
	; subtract 512 to get values in range (-511, 511)
		subi	temp0, 0x00
		sbci	temp1, 0x02
		andi	temp1, 0x03

		ret


;************************************************************************

ReadADC_8: ; temp0 contains number of ADC input to read
; Read value from ADC X channel
		andi temp0, 0b00000111
		ori	 temp0, 0b01100000	;AVCC refernce, set ADLAR for 8 bit conversion
		out ADMUX, temp0
		sbi		ADCSRA, ADSC	; start conversion
WaitForADC_8:
		sbic	ADCSRA, ADSC
		rjmp	WaitForADC_8

		in	temp0,ADCH

Subtract128:
	; subtract 128 to get values in range (-127, 127)
		subi	temp0, 0x80
		ret

;***************************************************88

BackupRegisters:
		sts	RegistersBackup+0, r0
		sts	RegistersBackup+1, r1
		sts	RegistersBackup+2, r2
		sts	RegistersBackup+3, r3
		sts	RegistersBackup+4, r4
		sts	RegistersBackup+5, r5
		sts	RegistersBackup+6, r6
		sts	RegistersBackup+7, r7
		sts	RegistersBackup+8, r8
		sts	RegistersBackup+9, r9
		sts	RegistersBackup+10, r10
		sts	RegistersBackup+11, r11
		sts	RegistersBackup+12, r12
		sts	RegistersBackup+13, r13
		sts	RegistersBackup+14, r14
		sts	RegistersBackup+15, r15
		sts	RegistersBackup+16, r16
		sts	RegistersBackup+17, r17
		sts	RegistersBackup+18, r18
		sts	RegistersBackup+19, r19
		sts	RegistersBackup+20, r20
		sts	RegistersBackup+21, r21
		sts	RegistersBackup+22, r22
		sts	RegistersBackup+23, r23
		sts	RegistersBackup+24, r24
		sts	RegistersBackup+25, r25
		sts	RegistersBackup+26, r26
		sts	RegistersBackup+27, r27
		sts	RegistersBackup+28, r28
		sts	RegistersBackup+29, r29
		sts	RegistersBackup+30, r30
		sts	RegistersBackup+31, r31
		ret

RestoreRegisters:
		lds	r0,RegistersBackup+0
		lds	r1, RegistersBackup+1
		lds	r2, RegistersBackup+2
		lds	r3, RegistersBackup+3
		lds	r4, RegistersBackup+4
		lds	r5, RegistersBackup+5
		lds	r6, RegistersBackup+6
		lds	r7, RegistersBackup+7
		lds	r8, RegistersBackup+8
		lds	r9, RegistersBackup+9
		lds	r10, RegistersBackup+10
		lds	r11, RegistersBackup+11
		lds	r12, RegistersBackup+12
		lds	r13, RegistersBackup+13
		lds	r14, RegistersBackup+14
		lds	r15, RegistersBackup+15
		lds	r16, RegistersBackup+16
		lds	r17, RegistersBackup+17
		lds	r18, RegistersBackup+18
		lds	r19, RegistersBackup+19
		lds	r20, RegistersBackup+20
		lds	r21, RegistersBackup+21
		lds	r22, RegistersBackup+22
		lds	r23, RegistersBackup+23
		lds	r24, RegistersBackup+24
		lds	r25, RegistersBackup+25
		lds	r26, RegistersBackup+26
		lds	r27, RegistersBackup+27
		lds	r28, RegistersBackup+28
		lds	r29, RegistersBackup+29
		lds	r30, RegistersBackup+30
		lds	r31, RegistersBackup+31
		ret

BackupUpperRegisters:
		sts	RegistersBackup+14, r14
		sts	RegistersBackup+15, r15
		sts	RegistersBackup+16, r16
		sts	RegistersBackup+17, r17
		sts	RegistersBackup+18, r18
		sts	RegistersBackup+19, r19
		sts	RegistersBackup+20, r20
		sts	RegistersBackup+21, r21
		sts	RegistersBackup+22, r22
		sts	RegistersBackup+23, r23
		sts	RegistersBackup+24, r24
		sts	RegistersBackup+25, r25
		sts	RegistersBackup+26, r26
		sts	RegistersBackup+27, r27
		sts	RegistersBackup+28, r28
		sts	RegistersBackup+29, r29
		sts	RegistersBackup+30, r30
		sts	RegistersBackup+31, r31
		ret

RestoreUpperRegisters:
		lds	r14, RegistersBackup+14
		lds	r15, RegistersBackup+15
		lds	r16, RegistersBackup+16
		lds	r17, RegistersBackup+17
		lds	r18, RegistersBackup+18
		lds	r19, RegistersBackup+19
		lds	r20, RegistersBackup+20
		lds	r21, RegistersBackup+21
		lds	r22, RegistersBackup+22
		lds	r23, RegistersBackup+23
		lds	r24, RegistersBackup+24
		lds	r25, RegistersBackup+25
		lds	r26, RegistersBackup+26
		lds	r27, RegistersBackup+27
		lds	r28, RegistersBackup+28
		lds	r29, RegistersBackup+29
		lds	r30, RegistersBackup+30
		lds	r31, RegistersBackup+31
		ret

;******************************************************************************
;*
;* FUNCTION
;*	mul16x16_16
;* DECRIPTION
;*	Multiply of two 16bits numbers with 16bits result.
;* USAGE
;*	r17:r16 = r23:r22 * r21:r20
;* STATISTICS
;*	Cycles :	9 + ret
;*	Words :		6 + ret
;*	Register usage: r0, r1 and r16 to r23 (8 registers)
;* NOTE
;*	Full orthogonality i.e. any register pair can be used as long as
;*	the result and the two operands does not share register pairs.
;*	The routine is non-destructive to the operands.
;*
;******************************************************************************

mul16x16_16:
	mul	r22, r20		; al * bl
	movw	r17:r16, r1:r0
	mul	r23, r20		; ah * bl
	add	r17, r0
	mul	r21, r22		; bh * al
	add	r17, r0
	ret


AddCRCOutReturn:	
		inc	ByteCount		;length of output buffer + CRC16
		inc	ByteCount


	; Backup Control pipe buffer pointers to save Control pipe state
		mov	temp0, OutputBufferLength
		sts BkpOutputBufferLength,temp0
		mov temp0, OutBitStuffNumber
		sts BkpOutBitStuffNumber,temp0


		inc	BitStuffInOut			;transmitting buffer - insertion of bitstuff bits
		ldi	USBBufptrY,JoystickBufferBegin	;to transmitting buffer
		rcall	BitStuff
;		mov	OutputBufferLength,ByteCount	;length of answer store for transmiting
		clr	BitStuffInOut			;receiving buffer - deletion of bitstuff bits


	; copy to Joystick buffer
		sts JoyOutputBufferLength, ByteCount
		sts JoyOutBitStuffNumber, OutBitStuffNumber


	; Restore Control pipe buffer pointers
		lds		temp0, BkpOutputBufferLength
		mov		OutputBufferLength, temp0
		lds		temp0, BkpOutBitStuffNumber
		mov		 OutBitStuffNumber,temp0


	; set joystick data ready flag
		ldi		temp0,JoystickDataReady
		or		JoystickFlags,temp0 
;TestpointEnd -------------
	;	rjmp	CRCReturnPoint

		ret
	;	rjmp	Main


;********************************************************************
;*  Main program END
;********************************************************************
;------------------------------------------------------------------------------------------
;********************************************************************
;*  Interrupt0 interrupt handler
;********************************************************************
INT0Handler:					;interrupt INT0
		in	backupSREG,SREG
		push	temp0
		push	temp1

		ldi	temp0,3			;counter of duration log0
		ldi	temp1,2			;counter of duration log1
		;waiting for begin packet
CheckchangeMinus:
		sbis	inputport,DATAminus	;waiting till change D- to 1
		rjmp	CheckchangeMinus
CheckchangePlus:
		sbis	inputport,DATAplus	;waiting till change D+ to 1
		rjmp	CheckchangePlus
DetectSOPEnd:
		sbis	inputport,DATAplus
		rjmp	Increment0		;D+ =0
Increment1:
		ldi	temp0,3			;counter of duration log0
		dec	temp1			;how many cycles takes log1
		nop
		breq	USBBeginPacket		;if this is end of SOP - receive packet
		rjmp	DetectSOPEnd
Increment0:
		ldi	temp1,2			;counter of duration log1
		dec	temp0			;how many cycles take log0
		nop
		brne	DetectSOPEnd		;if there isn't SOF - continue
		rjmp	EndInt0HandlerPOP2
EndInt0Handler:
		pop	ACC

⌨️ 快捷键说明

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