📄 hidkb_2313.lst
字号:
00005b d151 WREGI rIOPINS,0x00 ; all lights off
00005c cfd0 rjmp Initialize ; re-enable the interrupts
; Check for SUSPEND IRQ only if we're configured
00005d 2000 L4: tst configval
00005e f019 breq L5 ; skip if we're not configured
00005f fe44 sbrs rval,4 ; USBIRQ reg bit 4 is SUSPEND IRQ
000060 c001 rjmp L5
000061 d01f rcall Suspend ; stays in this subroutine until RESUME by host
;
000062 951a L5: dec button_time
000063 f6a9 brne mainloop ; check buttons if timer expires
;
; Check the button. GPIN-3 = toggle send/stop (was GPIN-1 for AtTiny13)
;
000064 e124
000065 d133 mRREG rIOPINS
000066 fb37 bst MAX_Dat,7 ; T <- GPI-3
000067 f42e brtc but_down ; active low--branch if button down
;
000068 fb01 bst flags,butstate ; T<-butstate. Button is up--was it up (1) last time?
000069 f076 brts L7 ; yes--do nothing
00006a 9468
00006b f901 SETFLAG butstate ; no--just show it's up now
00006c c00b rjmp L7
but_down:
00006d fb01 bst flags,butstate ; button is down--was it down (0) last time?
00006e f44e brtc L7 ; yes--do nothing
00006f 94e8
000070 f901 CLRFLAG butstate ; no--update it and toggle the SEND light
;
; Toggle the Send_Flag
;
000071 e850 ldi temp,bmSend_Flag ; Send_Flag is bit 7 of flags reg
000072 2705 eor flags,temp ; toggle the send bit
000073 fb07 bst flags,Send_Flag ; Send_Flag -> T
000074 f933 bld MAX_Dat,3 ; MAX_Dat.3 <- T
000075 e124
000076 2f33
000077 d135 mWREG rIOPINS,Max_Dat ; update the SEND light (GPO-3)
;
; Blink a light whenever the blink_count hits zero
;
000078 958a L7: dec blink_time
000079 f431 brne L8
00007a e986 ldi blink_time,BLINKTC
00007b 9468 seT
00007c fd30 sbrc MAX_Dat,0 ; check GPOUT0: IOPINS.0 (in MAX_Dat)
00007d 94e8 clT
00007e f930 bld MAX_Dat,0
00007f d12d rcall wreg
000080 cfb8 L8: rjmp mainloop
;
; *******************************************************************************
Suspend:
000081 e02d
000082 e134
000083 d129 WREGI rUSBIRQ,(bmSUSPIRQ+bmBUSACTIRQ) ; clear the IRQ bit & remove bus activity remnants
000084 e02e
000085 e034
000086 d126 WREGI rUSBIEN,BMBUSACTIE ; only check for this interrupt
000087 e124
000088 e034
000089 d123 WREGI rIOPINS,0b00000100 ; turn on GPO-2 light (only) to show SUSPEND
;
; Now wait for the BUSACT IRQ
;
00008a 9bb3 s1: sbis pinb,3 ; MAX3420E INT bit tied to PORTB.3 & configured for pos edge
00008b cffe rjmp s1 ; skip this if INT happened ;
;
suspend_done:
00008c e02e
00008d e138
00008e d11e WREGI rUSBIEN,(bmUSBRESIE+bmSUSPENDIE) ;disable BUSACTIE and re-enable BUSRES and SUSPEND IE's
00008f e124 ldi MAX_Reg,rIOPINS
000090 d108 rcall rreg
000091 7f3b andi MAX_Dat,0b11111011 ; turn off GPO-2 (SUSPEND) light
000092 d11a rcall wreg
000093 9508 ret
;
; ----------------------------------------------------------------------
; Reset the MAX3420E. Set the CHIPRES bit, delay, clear the CHIPRES bit.
; Then wait for OSCOK IRQ to assert.
; ----------------------------------------------------------------------
Reset_MAX:
000094 e02f
000095 e230
000096 d116 WREGI rUSBCTL,bmCHIPRES
000097 e030 ldi MAX_Dat,0 ; remove the chip reset
000098 d114 rcall wreg
;
; Resetting the chip stops the oscillator. Wait for it to stabilize
; by checking the OSCOK interrupt. Note: no need to first clear this
; IRQ because the chip reset does it.
;
000099 e02d ldi MAX_Reg,rUSBIRQ ; the OSCOKIRQ bit lives in this register
rm2:
00009a d0fe rcall rreg
00009b 7031 andi MAX_Dat,bmOSCOKIRQ
00009c f3e9 breq rm2
00009d e02d
00009e e031
00009f d10d WREGI rUSBIRQ,bmOSCOKIRQ ; clear the OSC IRQ bit
0000a0 9508 ret
; --------------------
; USB Request routines
; --------------------
;
Do_SETUP: ; Copy 8 setup bytes into SUD array in RAM
0000a1 e024 ldi MAX_Reg,rSUDFIFO
0000a2 e6e0 ldi ZL,LOW(SUD)
0000a3 e0f0 ldi ZH,0
0000a4 e058 ldi temp,8 ; fetch 8 bytes
su1:
0000a5 d0f3 rcall rreg ; result in MAX_Dat
0000a6 9331 st Z+,MAX_Dat
0000a7 955a dec temp
0000a8 f7e1 brne su1
;
; Respond to standard requests only (HID KB data requests are be requested via IN requests to EP3-IN)
;
0000a9 9150 0060 lds temp,SUD+bmRequestType
0000ab 7650 andi temp,0b01100000 ; check b6-b5 for request type
0000ac 3050 cpi temp,0b00000000 ; 00 is standard request
0000ad f019 breq std_request ; don't need to check for 01, class request since we have the INT IN endpoint for data
stall: ; vendor request (10) or undefined.
0000ae e029 ldi MAX_Reg,rEPSTALLS
0000af e233 ldi MAX_Dat,0x23
0000b0 c0fc rjmp wreg ; return from there. DON'T set ACKSTAT bit.
;
std_request:
0000b1 9150 0061 lds temp,SUD+bRequest
0000b3 305d cpi temp,13 ; make sure it's 0-12
0000b4 f7c8 brcc stall ; carry set for 12-13, clear for 13-13
0000b5 e0f0 ldi ZH,HIGH(sr_jump_table)
0000b6 ebeb ldi ZL,LOW(sr_jump_table)
0000b7 0fe5 add ZL,temp
0000b8 f408 brcc nc
0000b9 95f3 inc ZH
0000ba 9409 nc: ijmp ; PC=Z+temp
;
sr_jump_table: ; Standard Request Jump Table
0000bb c02b rjmp Get_Status ; 0
0000bc c00e rjmp Clear_Feature ; 1
0000bd cff0 rjmp stall ; 2--Reserved (Stall)
0000be c009 rjmp Set_Feature ; 3
0000bf cfee rjmp stall ; 4--Reserved (Stall)
0000c0 c024 rjmp as ; 5--Set_Address: do nothing but complete the CTL xfr
0000c1 c064 rjmp Get_Descriptor ; 6
0000c2 cfeb rjmp stall ; 7--Set_Descriptor (Stall)
0000c3 c03e rjmp Get_Configuration ; 8
0000c4 c043 rjmp Set_Configuration ; 9
0000c5 c04c rjmp Get_Interface ; 10
0000c6 c056 rjmp Set_Interface ; 11
0000c7 cfe6 rjmp stall ; 12--Sync_Frame (Stall)
;
Set_Feature:
0000c8 9468
0000c9 f903 SETFLAG setclrfeature
0000ca c002 rjmp feature
Clear_Feature:
0000cb 94e8
0000cc f903 CLRFLAG setclrfeature ; fall through to 'feature'
;
; ----------------------------------------------------------------
; GET/SET_Feature Request.The 'setclrfeature' flag says which one.
; ----------------------------------------------------------------
feature: ; check for bmRequestType = 0x02 AND wValueL = 0 AND wIndexL = 0x83
0000cd 9150 0060 lds temp,SUD+bmRequestType
0000cf 3052 cpi temp,0x02 ; dir is h->p, recipient is EP ?
0000d0 f6e9 brne stall
0000d1 9150 0062 lds temp,SUD+wValueL
0000d3 3050 cpi temp,0 ; wValueL is feature selector, 00 is EP halt
0000d4 f6c9 brne stall
0000d5 9150 0064 lds temp,SUD+wIndexL
0000d7 3853 cpi temp,0x83 ; 83 is value for EP3-IN
0000d8 f6a9 brne stall ; we only support EP-STALL
;
; It's a Set/Clr_Feature--endpoint halt request
;
0000d9 e029 ldi MAX_Reg,rEPSTALLS ; get the existing stall bits
0000da d0be rcall rreg ; value in MAX_Dat
0000db ff03 SKIP_ON_FLAG setclrfeature
0000dc c004 rjmp clrstall
; set stall bit
0000dd 9468
0000de f904 SETFLAG ep3stall
0000df 6130 ori MAX_Dat,bmSTLEP3IN
0000e0 c003 rjmp stl
clrstall:
0000e1 94e8
0000e2 f904 CLRFLAG ep3stall
0000e3 7030 andi MAX_Dat,!bmSTLEP3IN
0000e4 c0c6 stl:rjmp wregAS ; return from there
;
0000e5 e122 as: ldi MAX_Reg,rREVISION
0000e6 c0b0 rjmp rregAS ; do a dummy read just to set the ACKSTAT bit (return from rregAS)
; ----------
; Get Status
; ----------
Get_Status:
0000e7 e020 ldi MAX_Reg,rEP0FIFO ; in any case
0000e8 9150 0060 lds temp,SUD+bmRequestType
0000ea 3850 cpi temp,0x80 ; directed to device?
0000eb f029 breq GS_RWU ; yes--device status bits are self-powered & remote wakeup
0000ec 3851 cpi temp,0x81 ; directed to interface?
0000ed f051 breq GS_IF ; yes--no status bits, just send 2 zero bytes
0000ee 3852 cpi temp,0x82 ; directed to endpoint?
0000ef f051 breq GS_HALT ; yes--only ep status byte is HALT bit
0000f0 cfbd rjmp stall
GS_RWU:
;
; There are two status bits for a Device, b1=RWU_enabled and b0=Self_Powered.
; Both bits are zero: No RWU (as reported at enumeration), and we are bus powered.
;
; bst flags,RWU_enabled ; RWU_enabled bit -> T bit
; bld MAX_Dat,1 ; T bit -> into b1
0000f1 2733 clr MAX_Dat
0000f2 d0ba sz: rcall wreg
0000f3 e030 ldi MAX_Dat,0 ; second byte is 0
0000f4 d0b8 rcall wreg
0000f5 e025 ldi MAX_Reg,rEP0BC
0000f6 e032 ldi MAX_Dat,2 ; byte count
0000f7 c0b3 rjmp wregAS ; return from there
;
GS_IF:
0000f8 e030 ldi MAX_Dat,0x00 ; just send two zeros
0000f9 cff8 rjmp sz ; send this byte then a zero byte & finish the transaction
;
GS_HALT:
0000fa 9150 0064 lds temp,SUD+wIndexL ; make sure it's directed to our only data endpoint, EP3-IN
0000fc 3853 cpi temp,0x83 ; b7=1 for IN, EP=3
0000fd f009 breq valid_ep
0000fe cfaf rjmp stall ; illegal request
valid_ep:
0000ff fb04 bst flags,ep3stall ; ep3stall bit -> T bit
000100 f930 bld MAX_Dat,0 ; bit 0 is the status HALT bit
000101 cff0 rjmp sz ; send this byte then a zero byte & finish the transaction
;
;-----------------
Get_Configuration:
;-----------------
000102 e020 ldi MAX_Reg,rEP0FIFO
000103 2d30 mov MAX_Dat,configval
000104 d0a8 rcall wreg
000105 e025 ldi MAX_Reg,rEP0BC
000106 e031 ldi MAX_Dat,1
000107 c0a3 rjmp wregAS ; set the ACKSTAT bit. Return from there.
;
;-----------------
Set_Configuration:
;-----------------
000108 9000 0062 lds configval,SUD+wValueL ; config value in this byte
00010a 2d50 mov temp,configval ; so we can compare immediate
00010b 3050 cpi temp,0
00010c f409 brne enable_suspend_IRQ ; if IF NE 0, enable suspend interrupt
00010d cfd7 rjmp as ; set the ACKSTAT bit and return
enable_suspend_IRQ:
00010e e02e ldi MAX_Reg,rUSBIEN
00010f d089 rcall rreg
000110 6130 ori MAX_Dat,bmSUSPENDIE
000111 c099 rjmp wregAS ; return from there
;
;-----------------
Get_Interface:
;-----------------
; Respond to interface=0, report alternate setting=0 (our only alternate setting)
;
000112 9150 0064 lds temp,SUD+wIndexL ; wIndexL=Interface index
000114 3050 cpi temp,0
000115 f431 brne stall2 ; jump to Stall_EP0 from there
000116 e020 ldi MAX_Reg,rEP0FIFO
000117 e030 ldi MAX_Dat,0 ; alternate setting = 0
000118 d094 rcall wreg
000119 e025 ldi MAX_Reg,rEP0BC
00011a e031 ldi MAX_Dat,1
00011b c08f rjmp wregAS ; return from there
;
; Jump target for relative branches to reach the 'stall' label
;
stall2:
00011c cf91 rjmp stall
;
;-----------------
Set_Interface:
;-----------------
;
; Our descriptor reported only one interface(0) with one AS(0)
;
00011d 9150 0062 lds temp,SUD+wValueL ; wValueL=AS, should be 0
00011f 2355 tst temp
000120 f7d9 brne stall2 ; not zero--error
000121 9150 0064 lds temp,SUD+wIndexL ; wIndexL is interface
000123 2355 tst temp
000124 f7b9 brne stall2 ; not zero--error
000125 cfbf rjmp as ; return from there
;
;-----------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -