📄 input_module.asm
字号:
ENDIFSend1 movf ScanCode2,w movwf ByteToSend call SendByte sublw 0 btfsc STATUS,Z ; Check return code to see of host comms initiated goto Send2; host wants to communicate call ReceiveFromHost addwf PCL, f ; Jump according to value in w; Next 3 instructions constitute a jump table goto Send2 ; w=0 return ; w=1: Reset goto SendScanCode ; w=2: Resend IF ((HIGH($)) != (HIGH($-3))) ERROR("Table crosses page boundary!") ENDIFSend2 call Delay10msSend3 movf ScanCode1,w btfsc STATUS,Z goto Send4 movwf ByteToSend call SendByte sublw 0 btfsc STATUS,Z ; Check return code to see of host comms initiated goto Send4; host wants to communicate call ReceiveFromHost addwf PCL, f ; Jump according to value in w; Next 3 instructions constitute a jump table goto Send4 ; w=0 return ; w=1: Reset goto Send3 ; w=2: Resend IF ((HIGH($)) != (HIGH($-3))) ERROR("Table crosses page boundary!") ENDIFSend4 movlw 0x0F0 movwf ByteToSend call SendByte sublw 0 btfsc STATUS,Z ; Check return code to see of host comms initiated goto Send5; host wants to communicate call ReceiveFromHost addwf PCL, f ; Jump according to value in w; Next 3 instructions constitute a jump table goto Send5 ; w=0 return ; w=1: Reset goto Send3 ; w=2: Resend IF ((HIGH($)) != (HIGH($-3))) ERROR("Table crosses page boundary!") ENDIFSend5 movf ScanCode2,w movwf ByteToSend call SendByte sublw 0 btfsc STATUS,Z ; Check return code to see of host comms initiated goto Send6; host wants to communicate call ReceiveFromHost addwf PCL, f ; Jump according to value in w; Next 3 instructions constitute a jump table goto Send6 ; w=0 return ; w=1: Reset goto Send3 ; w=2: Resend IF ((HIGH($)) != (HIGH($-3))) ERROR("Table crosses page boundary!") ENDIFSend6 return; ----------------------------------------------------------------------SendByte btfss KEYBOARD_CLOCK_IN ; Check if host is blocking us goto $-1 ; Spin until Clock is High again call Delay30us call Delay30us btfss KEYBOARD_CLOCK_IN ; Check if host is blocking us again goto SendByte ; Spin until Clock is High again btfss KEYBOARD_DATA ; Check if host wants to talk to us retlw 1 ; Host wants to send data bcf KEYBOARD_DATA ; Start bit: Data = 0 bsf STATUS,RP0 bcf KEYBOARD_DATA_DIRECTION ; Set Data to Output bcf STATUS,RP0 call Delay5us bsf KEYBOARD_CLOCK_OUT ; Clock = 0 call Delay30us bcf KEYBOARD_CLOCK_OUT ; Clock = 1 call Delay30us btfss KEYBOARD_CLOCK_IN ; Check if host is blocking us goto $-1 ; Spin until Clock is High again bsf KEYBOARD_DATA ; Data = 1 so host transmission can be sensed bsf STATUS,RP0 bsf KEYBOARD_DATA_DIRECTION ; Set Data to Input bcf STATUS,RP0 btfss KEYBOARD_DATA ; Check if host wants to talk to us retlw 1 ; Host wants to send data bsf STATUS,RP0 bcf KEYBOARD_DATA_DIRECTION ; Set Data to Output bcf STATUS,RP0 movlw 1 movwf Parity movlw 8 movwf LoopCountSendLoop rrf ByteToSend, f ; Move LSbit into Carry btfss STATUS,C ; Skip next instruction if Carry bit set goto SendZeroSendOne bsf KEYBOARD_DATA ; Data = 1 movlw 1 xorwf Parity, f goto BitSetSendZero bcf KEYBOARD_DATA ; Data = 0BitSet call Delay5us bsf KEYBOARD_CLOCK_OUT ; Clock = 0 call Delay30us bcf KEYBOARD_CLOCK_OUT ; Clock = 1 call Delay30us btfss KEYBOARD_CLOCK_IN ; Check if host is blocking us goto $-1 ; Spin until Clock is High again bsf KEYBOARD_DATA ; Data = 1 so host transmission can be sensed bsf STATUS,RP0 bsf KEYBOARD_DATA_DIRECTION ; Set Data to Input bcf STATUS,RP0 btfss KEYBOARD_DATA ; Check if host wants to talk to us retlw 1 ; Host wants to send data bsf STATUS,RP0 bcf KEYBOARD_DATA_DIRECTION ; Set Data to Output bcf STATUS,RP0 decfsz LoopCount, f goto SendLoop movf Parity,f btfss STATUS,Z ; Skip next instruction if Parity = 0 goto ParityOneParityZero bcf KEYBOARD_DATA ; Parity bit: Data = 0 goto ParityBitSetParityOne bsf KEYBOARD_DATA ; Parity bit: Data = 1ParityBitSet call Delay5us bsf KEYBOARD_CLOCK_OUT ; Clock = 0 call Delay30us bcf KEYBOARD_CLOCK_OUT ; Clock = 1 call Delay30us btfss KEYBOARD_CLOCK_IN ; Check if host is blocking us goto $-1 ; Spin until Clock is High again bsf KEYBOARD_DATA ; Data = 1 so host transmission can be sensed bsf STATUS,RP0 bsf KEYBOARD_DATA_DIRECTION ; Set Data to Input bcf STATUS,RP0 btfss KEYBOARD_DATA ; Check if host wants to talk to us retlw 1 ; Host wants to send data bsf STATUS,RP0 bcf KEYBOARD_DATA_DIRECTION ; Set Data to Output bcf STATUS,RP0 bsf KEYBOARD_DATA ; Stop bit: Data = 1 call Delay5us bsf KEYBOARD_CLOCK_OUT ; Clock = 0 call Delay30us bcf KEYBOARD_CLOCK_OUT ; Clock = 1 call Delay30us bsf STATUS,RP0 bsf KEYBOARD_DATA_DIRECTION ; Set Data to Input bcf STATUS,RP0 call Delay30us retlw 0 ; Sent OK; ----------------------------------------------------------------------; Receive a byte from the host PC and process it. Return code in W:; 0 = host command acknowledged; 1 = host instructed us to reset (BAT is called in this sub); 2 = host wants us to resendReceiveFromHost call RxByte; Send ACK movlw 0x0FA movwf ByteToSend call SendByte movlw 0x0FF subwf ReceiveByte,w btfss STATUS,Z ; reset? goto RxHost1; Reset call BAT retlw 1RxHost1 movlw 0x0FE subwf ReceiveByte,w btfss STATUS,Z ; resend? goto RxHost2; Resend retlw 2RxHost2 movlw 0x0F2 subwf ReceiveByte,w btfss STATUS,Z ; send ID? goto RxHost3; Send ID movlw 0x0AB movwf ByteToSend call SendByte movlw 0x083 movwf ByteToSend call SendByte retlw 0 RxHost3 movlw 0x0EE subwf ReceiveByte,w btfss STATUS,Z ; Send echo? goto RxHost4; Send Echo movlw 0x0EE movwf ByteToSend call SendByte retlw 0 RxHost4 retlw 0; ----------------------------------------------------------------------RxByte movlw 1 movwf Parity movlw 8 movwf LoopCount clrf ReceiveByteRxWaitStart btfss KEYBOARD_CLOCK_IN goto RxWaitStart btfsc KEYBOARD_DATA goto RxWaitStartRxLoop bsf KEYBOARD_CLOCK_OUT ; Clock = 0 call Delay30us bcf KEYBOARD_CLOCK_OUT ; Clock = 1 call Delay5us btfss KEYBOARD_DATA ; Read data bit goto ReceivedZero; One bsf STATUS,C rrf ReceiveByte,f movlw 1 xorwf Parity, f goto DoneRxBit; ZeroReceivedZero bcf STATUS,C rrf ReceiveByte,fDoneRxBit call Delay30us decfsz LoopCount, f goto RxLoop bsf KEYBOARD_CLOCK_OUT ; Clock = 0 call Delay30us bcf KEYBOARD_CLOCK_OUT ; Clock = 1 call Delay5us btfss KEYBOARD_DATA ; Read data bit goto RxParityZero; One btfss Parity,0 clrf ReceiveByte ; Parity error goto RxDoneParity; ZeroRxParityZero btfsc Parity,0 clrf ReceiveByte ; Parity errorRxDoneParity call Delay30us bsf KEYBOARD_CLOCK_OUT ; Clock = 0 call Delay30us bcf KEYBOARD_CLOCK_OUT ; Clock = 1; Stop bit has now been clocked in at this point - discard it bsf STATUS,RP0 bcf KEYBOARD_DATA_DIRECTION ; Set Data to Output bcf STATUS,RP0 bcf KEYBOARD_DATA ; Ack bit: Data = 0 call Delay30us bsf KEYBOARD_CLOCK_OUT ; Clock = 0 call Delay30us bcf KEYBOARD_CLOCK_OUT ; Clock = 1 call Delay5us bsf KEYBOARD_DATA ; Data = 1 bsf STATUS,RP0 bsf KEYBOARD_DATA_DIRECTION ; Set Data to Input bcf STATUS,RP0 return; ----------------------------------------------------------------------Delay30us movlw 15 movwf DelayLoopCountDelay30Loop decfsz DelayLoopCount, f goto Delay30Loop return; ----------------------------------------------------------------------Delay5us nop nop nop nop nop return; ----------------------------------------------------------------------Delay10ms movlw HIGH((10000 / 5) + 256) movwf HiCount movlw LOW((10000 / 5) + 256)DelayLoop2 addlw 0x0FF btfsc STATUS, Z decfsz HiCount, f goto DelayLoop2 return; ----------------------------------------------------------------------InitInterrupts; Enable interrupts according to which remotes are enabled. bsf STATUS,RP0 bcf OPTION_REG^0x080,INTEDG ; Interrupt when RB0 goes High to Low bcf STATUS,RP0 clrf INTCON call IsRFEnabled btfsc STATUS,Z bsf INTCON,INTE ; Enable RB0/INT Pin interrupt call IsIREnabled btfsc STATUS,Z bsf INTCON,RBIE ; Enable Port B Input Change interrupt bsf INTCON,GIE ; Global Interrupt Enable return; ----------------------------------------------------------------------InitTimer bsf STATUS,RP0 bcf OPTION_REG^0x080,T0CS ; Select Timer Mode bcf OPTION_REG^0x080,PSA ; Assign prescaler to Timer0 bcf OPTION_REG^0x080,PS0 bcf OPTION_REG^0x080,PS1 bsf OPTION_REG^0x080,PS2 ; Set timer prescaler bcf STATUS,RP0 return; ----------------------------------------------------------------------InitIO; Set port A and B data directions movlw 0x010 ; Initialize data bits movwf PORTA clrf PORTB bsf STATUS,RP0 bcf OPTION_REG^0x080,NOT_RBPU ; Enable Port B internal pull-up resistors. movlw 0x0F7 ; Set Port A data direction bits. movwf TRISA^0x080 movlw 0x0FF ; Set Port B data direction bits. movwf TRISB^0x080 bcf STATUS,RP0 return; ----------------------------------------------------------------------; End end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -