; labels ending _loop are for loops
; labels ending _isr are at the start of interrupt service routines
; (which must end with retfie)
+; labels starting vector_ are the reset and interrupt entrypoints
; other labels in lowercase are normal subroutines (ending in `return')
; labels in UPPERCASE are defined addresses (in RAM or flash)
PIC_NO res 1
I2C_CTRL res 1
-I2C_CTRL_MASTER equ 0 ; bit 0 of I2C_CTRL is 1=master 0=slave
+I2C_CTRL_MASTER equ 7 ; bit 7 of I2C_CTRL is 1=master 0=slave
;****************************************************************************
; VECTORS: special locations, where the PIC starts executing
; MACROS
;----------------------------------------
-; debugvalue(BYTE)
+; debug(BYTE)
; writes BYTE through the serial port
; serial port hardware must be suitably initialised
; serial port transmit interrupts must be disabled
ifdef SLOW_VERSION
debug macro debugvalue
movlw debugvalue
- call debug_serial_transmit
+ call polling_serial_transmit
endm
endif
-;--------------------
-debugvalue_serial_transmit
-; writes W through the serial port
-; for use by debugvalue macro only
-
- movwf TXREG,0 ; move contents of W (i.e. debugvalue)
- ; to TXREG for transmission
-debugvalue_waitfortsr_loop
- btfss TXSTA,1,0
- bra debugvalue_waitfortsr_loop
-
- return
-
-;****************************************************************************
-
- code
-
;****************************************************************************
; PORTMANTEAU CODE
; which contains lists of checks and calls to function-specific
;----------------------------------------
vector_reset
+
call serial_setup
+
+ debug 'a'
+
call copy_per_pic_data
+
+ debug 'b'
+
call i2c_setup
call enable_interrupts
+
+ debug 'c'
+
goto main
;----------------------------------------
slave_main_loop
call wait_for_i2c_interrupt ; wait for 1st (address) byte
call wait_for_i2c_interrupt ; wait for 2nd (data) byte
- btg LATD,2,0 ; toggle colour of LED
+ btg TRISD,2,0 ; toggle LED on/off
goto slave_main_loop
;----------------------------------------
serial_rx_isr
+ call led_black
+
+ debug 'd'
+
; what we actually do here is faff with I2C to start transmitting
bsf SSPCON2,SEN,0 ; i2c START
call wait_for_i2c_interrupt
+
+ debug 'e'
+
movlw 0x41 ; transmit address 0100 0001
+ movwf SSPBUF,0
+
call wait_for_i2c_interrupt
+
+ debug 'f'
+
btfss SSPCON2,ACKSTAT,0 ; check for ack from slave (=0), if no
goto panic ; then panic, else
movff RCREG,SSPBUF ; copy byte from serial to i2c buffer
bsf SSPCON2,PEN,0 ; i2c STOP
call wait_for_i2c_interrupt
-;!!!fixme - next line is wrong, surely ?
- goto master_main
+ retfie
;***************************************************************************
; SERIAL PORT
bcf IPR1,5,0 ; set to low-priority interrupt
return
+;--------------------
+polling_serial_transmit
+; writes W through the serial port
+; serial port hardware must be suitably initialised
+; serial port transmit interrupts must be disabled
+; will spin until the byte is transmitted
+
+ movwf TXREG,0 ; move contents of W (i.e. debugvalue)
+ ; to TXREG for transmission
+debug_waitfortsr_loop
+ btfss TXSTA,1,0
+ bra debug_waitfortsr_loop
+
+ return
+
+;****************************************************************************
+
+ code
+
;***************************************************************************
; FLASH ID LOCATIONS
movwf TBLPTRU ; PIC number in flash
movlw (F_PIC_NO >> 8) & 0xff
movwf TBLPTRH
- movlw F_PIC_NO
+ movlw F_PIC_NO & 0xff
movwf TBLPTRL
tblrd *+ ; read then increment pointer
movf TABLAT,0,0 ; move pic number into normal memory
movwf PIC_NO,1
+ iorlw '0'
+ call polling_serial_transmit
+
tblrd * ; read i2c
movf TABLAT,0,0 ; move i2c_ctrl byte into normal memory
; now have: PIC number in 400h, i2c control byte in 401h - see
; RAM variables re i2c specific stuff, above
+ iorlw '0'
+ call polling_serial_transmit
+
return
;***************************************************************************
bcf IPR1,SSPIP,0 ; make interrupt low priority
; are we master or slave ?
- btfss I2C_CTRL,I2C_CTRL_MASTER,1 ; test whether PIC is master
+ btfss I2C_CTRL,I2C_CTRL_MASTER ; test whether PIC is master
goto i2c_setup_if_master
goto i2c_setup_if_slave
;----------------------------------------
i2c_isr
banksel PIC_NO ; ser BSR=i2c BSR (4)
- btfsc I2C_CTRL,I2C_CTRL_MASTER ; check =master?, if so
+ btfsc I2C_CTRL,I2C_CTRL_MASTER,1 ; check =master?, if so
goto i2c_master_isr ; goto master interrupt routine
goto i2c_slave_isr ; elso goto interrupt_slave
; are enabled, clearly.
wait_for_i2c_interrupt_loop
+ debug '.'
btfss PIR1,SSPIF,0 ; check if interrupt set, if not, loop
goto wait_for_i2c_interrupt_loop