chiark / gitweb /
first i2c test program, master pic0 receives byte over serial, transmits
authorceb <ceb>
Sun, 13 Feb 2005 19:26:07 +0000 (19:26 +0000)
committerceb <ceb>
Sun, 13 Feb 2005 19:26:07 +0000 (19:26 +0000)
it to slave pic1, which toggles LED colour (does not check contants of byte)

cebpic/README.protocol
cebpic/i2c-test.asm

index 5e86d969bdb4f1b8a405295dda27f2e56c6dbac5..711ce280125e6cb0605f6a4b30068641b1a95b83 100644 (file)
@@ -22,6 +22,7 @@ Flash memory ID locations
 =========================
 
 Byte 20 0000h
+               bits 7-5        = 000
                bits 4-0        PIC number 
                                (guaranteed to be in range 0..31 inclusive)
                
@@ -34,3 +35,4 @@ Byte 20 0001h
 
 I2C
 ===
+(slave addresses will be 10xxxxx where xxxxx=PIC number above)
index 882221a2d303b5a61867e6ae08ba80d8f96819bc..8966c5d69a568d9f3cd90d3298935a10693692b1 100644 (file)
@@ -1,11 +1,15 @@
+; write a byte to pic0 via the serial port, pic0 will transmit it to
+; pic1, which will then toggle its colour (without checking the contents
+; of the byte)
 
 ; pin 21 (per-pic-led, RD2/PSP2/C1IN) states: 
-;  high H = green, low L = red, float Z = black
+;  high H = blue (=green), low L = orange (=red), float Z = black
 
 
 
         include         /usr/share/gputils/header/p18f458.inc
 
+       radix           dec
 
 ; reserved for NMRA:
 NMRACTRL       equ     0x4     ; byte 4: state relevant to NMRA control
@@ -164,9 +168,9 @@ common_setup
        bsf     SSPSTAT,7,0     ; disable slew rate control
        bcf     SSPSTAT,6,0     ; disable SMBus specific commands
                                ; (whatever that means)
-       
-
+       bcf     SSPCON2,7,0     ; disable general call (for now)
 
+       bcf     IPR1,SSPIP,0    ; make interrupt low priority
 
 
 master_or_slave
@@ -178,30 +182,43 @@ master_or_slave
 
 pic_master_setup
 
+       movlw   0x08
+       movwf   SSPCON1,0       ; set to master mode, clear top 4 bits
+
+; set baud rate
+       movlw   100-1
+       movwf   SSPADD,0        ; set baud rate; clock=Fosc/(4*(SSPADD+1))
+                               ; Fosc=20MHz, currently want clock=50kHz
+                               ; => SSPADD=99
 
+       goto    switch_i2c_on
 
 
 pic_slave_setup
 
+       movlw   0x06
+       movwf   SSPCON1,0       ; set to 7bit slave mode, clear top 4 bits
+                               ; (no extra start/stop interrupts)
+       
+; set slave address
+        movlb   I2C_BUFF_PAGE   ; 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)
+       movwf   SSPADD,0        ; move to slave address register 
+                               ; (bit 7=0, bits 6-0=address)
+
+       goto    switch_i2c_on
+
 
+switch_i2c_on
 
+       bsf     SSPCON1,5,0     ; enable I2C mode
 
 
 ; p68
 ; p314
 ; p 275 ID locs
 
-; test whether master PIC (location 20 0000h bit 0; 1 if true)
-; by doing:
-; set tblptr (tblptru/tblptrh/tblptrl)
-; tblrd *
-; result in tablat
-
-; i2c_master_setup if so, i2c_slave_setup if not
-
-
-
-
 
 ;----------------------------------------------------------------------------
 
@@ -211,17 +228,50 @@ pic_slave_setup
        bsf     RCON,7,0        ; enable priority levels
        bsf     INTCON,7,0      ; enable high-priority interrupts
        bsf     INTCON,6,0      ; enable low-priority interrupts
+       bcf     PIE1,3,0        ; disable master synchronous serial port
+                               ; (MSSP; i.e. enable i2c) interrupts
+                               ; (temporary for this simple program)
        bsf     PIE1,5,0        ; enable USART receive interrupt (p85)
 
 
 ;****************************************************************************
+;****************************************************************************
+
+main
+       movlb   I2C_BUFF_PAGE   ; ser BSR=i2c BSR (4)
+       btfsc   I2C_CTRL,I2C_MASTER     ; check =master?, if so
+       goto    main_master             ; goto master main routine
+       goto    main_slave              ; elso goto slave main routine
+
+
+;----------------------------------------------------------------------------
+
+main_master
 
        call    led_green
 main_loop_led
        goto    main_loop_led
 
 
+;----------------------------------------------------------------------------
+
+main_slave
+
+       call    led_red
+
+slave_loop
+       call    wait_for_i2c_interrupt  ; check buffer full? if not
+       goto    slave_loop              ; loop
+       call    led_red                 ; else light LED red=received
+       call    wait_for_i2c_interrupt  ; wait for 2nd (data) byte
+       btg     LATD,2,0                ; toggle colour of LED
+       goto    slave_loop
+       
+
+
 ;****************************************************************************
+;****************************************************************************
+
 
 interrupt_high
        debug   'H'     
@@ -233,24 +283,59 @@ interrupt_high
 interrupt_low
 
 ; check which interrupt.
-       debug   'L'     
+       btfsc   PIR1,SSPIF,0    ; check if MSSP interrupt generated, if so
+;      goto    interrupt_ms    ; check whether master or slave
+       goto    panic           ; nothing should generate these ATM....
+        btfsc   PIR1,5,0        ; check whether serial receive interrupt bit set
+                               ; if so
+       goto    serial_receive  ; receive serial
+       debug   'L'             ; else panic
        goto    panic
-; serial only?
 
 
-;****************************************************************************
+interrupt_ms
+       movlb   I2C_BUFF_PAGE   ; ser BSR=i2c BSR (4)
+       btfsc   I2C_CTRL,I2C_MASTER     ; check =master?, if so
+       goto    interrupt_master        ; goto master interrupt routine
+       goto    interrupt_slave         ; elso goto interrupt_slave
 
-serial_receive
-       debug   'S'     
+
+;----------------------------------------------------------------------------
+interrupt_master
+       debug   'm'
        goto    panic
-; serial byte to say pic #, LED flash pattern, look pattern up in table? 
-; (to test use of flash memory and lookup therein)
-; think about serial msg format (in general and (simpler) for here)
 
+;----------------------------------------------------------------------------
+interrupt_slave
+       debug   's'
+       goto    panic
 
 ;****************************************************************************
 
+serial_receive
+       bsf     SSPCON2,SEN,0           ; i2c START
+       call    wait_for_i2c_interrupt
+       movlw   0x41                    ; transmit address 0100 0001
+       call    wait_for_i2c_interrupt
+       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
+       call    wait_for_i2c_interrupt
+       btfss   SSPCON2,ACKSTAT,0       ; check for ack from slave (=0), if no
+       goto    panic                   ; then panic, else
+       bsf     SSPCON2,PEN,0           ; i2c STOP
+       call    wait_for_i2c_interrupt
+       goto    main_master
+       
+
+wait_for_i2c_interrupt
+       btfss   PIR1,SSPIF,0    ; check if interrupt set, if not, loop
+       goto    wait_for_i2c_interrupt
+       bcf     PIR1,SSPIF,0    ; clear interrupt bit
+       return
 
+
+;****************************************************************************
 led_green
         bcf     TRISD,2,0       ; make pin RD2 an output (DS100)
         bsf     LATD,2,0        ; set pin RD2 H (green)