;;================================================= ;; MCP_master.asm ;; ;; part of the GPL'ed DIY 744 MCP ;; ;; This is the program that runs on the master PIC of the MCP. ;; Its responsibilities are: ;; * communication with the PC via RS-232 ;; * communication with the display PIC ;; * and the key matrix controller PIC ;; via a 2-wire serial bit-banging protocol ;; ;; ;; Copyright (c) 2003 by Manuel Bessler ;; ;; The full text of the legal notices is contained in the file called ;; COPYING, included with this distribution. ;; ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 2 ;; of the License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;; ;;================================================= ;;================================================= ;; modifications: ;; added PIC-TO-PIC sender ;;================================================= ;;================================================= ;; Credits: ;; The UART Test Program of ;; Lars Petersen, oz1bxm@qsl.net ;; www.qsl.net/oz1bxm/PIC/pic.htm ;;================================================= LIST P=16F628, R=DEC ; use a PIC16F628, use decimal system as standard #include "p16f628.inc" ; include appropriate processor definitions ; set config bits: __config _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON ERRORLEVEL -302 ; disable 302 assembler warning messages ; define SRAM data areas/variables/file registers CBLOCK 0x20 dataL delaycounter_inner,delaycounter_outer p2pdata,p2pbitcounter ENDC ;;------------------------------- ;; program start point ;;------------------------------- ORG 0x000 ; program start point at 0x000 GOTO init ;;------------------------------- ;; interrupt vector ;;------------------------------- ORG 0x0004 ; interrupt vector interrupt: ; global interrupts automatically disabled on entry! RETFIE ;;------------------------------- ;; generic initialization ;;------------------------------- init: CLRF PORTA ; set portA pins low CLRF PORTB ; set portB pins low MOVLW 0x07 MOVWF CMCON ; turn off comparators, all pins digital BCF STATUS,RP1 BSF STATUS,RP0 ; sel bank 1 CLRF TRISA ; set portA direction registers to all input CLRF TRISB ; set portB direction registers to all input BCF STATUS,RP0 ; sel bank 0 ;;------------------------------- ;; application specific initialization ;;------------------------------- BSF PORTB,2 ; set TX=1 BSF STATUS,RP0 ; sel bank 1 MOVLW b'00111111' ; RA6,7 outputs, others inputs MOVWF TRISA MOVLW b'11111011' ; RB1/RX input, RB2/TX output MOVWF TRISB ;;------------------------------------ ;; RS-232 Serial Port initialization ;;------------------------------------ ;; serial port Parameters: 19200bps, 8N1 ;;------------------------------------ MOVLW 0x0C ; 0x19=9600bps (0x0C=19200bps) MOVWF SPBRG ; set baud rate CLRF TXSTA BSF TXSTA,BRGH ; set BRGH high baud rates BSF TXSTA,TXEN ; enable async send BCF STATUS,RP0 ; sel bank 0 CLRF RCSTA BSF RCSTA,SPEN ; enable async serial port BSF RCSTA,CREN ; enable continuous receive ;;------------------------------- ;; let serial port stabilize ;;------------------------------- ; CALL delay250ms clrf dataL settle decfsz dataL,F goto settle MOVF RCREG,W MOVF RCREG,W MOVF RCREG,W ; flush receive register ;;------------------------------- ;; main loop ;;------------------------------- CALL send_alive ;send "16F628 alive" main: CALL rs232_recv ; recv char from PC via RS-232 CALL rs232_send ; echo back received char ; CALL p2psend ; and send it to display unit GOTO main ;;------------------------------- ;; PIC-TO-PIC comm sender (bit-banging type) routines ;;------------------------------- ;; RA6: Clock ;; RA7: Data ;; protocol: >=3ms pause between bytes ;; sends away data in W ;;------------------------------- p2psend: MOVWF p2pdata ; byte to send is passed in W, save it in p2pdata MOVLW 0x08 ; ???? 8 or 7 ???? protocol wants 8 bits per byte MOVWF p2pbitcounter ; this register keeps track of the number of received bits ; hold clock low for 4ms BCF PORTA,6 CALL delay1ms CALL delay1ms CALL delay1ms CALL delay1ms next_bit: RLF p2pdata,f ; roll next bit into carry BCF PORTA,7 ; data pin low BTFSC STATUS,C ; Carry contains the bit to send BSF PORTA,7 ; case C is set: data pin high BSF PORTA,6 ; clock high CALL delay1ms ; give receiver some time to latch bit BCF PORTA,6 ; clock cycle end, low CALL delay1ms ; let clock remain low for a short while DECF p2pbitcounter,f ; make sure we send out not more nor less than 8 bits BTFSS STATUS,Z ; p2pbitcounter == 0 ? then GOTO next_bit RETURN ;;------------------------------- ;; RS-232 receive routine ;;------------------------------- ;; received char is left in W ;; loops until a char is actually received ! ;;------------------------------- rs232_recv: BTFSS PIR1,RCIF ; poll for new received data GOTO rs232_recv MOVF RCREG,W ; serially received byte -> W ; BSF RCSTA,CREN ; make sure receive errors don't block, (re-)enable continuous receive RETURN ;;------------------------------- ;; RS-232 send routine ;;------------------------------- ;; send char in W via RS-232 ;; waits until sending is done ! ;;------------------------------- rs232_send: MOVWF TXREG ; send out data in W via serial port BSF STATUS,RP0 ; sel bank 1 rs232_send_wait: BTFSS TXSTA,TRMT GOTO rs232_send_wait ; wait till byte sent BCF STATUS,RP0 ; sel bank 0 RETURN ;;------------------------------- ;; send a "alive" message to PC ;;------------------------------- ;; sends string "MCP744REPORTING" ;;------------------------------- send_alive: MOVLW 'M' CALL rs232_send MOVLW 'C' CALL rs232_send MOVLW 'P' CALL rs232_send MOVLW '7' CALL rs232_send MOVLW '4' CALL rs232_send MOVLW '4' CALL rs232_send MOVLW 'R' CALL rs232_send MOVLW 'E' CALL rs232_send MOVLW 'P' CALL rs232_send MOVLW 'O' CALL rs232_send MOVLW 'R' CALL rs232_send MOVLW 'T' CALL rs232_send MOVLW 'I' CALL rs232_send MOVLW 'N' CALL rs232_send MOVLW 'G' CALL rs232_send ; send line break CRLF MOVLW 0x0D ; CR CALL rs232_send MOVLW 0x0A ; LF CALL rs232_send RETURN delay1ms: MOVLW 1 ; 50 * 1msec = 50msec MOVWF delaycounter_outer delay1_outer: MOVLW 200 ; 200*5usec = 1msec MOVWF delaycounter_inner delay1_inner: ; inner loop takes 5usec @4MHz NOP NOP DECFSZ delaycounter_inner,F GOTO delay1_inner DECFSZ delaycounter_outer,F GOTO delay1_outer RETURN delay250ms: MOVLW 250 ; 50 * 1msec = 50msec MOVWF delaycounter_outer delay250_outer: MOVLW 200 ; 200*5usec = 1msec MOVWF delaycounter_inner delay250_inner: ; inner loop takes 5usec @4MHz NOP NOP DECFSZ delaycounter_inner,F GOTO delay250_inner DECFSZ delaycounter_outer,F GOTO delay250_outer RETURN ;;================================================= ;; End of program ;;================================================= END