📄 mjoy.asm
字号:
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 + -