\ -*- forth -*-

\ Serial port driver, no interrupts.

\ currently supported devices:
\ original 18f252.

\ new 18f1220. extra features not present in old design, and not used
\ here. everything else, except the location of the pins, is the same.

\ - TXSTA SENDB
\ - BAUDCTL
\ - 16bit baud gen (default is 8 bit)
\ - autobaud


\ use partial evaluation to compute the baud count. note that for high
\ clock rates and low baud rates, this needs a 16bit baud rate
\ generator (or using the 64 division instead of 16)

\ parameter RCSTA
\ parameter CREN
\ parameter OERR
\ parameter FERR
\ parameter PIR1
\ parameter RCIF
\ parameter TXSTA
\ parameter TRMT
\ parameter RCREG
\ parameter TXREG
\ parameter SPBRG
\ parameter SPBRGH
\ parameter BAUDCON

\ driver code
macro
: async.rx-reset
    RCSTA CREN low
    RCSTA CREN high ;
: async.overrun?   RCSTA OERR high? ;
: async.frame?     RCSTA FERR high? ;
forth


macro  
: async.rx-ready? PIR1  RCIF high? ;
: async.tx-ready? TXSTA TRMT high? ;
forth

: async.rx>
    begin async.rx-ready? until
    async.overrun? if
        async.rx-reset
        async.rx> ;
    then
    RCREG @
    async.frame? if
        drop
        async.rx> ;
    then ;

: async.>tx
    begin async.tx-ready? until TXREG ! ;



macro

\ parameter  serial-div
\ parameter  fosc
\ parameter  baud

: baud>count >m fosc m> serial-div * / 1 - ;
: baud-count baud baud>count ;
  
\ not all machines have the 16 bit BRG, for example the older 252 and
\ 452 models. for newer (4-digit?) chips the 16bit timer can be used.

: init-serial-baud-8
    baud-count SPBRG !
    #x24 TXSTA !               \ enable transmission and high baud rate
    #x90 RCSTA !               \ enable serial port and reception
;



\ send out all ones, which gives a pattern 0 11111111 1... which can
\ be easily measured with a frequency counter to see if the rate is
\ right. frequency = baud rate / 10
    
: debug-transmit
    begin
        #xFF
        transmit again ;

: debug-loopback
    begin receive transmit again ;

forth
  
