-- serial routine from Axelk
--
-- ------------------------------------------------------------------------
-- bit lengths:
-- 9600 baud = 104 cycles
-- 19200 baud = 52 cycles
-- 38400 baud = 26 cycles
-- 76800 baud = 13 cycles
--
--
-- ------------------------------------------------------------------------
-- const asynch_baudrate = 19200 -- hardcoded
var volatile bit asynch_in_pin is rx
var volatile bit asynch_out_pin is tx
--
-- -------------------------------------------------------------------------
-- some easy delays
--
-- -------------------------------------------------------------------------
procedure delay10 is -- 10 usec including call
-- call=2 + return=2 + 3*(goto=2)
assembler
local L1, L2, L3
goto L1
L1: goto L2
L2: goto L3
L3:
end assembler
end procedure
--
-- ------------------------------------------------------------------------
procedure delay44 is -- 44 usec including call
-- call=2 + return=2 + 4*10
delay10
delay10
delay10
delay10
end procedure
--
-- -------------------------------------------------------------------------
-- send a byte
--
-- -------------------------------------------------------------------------
procedure asynch_send( byte in x ) is
var bit current_bit at x : 0
var byte times
assembler
local sendloop, L1, L2, by0, by1
-- wait 2 bits = 104 clocks
call delay44
call delay44
call delay10
call delay10 -- 108 is ok here
-- the start bit
bcf asynch_out_pin -- low
call delay44
-- the 8 data bits
movlw 8 -- 8 times
movwf times
-- 46
goto L1 -- 48
L1: goto L2 -- 50
L2:
sendloop:
-- asynch_out_pin = current_bit
btfss current_bit
goto by0
bsf asynch_out_pin
goto by1
by0:
bcf asynch_out_pin
nop
by1: -- 5
-- x = x >> 1
rrf x, f -- 6
call delay44 -- 50
-- end loop
decfsz times, f -- 51
goto sendloop -- 53
-- the stop bit(s)
bsf asynch_out_pin -- high
call delay44
call delay10
clrwdt
end assembler
end procedure
--
-- -------------------------------------------------------------------------
-- receive a byte into lastreceived
--
-- -------------------------------------------------------------------------
var byte lastreceived
procedure asynch_receive is
var byte times
assembler
local WaitIdle, WaitStart, RecvLoop
clrwdt
-- wait for idle
WaitIdle:
btfss asynch_in_pin -- active low
goto WaitIdle
-- wait for start bit
WaitStart:
btfsc asynch_in_pin -- active low
goto WaitStart
-- wait for half a bit time (26) until recvloop
call delay10
call delay10
nop
-- now repeat 8 times:
-- wait for the next interval and sample
movlw 8 -- 8 times
movwf times
goto recvloop -- 2 usec
recvloop:
call delay44 -- 44
nop -- 45
-- x = x >> 1
clrc -- 1
rrf lastreceived, f -- 2
-- bit x:7 = asynch_in_pin
btfsc asynch_in_pin -- 3
bsf lastreceived, 7 -- 4
-- end loop
decfsz times, f -- 5
goto recvloop -- 7
-- wait for the (first) stop bit
call delay44
clrwdt
end assembler
end procedure -- asynch_receive
--
-- -------------------------------------------------------------------------
               (
geocities.com/vsurducan/electro)                   (
geocities.com/vsurducan)