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