-- usart asynchronous serial routine
-- writen and tested in jal by Surducan Vasile
-- distributed under GPL licence ( all you see is yours, gave me some credits)
-- some ideea taken from picuart.asm by Thomas Mc.Gahee
 
include f877_20



-- uart initialization
-- -------------------------------------------------------------------------
  pin_c6_direction = output     -- tx
  pin_c7_direction = input      -- rx
  bank_1
  f877_txsta = 0b_0010_0100 ; asynch mode, 8bit, transmit enable, high speed
 ; f877_txsta = 0b_0010_0000 ; asynch mode, 8bit, transmit enable, low speed
  
  f877_spbrg = 10 ; set baudrate at 115200 bps; set your owns according the
                  ; table below
  bank_0
  f877_rcsta = 0b_1001_0000 ; serial port enable, 8bit mode, 
                            ; constant reception
 assembler
  movf f877_rcreg, w            -- clear uart receiver and 2 fifo's
  movf f877_rcreg, w
  movf f877_rcreg, w
  movlw 0
  movwf f877_txreg              -- send out one dummy caracter
 end assembler

-- end of usart initialization
-- -------------------------------------------------------


--  asynchronous mode
--  ------------------------------------------------------
--  xtal(MHz)	baud_rate	spbrg/brgh	spbrg/brgh
--  ------------------------------------------------------
--  20  	1200		255   0 	-
--  20          2400		129   0		-
--  20          4800            64    0         -
--  20		9600		-		129   1
--  20         19200		-               64    1
--  20         28800		-		42    1
--  20         33600		-		36    1
--  20         38400            -               32    1
--  20	       57600		-		20    1
--  20        115200            -               10    1
--  20*       230400            -                4    1
--  ------------------------------------------------------
--  10          1200            129   0         -
--  10          2400            64    0         -
--  10          4800            31    0         -
--  10          9600            -  		64    1
--  10         19200		-               31    1   
--  10         28800            -               21    1
--  10         33600            -               18    1
--  10         38400            -               15    1
--  10         57600            -               10    1
--  10*       115200            -                4    1
--  ------------------------------------------------------
--  4            300            207   0         -
--  4           1200            51    0         -
--  4           2400            25    0         -
--  4           4800            12    0
--  4           9600            -               25    1
--  4          19200            -               12    1
--  4*          28800            -                7    1
--  4*          33600            -                6    1
--  ------------------------------------------------------
--  spbrg = (xtal[hz]/(baudrate[bps]*64))-1 for brgh=low
--  spbrg = (xtal[hz]/(baudrate[bps]*16))-1 for brgh=high
--  asynchronous mode
--  ------------------------------------------------------
-- * not tested
 

procedure async_rx ( byte out rx_data ) is
                  
  assembler
    local  ser_in, uart_ready, no_int, overerror, 
           frameerror

ser_in:        
	btfsc	f877_rcsta,oerr
	goto	overerror	-- to overflow error...
	btfsc	f877_rcsta,ferr
	goto	frameerror	-- to framing error...
uart_ready:
	btfss	f877_pir1,rcif
	goto	ser_in		-- wait if not ready...
				
no_int:
	bcf	intcon_gie	-- switch off interrupts 
	btfsc	intcon_gie	-- be sure
	goto 	no_int
        movf	f877_rcreg,w    -- recover uart data
	bsf	intcon_gie	-- re-enable interrupts
	movwf	rx_data		-- save in reception register 
	return

overerror: -- if f877_rcreg is still full at third byte stop bit detection
	bcf	intcon_gie	-- turn interrupts off
	btfsc	intcon_gie	-- be sure
	goto 	overerror
	bcf	f877_rcsta,cren	-- disable continuous receive, reset oerr
	movf	f877_rcreg,w	-- flush rcreg + 2 fifo, this will clears the
	movf	f877_rcreg,w	-- ferr flag
	movf	f877_rcreg,w
	bsf	f877_rcsta,cren	-- enable continous receive, clear oerr			
	bsf	intcon_gie	-- enable interrupts.
	goto	ser_in		-- try again...

frameerror:			-- if garbage is coming in
	bcf	intcon_gie	-- disable interrupts
	btfsc	intcon_gie	
	goto 	frameerror	-- be sure
  	movf	f877_rcreg,w    -- reading rcreg clears ferr flag 
   --     bcf     f877_rcsta,ferr -- sure clears ferr
        bsf     intcon_gie
        goto    ser_in
end assembler
end procedure

procedure async_tx ( byte in tx_data ) is
 assembler
  local transmit, interrupt
 	movf	tx_data,w	-- copy tx_data to w.
transmit:				
	btfss	f877_pir1,txif   
	goto	transmit	-- wait for transmitter interrupt flag
interrupt:
	bcf	intcon_gie	-- disable interrupts
	btfsc	intcon_gie	-- be sure
	goto	interrupt
	movwf	f877_txreg      -- load data to be sent...
	bsf	intcon_gie	-- re-enable interrupts
	return			-- transmitted data is in W
 end assembler
end procedure



var byte data 
 
forever loop
  async_rx ( data ) -- receive a character ( 8,N,1, hardware flow DTR=DSR, 
                    -- RTS=CTS or none )
  async_tx ( data ) -- send back to terminal
end loop


 
 

    Source: geocities.com/vsurducan/electro/PIC

               ( geocities.com/vsurducan/electro)                   ( geocities.com/vsurducan)