📄 usb-scan.asm
字号:
*****************************************************************************
* Copyright (c) Motorola 1999 *
* File Name: PS2-SCAN.ASM *
* *
* Description: Keyboard matrix scanner and handler in PS/2 mode *
* *
* *
* Assembler: CASM08Z (P&E Microcomputer Systems Inc) *
* Version: 3.16 *
* *
* Current Revision: 1.3 *
* Current Revision Release Date: 1999.08.23 by Tony Luk *
* *
* Updated History *
* Rev YYYY.MM.DD Author Description of Change *
* --- ----------- ------ --------------------- *
* 0.0 1998.06.15 Tony Luk orginal release *
* 1.0 1998.10.17 Tony Luk extended key matrix to 8 x 18 *
* 1.1 1998.10.17 Tony Luk separated init. column mask table *
* from scan_init *
* (to speed up keyboard reset) *
* 1.2 1008.10.24 Tony Luk updated key matrix scan method *
* (see note 1) *
* 1.3 1999.03.23 Tony Luk skip columns with no key press to *
* speed up GHOST_KEY & SCAN_HDLR *
* routines *
*****************************************************************************
* This Program is a freeware to demonstrate the operation of Motorola *
* Microcontroller. Motorola reserves the right to make changes without *
* further notice to any product herein to improve reliability, function, or *
* design. Motorola does not assume any liability arising out of the *
* application or use of any product, circuit, or software described herein; *
* neither does it convey any license under its patent rights nor the rights *
* of others. Motorola products are not designed, intended, or authorized *
* for use as components in systems intended for surgical implant into the *
* body, or other applications intended to support life, or for any other *
* application in which the failure of the Motorola product could create a *
* situation where personal injury or death may occur. Should Buyer purchase *
* or use Motorola products for any such intended or unauthorized *
* application, Buyer shall indemnify and hold Motorola and its officers, *
* employees, subsidiaries, affiliates, and distributors harmless against *
* all claims, costs, damages, and expenses, and reasonable attorney fees *
* arising out of, directly or indirectly, any claim of personal injury or *
* death associated with such unintended or unauthorized use, even if such *
* claim alleges that Motorola was negligent regarding the design or *
* manufacture of the part. Motorola and the Motorola logo* are registered *
* trademarks of Motorola Inc *
*****************************************************************************
* Notes :-
* 1) key matrix scan method
* - whenever ghost keys detected, error codes are reported
* - error codes are cleared whenever error conditions no longer exist
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* ====== Compile Options =================================================
.CYCLE_ADDER_OFF
$BASE !10
* ====== MACRO Definition ================================================
;;$INCLUDE "macro8.asm"
.PAGE
* ====== Subroutines =====================================================
* SCAN_INIT initialize key matrix scan
* COL_MSK_INIT initialize column mask table of key matrix map
* SCAN_MTX scan matrix keyboard(non-diode)
* GHOST_KEY detect ghost keys, and then mask off rows with ghost keys
* COUNT_ONE count the no. of '1' in <reg_A>
* SCAN_HDLR process scan results
* ADD_KEY add reg_A to USB keyboard report
* BIT_TABLE return bit position in a byte
* DLY_20US delay 20us (HC08, Fcpu=3MHz) - by inst. cycles
* --------------------------------------------------------------------- *
* SCAN_INIT - Initialize key matrix scan *
* In : <nil> *
* Out : b_CKPress =0 no key pressed(for curr. scan) *
* b_Kghost =0 no ghost keys detected *
* Q_CScan[0..17] =0 no pressed key latched in table *
* Call : <nil> *
* --------------------------------------------------------------------- *
SCAN_INIT:
clr VS_Scan ; clr key press flag,
; clr ghost key flag
*
*
*
* --- Initialize Scan Results --------------------------------------------
ldx #K_ColMax ; start with last column
clra
SINI_PVAGN:
sta {Q_CScan-1},x ; clear curr. scan results
DBNZX SINI_PVAGN ; ~last column ?
*
*
*
ldx #K_IRPT0_Size
SINI_RST_NXT:
clr {QC_IN0_RPT-1},x ; reset kbd report
DBNZX SINI_RST_NXT
*
*
ldx #K_H_Buff_Size
SINI_Clr_H_Bfr:
clr {H_Rpt_Begin-1},x
dbnzx SINI_Clr_H_Bfr
*
*
*
ldx #(K_KNCsize*4)
SINI_Clr_F_Bfr:
clr {Q_N_KEY-1},x
dbnzx SINI_Clr_F_Bfr
*
*
clr V_3_Zero
*
*
* ------------------------------------------------------------------------
SINI_EXIT:
rts
* --------------------------------------------------------------------- *
* COL_MSK_INIT - Initialize column mask table of key matrix map *
* In : KEY_TABLE key matrix map *
* K_ColMax max. # of columns *
* K_RowMax max. # of rows *
* Out : Q_ColMsk[0..17] column mask table(0- blank key) *
* Call : LOCATE_KEY *
* Note :- column mask table is used to mask out blank keys in *
* a key matrix map, in order to speed up the ghost key *
* detection algorithm *
* - column mask is only required to initialize once during *
* power-on reset *
* --------------------------------------------------------------------- *
COL_MSK_INIT:
clr VP_Col ; start with column 0
CMI_CAGN:
clr V_ColVal ; temp. byte for column mask
*
clr VP_Row ; start with row 0
CMI_RAGN:
*
* --- Get Key Code at Location (VP_Row,VP_Col) ---------------------------
lda VP_Row
ldx VP_Col
jsr ULOCATE_KEY ; return key no. in V_KeyNum
*
* --- Update Temp. Column Mask -------------------------------------------
clc
lda V_KeyNum
KCMPEQ CKEY_NA,CMI_BlankKey ; blank key ?
sec
CMI_BlankKey:
*
ror V_ColVal ; shift in mask bit
*
* --- Check Next Row -----------------------------------------------------
CMI_NROW:
*
inc VP_Row
*
ldx VP_Row
KCPXNE K_RowMax,CMI_RAGN ; ~last row ?
*
* --- Check Next Column --------------------------------------------------
CMI_NCOL:
lda V_ColVal
ldx VP_Col
sta Q_ColMsk,x ; store column mask
*
inc VP_Col
ldx VP_Col
KCPXNE K_ColMax,CMI_CAGN ; ~last column ?
*
*
*
* ------------------------------------------------------------------------
CMI_EXIT:
rts
* --------------------------------------------------------------------- *
* SCAN_MTX - scan matrix keyboard(non-diode) *
* In : b_CKPress =1 key press detected for prev. scan *
* Q_CScan[0..17] table of prev. scan result *
* Q_ColMsk[0..17] table of column mask(for blank keys) *
* Out : Q_CScan[0..17] table of curr. scan result *
* (if a bit is set, key at that pos. is *
* pressed.) *
* b_CKPress =1 key press detected for curr. scan *
* Call : Dly_20uS *
* --------------------------------------------------------------------- *
USCAN_MTX:
*
* --- Check for Key(s) Pressed -------------------------------------------
* (pull low all column lines to check if any key pressed)
USMTX_CKPRESS:
*
;; (column data zero)
clr PTB ; put zero to column data bits
clr PTC
*
lda V_PTE
and #%11111010 ; put zero PTE0,2 col 16, 17
sta PTE
*
lda #$FF ; pull low all column lines
sta DDRB ; (related data reg. default to $00)
sta DDRC
*
bset b_COL16,DDRE ; pull low col 16
bset b_COL17,DDRE ; pull low col 17
*
jsr Dly_20uS ; wait column lines stable
*
lda Port_Row ; read back row lines
coma ; key pressed(active low)
bne USMTX_SCAN ; key press detected ?
*
* --- Clear Current Scan Result (for no key press detected) --------------
USMTX_RST:
bclr b_CKPress,VS_Scan ; signal no key pressed
*
clra
ldx #K_ColMax ; start with last column
USMTX_RNXT:
sta {Q_CScan-1},x ; clear Q_CScan[x]
DBNZX USMTX_RNXT ; ~last column ?
*
bra USMTX_EXIT
*
*
*
* --- Scan Keys Matrix ---------------------------------------------------
USMTX_SCAN:
*
bset b_CKPress,VS_Scan ; signal key pressed
*
;; (done in SMTX_CKPRESS above)
clr PTB ; put zero to column data bits
clr PTC
*
*
MOV #%00000001,DDRB ; init. $00001 to Col[17..0]
MOV #%00000000,DDRC
bclr b_COL16,DDRE ; release high col 16
bclr b_COL17,DDRE ; release high col 17
*
clr VP_Col ; start with col #0
USMTX_SNCOL:
jsr Dly_20uS ; wait column lines stable
*
ldx VP_Col ; get curr. col ptr
*
lda Q_CScan,x ; copy prev. Q_CScan[x] to
sta Q_PScan,x ; curr. Q_PScan[x]
*
lda Port_Row ; check row status
coma ; key pressed(active low)
and Q_ColMsk,x ; mask out blank key pos.
sta Q_CScan,x ; store result to scan buffer
*
lsl DDRB ; force low next column
rol DDRC
*
bcc USMTX_NC16 ; reach col 16 ?
bset b_COL16,DDRE ; force low col 16
USMTX_NC16:
KCPXNE 16,USMTX_NC17 ; reach col 17 ?
bclr b_COL16,DDRE ; force high col 16
bset b_COL17,DDRE ; force low col 17
USMTX_NC17:
*
inc VP_Col
ldx VP_Col
KCPXNE K_ColMax,USMTX_SNCOL ; ~last column ?
*
*
*
* -------------------------------------------------------------------
USMTX_EXIT:
clr DDRB ; release high all column lines
clr DDRC
*
bclr b_COL16,DDRE ; release high PTE0,2 col 16, 17
bclr b_COL17,DDRE
*
rts
* --------------------------------------------------------------------- *
* GHOST_KEY - detect ghost keys, and then mask off rows with ghost keys *
* In : Q_CScan table of current scan result *
* b_CKPress =1 key press detected on curr. scan *
* Out : b_Kghost =1 ghost key detected *
* Call : COUNT_ONE *
* --------------------------------------------------------------------- *
GHOST_KEY:
bclr b_Kghost,VS_Scan ; reset ghost key flag
*
brclr b_CKPress,VS_Scan,GKEY_EXIT ; no key press detected ?
*
*
*
* --- Locate Rows with Ghost Keys in Q_CScan[0..K_ColMax] ----------------
MOV #{K_ColMax-1},VP_Col ; start with last column
GKEY_NELOOP:
*
* --- Count the no. of pressed keys in Current Column ----------
ldx VP_Col ; get current column value
lda Q_CScan,x
beq GKEY_NECOL ; no keys pressed in curr. column ?
sta V_ColVal
*
jsr COUNT_ONE ; count no. of '1' in <reg_A>
lda VC_One
lsra
beq GKEY_NECOL ; < 2 keys pressed in curr. column ?
*
* --- Check Ghost Keys overlapped with Other Columns -----------
lda VP_Col ; start with {VP_Col-1}
deca
sta VP_ChkCol
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -