chiark / gitweb /
BUGFIXES
authorian <ian>
Wed, 23 Feb 2005 21:36:30 +0000 (21:36 +0000)
committerian <ian>
Wed, 23 Feb 2005 21:36:30 +0000 (21:36 +0000)
get address value right: bottom bit is always read/write, so:
 in slave mode: shift value for SSPADD left
 in master mode: choose slave address 0x82 = I2C addr 0b1000001, write

NICETIES
disable serial rx and tx interrupts in slave mode
new ifbit1 and ifbit0 macros

DEBUGGING IMPROVEMENTS
master does not panic immediately before sending address
print calculated SSPADD value via debughf in slow slave mode
a few other "debug" statements
debughf gets nybbles > 0x9 right (!)

cebpic/i2c-test.asm

index 58b6bea2b454b3b39e20fce68c806ed08aa751b8..b15ccc5de60b8a4669d0e910b83ab4ea21bdbadd 100644 (file)
@@ -75,6 +75,22 @@ I2C_CTRL_MASTER      equ     7       ; bit 7 of I2C_CTRL is 1=master 0=slave
 ;****************************************************************************
 ; MACROS
 
+;----------------------------------------
+; ifbit1(REGISTER,BITNUMBER)
+;      executes the next instruction but only if bit BITNUMBER
+;      in REGISTER (which must be in the access bank) is set
+ifbit1 macro REGISTER, BITNUMBER
+       btfsc   REGISTER, BITNUMBER, 0
+       endm
+
+;----------------------------------------
+; ifbit0(REGISTER,BITNUMBER)
+;      executes the next instruction but only if bit BITNUMBER
+;      in REGISTER (which must be in the access bank) is clear
+ifbit0 macro REGISTER, BITNUMBER
+       btfss   REGISTER, BITNUMBER, 0
+       endm
+
 ;----------------------------------------
 ; debug(BYTE)
 ;      writes BYTE through the serial port
@@ -135,7 +151,7 @@ debughf_digit
        sublw   10
        sublw   0
        bn      debughf_digit_ifnot_ge10
-       addlw   'a'-'0'
+       addlw   'a'-('0'+10)
 debughf_digit_ifnot_ge10
        addlw   '0'+10
        goto    polling_serial_transmit
@@ -176,6 +192,7 @@ main
        debughf SSPSTAT
        debughf SSPCON1
        debughf SSPCON2
+       debughf SSPADD
 
        banksel I2C_CTRL                ; ser BSR=i2c BSR (4)
        btfsc   I2C_CTRL,I2C_CTRL_MASTER,1 ; check =master?, if so
@@ -236,13 +253,18 @@ master_main_loop
 slave_main
 ;      main program for slave PICs
 
+       bcf     PIE1,5,0        ; disable serial receive interrupt
+       bcf     PIE1,4,0        ; disable serial transmit interrupt
        call    led_red
+       debug   'S'
 
 slave_main_loop
        call    wait_for_i2c_interrupt  ; wait for 1st (address) byte
        call    led_green
+       debug   'G'
        call    wait_for_i2c_interrupt  ; wait for 2nd (data) byte
        call    led_black
+       debug   'B'
        goto    slave_main_loop
 
 ;----------------------------------------
@@ -256,17 +278,19 @@ serial_rx_isr
        call    wait_for_i2c_interrupt
 
        debug   'e'
-       call    panic
 
-       movlw   0x41                    ; transmit address 0100 0001
-       movwf   SSPBUF,0
+       movlw   0x82                    ; transmit 1000 0010
+       movwf   SSPBUF,0                ; (ie address 1000001, read=0)
 
        call    wait_for_i2c_interrupt
 
        debug   'f'
 
-       btfsc   SSPCON2,ACKSTAT,0       ; check for ack from slave (=0), if no
+       ifbit1  SSPCON2,ACKSTAT         ; check for ack from slave (=0), if no
        goto    panic                   ; then panic, else
+
+       debug   'g'
+
        movff   RCREG,SSPBUF            ; copy byte from serial to i2c buffer
        call    wait_for_i2c_interrupt
        btfsc   SSPCON2,ACKSTAT,0       ; check for ack from slave (=0), if no
@@ -413,8 +437,9 @@ i2c_setup_if_slave
        banksel PIC_NO          ; set BSR=i2c BSR (4)
        movf    PIC_NO,0,1      ; copy pic_no to W (000xxxxx)
        iorlw   0x40            ; change top 3 bits t 010 (010xxxxx)
+       rlncf   WREG,0,0        ; shift, bottom bit is r/w (10xxxxx0)
        movwf   SSPADD,0        ; move to slave address register 
-                               ; (bit 7=0, bits 6-0=address)
+                               ; (bits 7-1=address, bit 0=0)
 
 i2c_setup_endif_master_slave
        bsf     SSPCON1,5,0     ; enable I2C mode
@@ -444,8 +469,8 @@ wait_for_i2c_interrupt
 ;      then returns.  should not usually be used if I2C interrupts
 ;      are enabled, clearly.
 
-wait_for_i2c_interrupt_loop
        debug   '.'
+wait_for_i2c_interrupt_loop
        btfss   PIR1,SSPIF,0    ; check if interrupt set, if not, loop
        goto    wait_for_i2c_interrupt_loop