📄 jb8-usb.asm
字号:
jsr Init_IO
* --- Scan Key Matrix ------------------------------------------
jsr UScan_MTX ; scan key matrix
*
* --- Eliminate Ghost Keys -------------------------------------
jsr Ghost_Key ; detect ghost keys
*
* --- Handle New Key Matrix Scan -------------------------------
jsr UScan_Hdlr ; handle new key scan result
*
*
* --- Force RESUME signal to Host PC -----------------
bclr b_SUSPND,UIR0 ; restore USB module to normal mode
bset b_FRESUM,UCR1 ; enable force Resume
*
* --- Delay 12ms (force RESUME for 1-15ms) ----------
MSUS_D12MS:
*
MOV #{K_N12ms/256},TMODH ; set TIM overflow interval
MOV #{K_N12ms%256},TMODL ; (must write high byte first)
*
bset b_TRST,TSC ; reset TIM counter
bclr b_TOF,TSC ; clear TOF flag
MSUS_WD12MS:
nop
brclr b_TOF,TSC,MSUS_WD12MS ; wait next TOF set after 12ms
*
* --- Release RESUME signal to Host PC ---------------
bclr b_FRESUM,UCR1 ; disable force Resume
*
* --- Bring USB Module out of Resume Mode ----------------------
MSUS_RESUME:
*
* --- Wait First EOP signal after RESUME(K-state) ----
MSUS_RWEOP:
*
bclr b_SUSPND,UIR0
brclr b_EOPF,UIR1,MSUS_RWEOP ; wait end of resume signal
bset b_RESUMFR,UIR2 ; reset RESUME flag
bset b_EOPFR,UIR2 ; clear EOPF flag
*
* --- Restart Device ---------------------------------
jmp RIN_SYS ; re-start system hardware
*
* ------------------------------------------------------------------------
MSUS_EXIT:
*
*
*
.PAGE
* ------ End of Main Loop ------------------------------------------------
UMAIN_EXIT:
jmp UMAIN
.PAGE
* ------ Subroutines -----------------------------------------------------
* Init_IO initialize I/O
* RIN_RESET initialize MCU
* RST_USB_IF initialize USB module
* EP1N2_INIT initialize interrupt endpoints 1 & 2
* EP1_IN_TRANSACT prepare for next IN Interrupt Transact at Epnt 1
* EP2_IN_TRANSACT prepare for next IN Interrupt Transact at Epnt 2
* REF_TCH0 refresh TIM Ch0 O/P Compare Counter for next OCMP IRQ
* REF_TCH1 refresh TIM Ch1 O/P Compare Counter for next OCMP IRQ
* --------------------------------------------------------------------- *
*
*
*
* --------------------------------------------------------------------- *
* Init_IO - initialize I/O *
* In : <nil> *
* Out : PTA, PTB, PTC, PTD, PTE *
* DDRA, DDRB, DDRC, DDRD. DDRE *
* POC, KBIER
* Call : <nil> *
* --------------------------------------------------------------------- *
Init_IO:
* --- Initialize I/O Ports -----------------------------------------------
MOV #%11100111,POC ; enable Port A/B/C/E pullup,
* ; enable Port D high current sink
*
* (Init. Port A lines)
clr PTA ; Row 0-7 release high
clr DDRA
*
* (Init. Port B lines)
clr PTB ; Column 0-7 release high
clr DDRB
*
* (Init. Port C lines)
clr PTC ; Column 8-15 release high
clr DDRC
*
* (Init. Port D lines)
MOV #%00011111,PTE ; Column 16 & 17 release high
MOV #%11111111,PTD
MOV #%11111111,DDRD ; Force PortD output open
*
MOV #$FF,KBIER ; enable pullup at port A
*
* (Init. Port E lines)
*
MOV #%00011000,PTE ; set PTE[2:0] as i/p
MOV #%00000000,DDRE ;
*
* ------------------------------------------------------------------------
rts
*
*
*
* --------------------------------------------------------------------- *
* RIN_RESET - initialize MCU *
* In : <nil> *
* Out : TSC *
* TM0DH, TM0DL *
* KBSCR *
* Call : Init_IO *
* Col_Msk_Init
* Scan_Init
* --------------------------------------------------------------------- *
RIN_RESET:
sei
jsr Init_IO
*
*
*
* --- Initialize Timer Interface Module ----------------------------------
MOV #%00010010,TSC ; TIM clk - CPU clk / 4
; TOF interrupt disable
; reset TIM cntr & prescalar
*
MOV #$FF,TMODH ; init. TIM counter modulo
MOV #$FF,TMODL
*
*
* --- Start Suspend & Idle Timeout Timers ----------------------
MOV #%01010000,TSC0 ; CH0: OC mode, disable TCH0 pin,
; interrupt enable
; interrupt enable
*
jsr REF_TCH0 ; Add 8ms to TCH0H:L
*
* --- Initialize Keyboard Interrupt --------------------------------------
bset b_IMASKK,KBSCR ; disable keyboard interrupts
brset b_CONFIG,V_Dev_State,RIN_RST_Config
* -- do the following only when device is not configured
clr TSC1 ; disable CH1 interrupt
* --- Initialize Keyboard Scan Handler ----------------------------------
bclr b_NIRpt0,V_Dev_Status
clr V_HK_Status
jsr Col_Msk_Init
jsr SCAN_INIT ; init. key matrix scan handler
* ------------------------------------------------------------------------
bra RIN_RST_Not_Config
RIN_RST_Config:
mov #%01010000,TSC1
RIN_RST_Not_Config:
* ------------------------------------------------------------------------
rts
*
*
*
* --------------------------------------------------------------------- *
* RST_USB_IF - initialize USB module *
* In : <nil> *
* Out : V_TRANSACT -{1<b_IDLE} device idle *
* b_SPower -0 bus-powered device *
* b_RWakeup -1 enable remote wakeup *
* b_UpdAddr -0 no set device addr pending *
* V_ConfigID -$01 select Config Desc. #1 *
* I/F *
* Call : <nil> *
* --------------------------------------------------------------------- *
RST_USB_IF:
*
* --- Initialize USB Interface -------------------------------------------
MOV #%10000000,UADDR ; restore default addr($00), enable USB
MOV #%10000011,UIR0 ; enable EOP, TXD0 & RXD0 int.
MOV #%11111111,UIR2 ; reset all USB flags
$IF USB_IPullup
MOV #%01110100,UCR3 ; reset TX1st, enable USB pullup
$ENDIF ; STALL EP0 IN/OUT
$IFNOT USB_IPullup
MOV #%01110000,UCR3 ; reset TX1st, disable USB pullup
$ENDIF ; STALL EP0 IN/OUT
MOV #{1<b_RX0E},UCR0 ; disable EP0 Tx, enable Rx
*
*
* --- Initialize USB Variables -------------------------------------------
MOV #{1<b_IDLE},V_TRANSACT ; device idle
clr V_PROCESS ; clear pkt processing status
*
clr V_TRANSACT1
clr V_ConfigID
; MOV #$01,V_ConfigID ; Config ID-1
*
clr V_Dev_Status ; bus-powered device,
; default device address,
; ~Epnt 0 stalled,
; wait enumeration
; disable remote wakeup
*
* --- Set Default Status for Remote Wakeup -----------
; lda CFG_bmAttrib ; check remote wakeup default
; and #%00100000 ; in CONFIG desc.
; beq RSL_NO_RWP ; - remote wakeup disabled ?
; bset b_RWakeup,V_Dev_Status ; default to enable
RSL_NO_RWP:
*
* --- Set Keyboard Protocol & Idle Timeout Rate ------
clr V_IF0_Ptcl ; use boot protocol for kbd
*
mov #KD_IF0_Idle,V_IF0_Idle ; load default kbd idle timeout
lda #KD_IF1_Idle
sta V_IF1R1_Idle ; load default ACPI idle timeout
sta V_IF1R2_Idle
sta V_IF1R3_Idle
*
* ------------------------------------------------------------------------
RSL_EXIT:
rts
* [Embedded Device] --------------------------------------------------- *
* KBD_ADDRESS - bring keyboard from CONFIG to ADDRESS state *
* In : <nil> *
* Out : <nil> *
* Call : <nil> *
* --------------------------------------------------------------------- *
*
Kbd_Address:
lda UIR0
and #%11000011
sta UIR0 ; disable TXD2,RXD2,TXD1 int
*
mov #%00111100,UIR2 ; Reset TXD2,RXD2,TXD1 Flag
*
bset b_EOPIE,UIR0 ; enable EOPF int.
*
*
lda UCR3
and #%11111100 ; disable EP1 & EP2
sta UCR3
*
MOV #{1<b_ADDRESS},V_Dev_State ; device in ADDRESS state
*
lda V_Dev_Status ; keep remote wakeup status,
and #{1<b_RWakeup} ; clr other status
sta V_Dev_Status
*
clr TSC1 ; disable TIM CH1
; clr VS_Timer ; clr all time events
*
*
* ------------------------------------------------------------------------
Kbd_Adr_Exit:
rts
* ---------------------------------------------------------------------- *
* KBD_CONFIG - bring keyboard from ADDRESS to CONFIG state *
* In : <nil> *
* Out : <nil> *
* Call : *
* ---------------------------------------------------------------------- *
Kbd_Config:
* --- Initialize USB Interrupt Endpoint 1 & 2 --------------------------
* --- Init. Interrupt Endpoints 1 & 2 ------------------------------------
clr UCR1 ; disable Tx of Epnt 1
clr UCR2 ; disable Tx & Rx of Epnt 2
*
lda UIR0
ora #%10010100 ; enable TXD1, TXD2 int
sta UIR0
*
mov #%00111100,UIR2 ; Reset TXD2,RXD2,TXD1 Flag
*
*
*
* --- Init. Variables of Keyboard Report ---------------------------------
MOV V_IF0_Idle,VC_IF0_Idle ; start Kbd idle timeout cntr
MOV V_IF1R1_Idle,VC_IF1R1_Idle ; start ACPI idle timout cntr
MOV V_IF1R2_Idle,VC_IF1R2_Idle ; start Hot Key timout cntr
MOV V_IF1R3_Idle,VC_IF1R3_Idle ; start timout cntr
*
clr VP_KCode ; reset ptr to Q_NKey
*
*
bclr b_NIRpt0,V_Dev_Status
clr V_HK_Status
mov #%10101000,V_EP1_UCR1 ; UCR1 value for EP1
mov #%10100010,V_EP2_UCR2 ; UCR2 value for EP2
lda UCR3
ora #%00000011 ; enable EP1 & EP2
sta UCR3
mov #{1<b_Config},V_Dev_State ; device to CONFIG state
jsr Scan_Init
jsr Update_LED
MOV #%01010000,TSC1 ; CH1: OC mode, disable TCH1 pin,
; interrupt enable
mov #%00000010,TSC
mov #$FF,TMODH
mov #$FF,TMODL
jsr Ref_TCh1
mov KC_40ms,VC_40ms
mov V_IF0_Idle,VC_IF0_Idle
mov {1<b_T40ms},VS_Timer ; clr TCh1, TSus flags
; set TCh1 x10 flag (force 1st key scan)
*
* ------------------------------------------------------------------------
KBD_Cfg_Exit:
rts
*
*
*
* --------------------------------------------------------------------- *
* EP1N2_INIT - initialize Interrupt Endpoints 1 & 2 *
* In : <nil> *
* Out : <nil> *
* Call : EP1_IN_TRANSACT *
* --------------------------------------------------------------------- *
EP1N2_INIT:
*
* --- Init. Interrupt Endpoints 1 & 2 ------------------------------------
clr UCR1 ; disable Tx of Epnt 1
clr UCR2 ; disable Tx & Rx of Epnt 2
*
lda UIR0
and #%11000011
sta UIR0 ; disable TXD2,RXD2,TXD1 int
*
mov #%00111100,UIR2 ; Reset TXD2,RXD2,TXD1 Flag
*
bset b_EOPIE,UIR0 ; enable EOPF int.
*
$IF USB_IPullup
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -