; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; RS232 Code
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; RecChar - RS-232 Recieve Character Routine - 19200 Baud, no parity, 8 data, 1 stop
RecChar ; Serial Recieve a Character from a Host
; A character is preceeded by a start bit,
; the 5v data line will go LOW for 104us (9600 baud)
MOVLW 0x09 ; Setup the 8 Bits + Start to Recieve (ignore Stop)
MOVWF SCCount
MOVF PORTA, W ; Copy to W reg
MOVWF Temp ; and save in Temp
BTFSC Temp, 1 ; Serial Input pin - TTL side goes LOW for START bit
GOTO RecChar ; Nothing yet
StartTest ; Time it - should be 104us per bit for 9600 baud
; 52us for 19200 baud
MOVLW 0x05 ;start bit leading edge, wait for centre & retest
CALL Wait_n_
GOTO $ + 1
MOVF PORTA, W ; Centre of start bit -Copy to W reg
MOVWF Temp ; and save in Temp
BTFSC Temp, 1 ; Serial Input pin - TTL still LOW for START bit
GOTO RecChar ; Must be noise - ignore it
CLRF KeyCode ; temporary storage of incoming byte
GOTO $ + 1
GOTO $ + 1
RCLoop ; Loop Here for Each Character
MOVLW 0x05
CALL Wait_n_ ; Wait for end of bit
DECFSZ SCCount,F
GOTO NextBit
MOVLW 0x05
CALL Wait_n_ ;centre of bit, wait for end
RETLW 0 ; All done - byte in KeyCode
NextBit ; Wait for middle of new bit
MOVLW 0x05
CALL Wait_n_ ;wait for centre of new bit
MOVF PORTA, W ; Copy to W reg
MOVWF Temp ; and save in Temp
BTFSC Temp, 1 ; Serial Input pin
GOTO GotOne
GotZero RRF KeyCode, F ; Note RS232 sends LSB first
BCF KeyCode, 7
NOP ; even up loop times
GOTO RCLoop
GotOne RRF KeyCode, F
BSF KeyCode, 7
GOTO RCLoop
RETLW 0
; SendChar - RS-485 Send Character Routine - 9600 Baud, ODD parity, 8 data, 1 stop
SendChar ; Serial Send the Character to the Host
MOVWF Temp ; Save the Character to Send
MOVLW 8 ; Setup the 8 Bits to Send
MOVWF SCCount
CLRF Parity ; Bit counter for parity calculation
StartBit BCF PORTA, 0 ; Output the 'Zero' Start Bit
GOTO $ + 1 ; NOTE: it is Inverted by driver (+12v)
MOVLW 0x1E
GOTO SCLoopStart
SCLoop ; Loop Here for Each Character
MOVLW 0x1D
SCLoopStart CALL Wait_n_
RRF Temp, f ; Note RS232 sends low bit first
BTFSC STATUS, C ; Do we have to Send a '1'?
GOTO SCOne ; One cycle for SCZero, two for SCOne
SCZero NOP
BCF PORTA, 0 ; NOTE: it will be Inverted by driver (+12v)
GOTO SCLoopEnd
SCOne BSF PORTA, 0 ; Send a One - NOTE: it is Inverted by driver (-12v)
MOVLW 0x01
XORWF Parity, f ; Toggle LSB to produce intermediate parity bit
SCLoopEnd GOTO $ + 1 ; Do this for 8 Bits
DECFSZ SCCount, f ;
GOTO SCLoop
MOVLW 0x1D ; Delay for the Last Data Bit
CALL Wait_n_
NOP ; Delay the Correct Number of Cycles
;Parity transmit ...
XORWF Parity, f ; test if parity bit should be set (Zero flag set)
BTFSC STATUS, Z
GOTO ParityOn
NOP
ParityOff BCF PORTA, 0 ; Odd number of bits in byte sent
GOTO ParityDel
ParityOn BSF PORTA, 0 ; Even number of bits in byte sent
GOTO $ + 1
ParityDel MOVLW 0x20
CALL Wait_n_
BSF PORTA, 0 ; Send a 'One' Stop Bit
MOVLW 0x21
CALL Wait_n_
RETLW 0
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Odds and Ends
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Wait46us - Wait Time for half of RS232 bit length - bit processing time (52us total)
Wait46us
MOVLW 0x0D ; Loop for 46 instruction cycles
GOTO $ + 1 ; Including Call and Ret (Used in RS232 Receive)
Wait_n_ MOVWF Count ; Variable delay (6+3*n us)
DECFSZ Count, f
GOTO $ - 1
Wait4us RETLW 0
; Wait4ms - Wait Time for Key to Debounce - Wait through 4,000 Cycles
Wait4ms
MOVLW 53 ; Loop Around 1,000x for a 4ms wait
MOVWF Count
MOVLW 6
MOVWF Counthi
DECFSZ Count, f
GOTO $ - 1
DECFSZ Counthi, f
GOTO $ - 3
RETLW 0