;********************************************************************** ; * ; Filename: picbus.asm * ; Date: * ; File Version: * ; * ; Author: el@jap.hu * ; Company: * ;********************************************************************** ; Notes: ; ; 2400 baud serial PIC bus ; for interPIC communication ; btw. 1 MASTER, 1-15 SLAVE(s) ; ;********************************************************************** ;HISTORY ; ;000-20000129 ;initial version ; ;002-20000130 ;slave first version ; ;003-20000130 ;master first version ; ;005-20010121 ;master&slave first working ping-pong ; ;006-20010225 ;adapt to 01x (int-driven) series & f628 ; ;008-20010308 ;check dev4 for stats, dev5 or RF received codes ; ;009-20010513 ;check dev4 and dev5 for stats ; ;010-20010521 ;4-dev check and display (2-5) ;********************************************************************** ;define mhz8 #define F628 ;define C508 #define MASTER ;define SLAVE #ifdef F628 list p=16F628 ; list directive to define processor #include ; processor specific variable definitions #include "lcdlib.inc" __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _LVP_OFF ;WDT=watchdog, PWRTE=power on timer, XT=external crystal osc ;#define RXBIT PORTA, 4 #define RXBIT PORTB, 0 TXMASK EQU 0x10 TXPORT EQU PORTA DIRTX macro movlw TXMASK iorwf txport_shadow, W movwf TXPORT movlw 0xef tris TXPORT endm DIRRX macro ; movlw 0xff ; tris TXPORT endm .mainda UDATA #endif #ifdef C508 list p=12c508 #include __CONFIG _CP_OFF & _WDT_OFF & _MCLRE_OFF & _IntRC_OSC .mainda UDATA 0x07 #endif ;***** VARIABLE DEFINITIONS bt res 1 btcnt res 1 dlcnt res 1 txport_shadow res 1 bfcnt res 1 ;retries res 1 ; SLAVE ;polldev res 1 ; MASTER buffer res 0 byte0 res 1 command res 1 data0 res 0x10 chksum res 1 ptr0 res 1 counters res 0x0c #ifdef MASTER DEVID EQU 0x00 ; MASTER must be 0 #else DEVID EQU 0x10 ; slave ID #endif ;********************************************************************** #ifdef F628 vectors CODE 0 ; processor reset vector nop goto main ; go to beginning of program nop nop ;ORG 0x004 ; interrupt vector location retfie prog CODE 5 messages movwf PCL GLOBAL messages msg_err dt "error ", 0 #endif #ifdef C508 CODE 0 movwf OSCCAL ;C508 HARDWARE INIT -- missing -- goto main #endif #ifdef SLAVE rxwgap ; wait for a gap at least 5ms long ; exit at the end of the gap movlw 0xb0 ; max LOW is 5ms movwf TMR0 ; wait for the end of the LOW signal rxwgap0 movf TMR0, W btfsc STATUS, Z retlw 0x82 ; short-circuit error btfss RXBIT goto rxwgap0 movlw 0xb0 ; test for the gap min 5ms movwf TMR0 rxwgap1 movf TMR0, W bz rxwgap2 ; 5 ms is over! btfsc RXBIT goto rxwgap1 ; gap is less than 5ms, need to start over! retlw 0x83 rxwgap2 ; still gap, wait for max 10ms movlw 0x64 movwf TMR0 rxwgap3 movf TMR0, W btfsc STATUS, Z retlw 0x84 ; gap too long btfsc RXBIT goto rxwgap3 retlw 0 ; OK, startbit present #endif rxwhead ; wait 4 a startbit then receive a byte ; timeout is ~1 msec (default) ; movlw 0xf0 rxwhead2 ; same with custom timeout movwf TMR0 rxw0 movf TMR0, W bz rxtimeout btfsc RXBIT ; wait 4 a startbit (L) goto rxw0 rx ; receive a byte into bt ; after the arrive of a startbit call dlyhalfbit ; half bit delay movlw 8 movwf btcnt rx0 call dlyhalfbit call dlyhalfbit bcf STATUS, C btfsc RXBIT bsf STATUS, C rrf bt, F decfsz btcnt, F goto rx0 call dlyhalfbit call dlyhalfbit btfsc RXBIT ; STOPbit must be H retlw 0 ; OK, byte is in bt retlw 0x80 ; receive error rxtimeout retlw 0x81 ; timeout waiting tx ;transmit the byte in W movwf bt movlw 8 movwf btcnt ;startbit movf txport_shadow, W movwf TXPORT call dlyhalfbit call dlyhalfbit txcycle rrf bt, F movlw TXMASK btfss STATUS, C clrw iorwf txport_shadow, W movwf TXPORT call dlyhalfbit call dlyhalfbit decfsz btcnt, F goto txcycle movlw TXMASK iorwf txport_shadow, W movwf TXPORT call dlyhalfbit call dlyhalfbit return #ifdef mhz8 dlyhalfbit movlw 0x88;44 #else dlyhalfbit movlw 0x44 #endif movwf dlcnt dlycycle decfsz dlcnt, F goto dlycycle return silence ; delay 8.5 msec ; movlw 0x29 silence2 movwf bfcnt silcycle call dlyhalfbit decfsz bfcnt, F goto silcycle return SUMCALC macro ; calculate the sum of buffer chksum_set movlw buffer movwf FSR movlw 0x0f andwf byte0, W movwf bfcnt movlw 2 addwf bfcnt, F clrw chksum_set0 addwf INDF, W incf FSR, F decfsz bfcnt, F goto chksum_set0 clrf chksum subwf chksum, F endm SUMCHK macro err_label ; check the sum of buffer, set W & Z chksum_chk movlw buffer movwf FSR movlw 0x0f andwf byte0, W movwf bfcnt movlw 3 addwf bfcnt, F clrw chksum_chk0 addwf INDF, W incf FSR, F decfsz bfcnt, F goto chksum_chk0 andlw 0xff btfss STATUS, Z goto err_label ; chksum error... endm BUFTX macro txmsg movlw buffer movwf FSR movlw 0x0f andwf byte0, W movwf bfcnt movlw 2 addwf bfcnt, F txmsg0 movf INDF, W call tx incf FSR, F decfsz bfcnt, F goto txmsg0 movf chksum, W call tx endm BUFRX macro ver, err_label ; receive a buffer, W=read timeout if ver == 0 call rxwgap andlw 0xff bnz err_label call rx else call rxwhead endif andlw 0xff bnz err_label ; movf bt, W movwf byte0 ; receive response movlw command movwf FSR movlw 0x0f andwf byte0, W movwf bfcnt movlw 2 addwf bfcnt, F rxmsg2 movlw 0xf0 call rxwhead2 andlw 0xff bnz err_label; error receiving movf bt, W movwf INDF incf FSR, F decfsz bfcnt, F goto rxmsg2 ; received buffer ; check DEVID movlw 0xf0 andwf byte0, W movwf bt movlw DEVID subwf bt, W ; btfss STATUS, Z ; goto err_label ; not me... btfsc STATUS, Z goto rx_ok movlw 0x85 goto err_label ; not me... rx_ok ; all done endm main #ifdef F628 ;F628 HARDWARE INIT ; TMR0 1:32 on Fosc/4 movlw 7 movwf CMCON ; disable an. comparators! clrf PORTA clrf PORTB clrf txport_shadow #ifdef mhz8 movlw 0x86;5 #else movlw 0x85 #endif clrwdt OPTION ; presc on TMR0, incr on osc, no pullup DIRTX ; set PORTA4 out movlw 1 TRIS PORTB ; PORTB0 input call lcd_init movlw 0xcf ;call lcd_cmdout movlw 7 ;call lcd_cmdout #endif #ifdef SLAVE warm ; loop ; do WORK here ; done WORK, now chat DIRRX rxmsg ; read a message movlw 5 ; number of retries+1 movwf retries rxmsg0 decfsz retries, F goto rxmsg1 ; ERROR (timeout trying) goto loop ; go WORK again rxmsg1 BUFRX 0, rx_err_b SUMCHK rx_err_c ; received message, do WORK ; done WORK, construct response movlw 0x0 movwf byte0 movlw 0x55 movwf command SUMCALC DIRTX BUFTX movlw msg_rx call lcd_strout movlw command call lcd_hexout ; response sent goto loop rx_err_c movlw 'c' call lcd_chrout goto rxmsg0 rx_err_b movwf bt movlw 0x83 subwf bt, W bz rxmsg0 movlw 0x84 subwf bt, W bz rxmsg0 movlw 0x85 subwf bt, W bz rxmsg0 movlw 'b' call lcd_chrout movlw 0x50 subwf bt, W call lcd_chrout goto rxmsg0 #endif SLAVE #ifdef MASTER #define ROK 0x60 #define RERR 0x61 ; zero out counters movlw counters movwf FSR movlw 0x0c movwf bfcnt null_out clrf INDF incf FSR, F decfsz bfcnt, F goto null_out warm loop ; device poll loop d2_chk movlw 0x80 call lcd_cmdout movlw '2' call lcd_chrout movlw ':' call lcd_chrout movlw 0x2f call send_junk movlw 0x20 movwf byte0 movlw 0x5e ; CVER movwf command call communicate btfsc STATUS, Z goto d2_err d2_ok movf data0, W call lcd_hexout movf data0+1, W call lcd_hexout movf data0+2, W call lcd_hexout goto d3_chk d2_err movlw msg_err call lcd_strout d3_chk movlw 0x88 call lcd_cmdout movlw '3' call lcd_chrout movlw ':' call lcd_chrout movlw 0x3f call send_junk movlw 0x30 movwf byte0 movlw 0x5d ; STATS movwf command call communicate btfsc STATUS, Z goto d3_err d3_ok movf data0, W call lcd_hexout movf data0+2, W call lcd_hexout movf data0+4, W call lcd_hexout goto d4_chk d3_err movlw msg_err call lcd_strout d4_chk movlw 0xc0 call lcd_cmdout movlw '4' call lcd_chrout movlw ':' call lcd_chrout movlw 0x4f call send_junk movlw 0x40 movwf byte0 movlw 0x5d ; STATS movwf command call communicate btfsc STATUS, Z goto d4_err d4_ok movf data0, W call lcd_hexout movf data0+2, W call lcd_hexout movf data0+4, W call lcd_hexout goto d5_chk d4_err movlw msg_err call lcd_strout d5_chk movlw 0xc8 call lcd_cmdout movlw '5' call lcd_chrout movlw ':' call lcd_chrout movlw 0x5f call send_junk movlw 0x50 movwf byte0 movlw 0x5d ; STATS movwf command call communicate btfsc STATUS, Z goto d5_err d5_ok movf data0, W call lcd_hexout movf data0+2, W call lcd_hexout movf data0+4, W call lcd_hexout goto loop d5_err movlw msg_err call lcd_strout goto loop communicate call silence SUMCALC BUFTX BUFRX 1, c_err SUMCHK c_err bcf STATUS, Z return c_err bsf STATUS, Z return send_junk movwf byte0 movlw 4 movwf bfcnt s0 movf byte0, W call tx decfsz bfcnt, F goto s0 return #endif MASTER end