;KEY PAD ;------------------------------------------------------------------------------------------ ;output: PD0 PA3 PA2 PA1 PA0 ;------------------------------------------------------------------------------------------ ;KeyValue: | input: ; 32 24 16 8 0 | PB0 ; 33 25 17 9 1 | PB1 ; 34 26 18 10 2 | PB2 ; 35 27 19 11 3 | PB3 ; 36 28 20 12 4 | PC0 ; 37 29 21 13 5 | PC1 ; 38 30 22 14 6 | PC2 ; 39 31 23 15 7 | PC3 ;========================================================================================== KEY_DEBOUNCE_TIMER EQU 32 ;adjust sensitive here(20ms) ;-------------------------------------------------------------------------------------- ScanKeyIO: ; set PD0=0 and then accumulate the value of PB & PC ;then set PA3=0 and then accumulate the value of PB & PC ;then set PA2=0 and then accumulate the value of PB & PC ;then set PA1=0 and then accumulate the value of PB & PC ;then set PA0=0 and then accumulate the value of PB & PC ;at last the accumulated value is save in zKeyTMP[H,L] regs and its regards ;as current keyState ;---------scan the key ----------- ldi zKeyTMP_L ,0x00 ldi zKeyTMP_H ,0x00 ;------------------------------------- ;PA0: ldi rzPDOUT ,0000b ;PA0 output low,others all float ldi rzPD ,0000b ldi rzPAOUT ,0001b ldi rzPA ,0000b call AccumulateMatrixKey ;PA1: ;ldi rzPDOUT ,0000b ;PA1 output low,others all float ;ldi rzPD ,0000b ldi rzPAOUT ,0010b ldi rzPA ,0000b call AccumulateMatrixKey ;PA2: ;ldi rzPDOUT ,0000b ;PA2 output low,others all float ;ldi rzPD ,0000b ldi rzPAOUT ,0100b ldi rzPA ,0000b call AccumulateMatrixKey ;PA3: ;ldi rzPDOUT ,0000b ;PA3 output low,others all float ;ldi rzPD ,0000b ldi rzPAOUT ,1000b ldi rzPA ,0000b call AccumulateMatrixKey ;PD0: ldi rzPDOUT ,0001b ;PD0 output low,others all float ldi rzPD ,0000b ldi rzPAOUT ,0000b ldi rzPA ,0000b call AccumulateMatrixKey ;all float ldi rzPDOUT ,0000b ldi rzPD ,0000b ;ldi rzPAOUT ,0000b ;ldi rzPA ,0000b ;----- Result save in zKeyTMP------- lda zKeyTMP_H ,0 rtni ;-------------------------------------------------------------------------------------- AccumulateMatrixKey: ;init all input port ldi rzPB ,1111b ldi rzPC ,1111b ;------------------------------------------ lda rzPB ,0 nop addm zKeyTMP_L ,0 eor zKeyTMP_L ,0 adcm zKeyTMP_H ,0 lda rzPC ,0 nop addm zKeyTMP_L ,0 eor zKeyTMP_L ,0 adcm zKeyTMP_H ,0 ;------------------------------------------ rtni ;----------------------------------------------------------------------------------------- ReadKeyValue: ;init all input port ldi rzPB ,1111b ldi rzPC ,1111b ;------------------------------------------ ldi zKShiftCount ,0x00 ?loadKeyValue: lda rzPB ,0 nop sta zKTmpL ,0 lda rzPC ,0 nop sta zKTmpH ,0 eorim zKTmpL ,1111b eorim zKTmpH ,1111b ?shiftKeyValue: adim zKIndex ,0x01 eor zKIndex ,0 adcm zKIndexH ,0 ;shift right one bit lda zKTmpL ,0 shr sta zKTmpL ,0 bc ?saveKeyValue ?continueShiftKeyValue: lda zKTmpH ,0 ba0 $+2 jmp $+2 orim zKTmpL ,1000b lda zKTmpH ,0 shr sta zKTmpH ,0 jmp ?nextBit ?saveKeyValue: adim zKPressCount ,0x01 sbi zKPressCount ,0x01 baz ?saveKeyValue1 sbi zKPressCount ,0x02 baz ?saveKeyValue2 sbi zKPressCount ,0x03 baz ?saveKeyValue3 ?moreThanThreeKeys: ;prevent zKPressCount overflow ldi zKPressCount ,0x04 jmp ?continueShiftKeyValue ?saveKeyValue3: lda zKIndex ,0 sta zKeyValue_L3 ,0 lda zKIndexH ,0 sta zKeyValue_H3 ,0 jmp ?continueShiftKeyValue ?saveKeyValue2: lda zKIndex ,0 sta zKeyValue_L2 ,0 lda zKIndexH ,0 sta zKeyValue_H2 ,0 jmp ?continueShiftKeyValue ?saveKeyValue1: lda zKIndex ,0 sta zKeyValue_L ,0 lda zKIndexH ,0 sta zKeyValue_H ,0 jmp ?continueShiftKeyValue ?nextBit: adim zKShiftCount ,0x01 ?judgeFinish: sbi zKShiftCount ,0x08 bnz ?shiftKeyValue rtni ;====================================================================================== ; ScanKey ;====================================================================================== ScanKey: ;prepare to scan key ldi rzPAOUT ,0000b ldi rzPA ,1111b ldi rzPDOUT ,0000b ldi rzPD ,0011b ldi rzPBOUT ,0000b ldi rzPB ,1111b ldi rzPCOUT ,0000b ldi rzPC ,1111b ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;whether ever get different key value than the last key state lda zKdebounce ,0 ;yes,check whether maintain stable ba0 ContinueScanKey ;no,check whether get different Key value LookUpKeyState: call ScanKeyIO ;lda zKeyTMP_H ,0 eor zKeyState_H ,0 ;if different from the last stable state bnz BeginScanKey lda zKeyTMP_L ,0 eor zKeyState_L ,0 ;if different from the last stable state bnz BeginScanKey ;if equal to the last state jmp Finish_ScanKey BeginScanKey: ;save current state to zKeyState buffer lda zKeyTMP_L ,0 sta zKeyState_L ,0 lda zKeyTMP_H ,0 sta zKeyState_H ,0 ;----- Reload Debounce counter and clear debounce done flag ----- ldi zKeyPeriod_H ,(KEY_DEBOUNCE_TIMER>>4)&0x0f ldi zKeyPeriod_L ,(KEY_DEBOUNCE_TIMER )&0x0f ;---------------------------------------------------------------- ;mark ever get different Key value than the last Key state flag orim zKdebounce ,0001b jmp Finish_ScanKey ;exit ContinueScanKey: call ScanKeyIO ;lda zKeyTMP_H ,0 eor zKeyState_H ,0 ;if different from the last stable state again bnz BeginScanKey lda zKeyTMP_L ,0 eor zKeyState_L ,0 ;if different from the last stable state again bnz BeginScanKey ;if still equal to the last state DebounceScanKey: ;the key state must be stable here ;Judge whether finish debouncing work. sbim zKeyPeriod_L ,01h eor zKeyPeriod_L ,0 sbcm zKeyPeriod_H ,0 bnc VerifyKeyValue jmp Finish_ScanKey VerifyKeyValue: ; andim zKdebounce ,1110b ; ;prevent enter ISR and send the wrong code while the key value is being ; ;determined below. ; andim zKeyPressFlag ,0011b andim zKeyPressFlag ,0010b ;---------------------------------------------------------------------------------------- GetKeyValue: zKIndex EQU zKeyPeriod_L ;key code table index zKIndexH EQU zKeyPeriod_H ; zKTmpL EQU zWk0 ;current port state zKTmpH EQU zWk1 ;current port state zKShiftCount EQU zWk2 ; zKPressCount EQU zWk3 ;how many key is press ldi zKPressCount ,0x00 ldi zKIndex ,0x0f ldi zKIndexH ,0x0f ;ScanPA0: ldi rzPDOUT ,0000b ;PA0 out put low,others float ldi rzPD ,0000b ldi rzPAOUT ,0001b ldi rzPA ,0000b call ReadKeyValue ;ScanPA1: ;ldi rzPDOUT ,0000b ;PA1 out put low,others float ;ldi rzPD ,0000b ldi rzPAOUT ,0010b ldi rzPA ,0000b call ReadKeyValue ;ScanPA2: ;ldi rzPDOUT ,0000b ;PA2 out put low,others float ;ldi rzPD ,0000b ldi rzPAOUT ,0100b ldi rzPA ,0000b call ReadKeyValue ;ScanPA3: ;ldi rzPDOUT ,0000b ;PA3 out put low,others float ;ldi rzPD ,0000b ldi rzPAOUT ,1000b ldi rzPA ,0000b call ReadKeyValue ;ScanPD0: ldi rzPDOUT ,0001b ;PD0 out put low,others float ldi rzPD ,0000b ldi rzPAOUT ,0000b ldi rzPA ,0000b call ReadKeyValue ;all float ldi rzPDOUT ,0000b ldi rzPD ,0000b ;ldi rzPAOUT ,0000b ;ldi rzPA ,0000b ;---------------------------------------------------------------------------------------- JudgeKeyValue: lda zPoweronEntry ,0 bnz ContinuePowerOn FirstPowerOn: sbi zKPressCount ,0x03 bnz ?customerMode sbi zKeyValue_L ,(KEY25_INDEX)&0x0f bnz ?customerMode sbi zKeyValue_H ,(KEY25_INDEX>>4)&0x0f bnz ?customerMode sbi zKeyValue_L2 ,(KEY26_INDEX)&0x0f bnz ?customerMode sbi zKeyValue_H2 ,(KEY26_INDEX>>4)&0x0f bnz ?customerMode sbi zKeyValue_L3 ,(KEY27_INDEX)&0x0f bnz ?customerMode sbi zKeyValue_H3 ,(KEY27_INDEX>>4)&0x0f bnz ?customerMode ?factoryMode: orim zMode ,0100b jmp ?next ?customerMode: andim zMode ,1011b ?next: ldi zPoweronEntry ,0x0f ;------------------------------------------------------------------------------------------ ContinuePowerOn: lda zKPressCount ,0 baz ReleaseAllKey sbi zKPressCount ,0x01 baz PressOneKey PressMultiKey: PressInvalidKey: ; ;since multi key or invalid key,the request to return to customer mode is ; ;inefficacy ; andim zKeyPressFlag ,1101b ; ;set invalid key press ; orim zKeyPressFlag ,1000b ldi zKeyPressFlag ,1000b jmp Finish_ScanKey PressOneKey: ;set back to customer mode request sbi zOption ,RC2143801 bnz ?36key ?38key: sbi zKeyValue_L ,(KEY38_INDEX)&0x0f bnz ?next sbi zKeyValue_H ,(KEY38_INDEX>>4)&0x0f bnz ?next jmp ?setReturnCustomerRequest ?36key: sbi zKeyValue_L ,(KEY36_INDEX)&0x0f bnz ?next sbi zKeyValue_H ,(KEY36_INDEX>>4)&0x0f bnz ?next ?setReturnCustomerRequest: orim zKeyPressFlag ,0010b ?next: ;invert toggle bit eorim zToggle ,1000b ;set valid key press orim zKeyPressFlag ,0100b jmp Finish_ScanKey ReleaseAllKey: ;return customer mode lda zKeyPressFlag ,0 ba1 $+2 jmp $+2 ;set current mode as customer mode andim zMode ,1011b ; ;clear back to custom mode request ; andim zKeyPressFlag ,1101b ldi zKeyPressFlag ,0000b ;----------------------------------------------------------------------------------------- Finish_ScanKey: jmp Exit_ScanKey ;----------------------------------END----------------------------------------------------- |