;   File:SAMPLE2.ASM
;    PIC: 16F877 @ 20Mhz
;   Date: 28 Dec 2002
; Author: Joe Farr
;---------------------------------------------------------------------
; Description:
; Sample program to test the PIC Serial Board interface
; Echoes back to the PC the binary equiv. of a character sent to the
; PIC whilst also displaying the ASCII code on 8 x LED's on PORT B
;
; 19200 Baud, No parity, 1 Stop bit @ 20Mhz XTAL
; TX from PIC on C6 (From PIC to PC/Interface Card)
; RX back to pic on C7 (From PC/Interface Card to PIC)
;
;---------------------------------------------------------------------
; Config register bits from the TK3 Config PIC screen
; CP1  CP0  DBG  NIL  WRT  CPD  LVP  BOR  CP1 CP0  POR  WDT  OS1  OS0
;  1    1    1    1    1    1    0    0    1   1    0    0    1    0
; N.B. Logic 1/0 do NOT necessarily mean that the function is On/Off
; respectively - refer ro PIC '87 data sheet.
;---------------------------------------------------------------------
;
; I/O Port Usage Map
; PORT    Usage
;------------------------------------------
; A0 - A5 N/U
; B0      LED 0 (LSB)
; B1      LED 1
; B2      LED 2
; B3      LED 3
; B4      LED 4
; B5      LED 5
; B6      LED 6
; B7      LED 7 (MSB)
; C0 - C5 N/U
; C6 	  RS232 from PIC to Interface Card
; C7 	  RS232 from Interface Card to PIC
; D0 - D7 N/U
; E0 - E2 N/U

	LIST p=16f877,c=140,n=999
        errorlevel 1,-(305)
        include "p16f877.inc"

LOOP    equ     0x24
TEMP    equ     0x25
VALUE   equ     0x26
COUNT   equ     0x27

	org 	0
        clrf 	STATUS
        goto 	BootStart
        org 	4
ISR     goto 	5            	; Setup Interupt Address
	org 	5



BootStart
        ;
        ; Configure the I/O ports
        ;
        clrf    STATUS
        movlw   b'00000000'
        movwf   PORTA
        movwf   PORTB
        movwf   PORTC
        movwf   PORTD
        movwf   PORTE

; -------- PORT C ---------
        movlw   b'11000000'     ; set RC0 - RC5 as outputs
                                ; set RC6 - RC7 as inputs(serial)
        movwf   TRISC


;
; Configure the baud rate generator
;
        movlw   d'64'           ; 19.2K Baud with 20MHz XTAL - Page 98, Table 10-4 of the Microchip 16877 data sheet
        bsf 	STATUS,RP0  	; set RAM Page 1 for TRIS registers
	movwf   SPBRG           ; Store In bank 1
        movlw   b'00100100'     ; BRGH = 1(High speed) & ASYNC transmission
        movwf   TXSTA           ; In bank 1
        bcf 	STATUS,RP0      ; Select Bank 0
        movlw   b'10010000'     ; ASYNC reception
        movwf   RCSTA           ; In bank 0
        movf    RCREG,W         ; Flush the RX buffer in bank 0
        movf    RCREG,W
	movf    RCREG,W


;
; Ready to start program
; Indicate that now ready
;
        movlw   mReady          ; MSG - Ready
	call    SendMessage     ; Send message to serial

;
; *** MAIN PROGRAM LOOP ***
;
WaitCom
        call 	FlushRXBuffer   ; Make sure that the RX buffer is empty
        call    RecLoop         ; Wait and read from serial - character returned in 'W'

; Send the Binary pattern equiv. back to the serial port
        movwf   VALUE           ; Store 'W' in 'VALUE' for the TXBinary routine
        call    TxBinary

;
; Were done....
;
        movlw   mOK             ; Send OK message back to PC
	call    SendMessage
	goto 	WaitCom        	; Go wait for next incomming data

;
; *** END OF MAIN PROGRAM LOOP ***
;



;
; Receive a character from RS232
; (This routine does not return until a character has been received)
; The received character is in the 'W' register
RecLoop
        nop
        btfss   PIR1,RCIF       ; Check for any RX'd data
        goto 	RecLoop         ; Nothing RX'd
        movf    RCREG,W         ; Store the RX'd data in 'W'
        return

;
; Send contents of 'VALUE' to Serial Port as 8-bit binary value
; in ASCII
;
TxBinary
	movlw   mCRLF          	; MSG - CRLF
	call    SendMessage
	movlw   0x08            ; Process 8 bits (0-7)
        movwf   COUNT

NextBit
	movlw   0x31            ; '1'
        btfss   VALUE, 7        ; Test bit 7
	movlw   0x30            ; '0'

        call	TxByte          ; Send ASCII code for bit
	rlf     VALUE, F        ; Rotate left through carry
        decfsz  COUNT, F        ; Decrement bit position counter
        goto    NextBit         ; Process next bit

        movlw   mCRLF          	; MSG - CRLF
	call    SendMessage
        return


;
; Send a byte 'W' to the USART
;
TxByte
        nop
        btfss   PIR1,TXIF       ; TX Buffer empty yet ?
        goto    TxByte          ; No - Keep waiting
        movwf   TXREG           ; Now empty - send this character
        return

FlushRXBuffer
	movf    RCREG,W        	; Flush the RX buffer in bank 0
        movf    RCREG,W
	movf    RCREG,W
        return

;
; Send the specified message text to the serial port
;
SendMessage
        movwf	LOOP            ; Set the OFFSET of the table
SendMes2
        movf    LOOP, W         ; Load pointer to character
        call    MsgTable        ; Returns with 'W' = ASCII char to send or ASCII 0 = EOM
        movwf   TEMP            ; Save returned ASCII character

        sublw   0x00            ; Test for EOM

	btfsc   STATUS, Z    	; EOM character found
        return                  ; Yes

        movf    TEMP, W         ; Recover original value
	call    TxByte          ; Send character to serial port
        incf    LOOP, F         ; Point to next character in msg
        goto    SendMes2        ; Not done yet


;******************************************************************


;
; Setup message table
;
MsgTable
mOK	equ     0x00
        addwf   PCL, F

        retlw   'O'             ; OK
        retlw   'K'
        retlw   '.'
        retlw   d'13'
        retlw   d'10'
        retlw   d'0'            ; EOM

mReady  equ     0x06
        retlw   'R'             ; Ready
        retlw   'e'
        retlw   'a'
        retlw   'd'
        retlw   'y'
        retlw   '.'
        retlw   d'13'
        retlw   d'10'
        retlw   d'0'            ; EOM

mCRLF   equ     0x0F            ; CR+LF
        retlw   d'13'
        retlw   d'10'
        retlw   d'0'            ; EOM
        end