Welcome, Guest
Username: Password: Secret Key Remember me
  • Page:
  • 1
  • 2

TOPIC: I2C Slave mode?

Re: I2C Slave mode? 8 years 3 weeks ago #15797

  • RogerTango
  • RogerTango's Avatar
  • Offline
  • Fresh Boarder
  • Thanks received: 2
Is it possible to program a PIC to operate as a slave device on a I2C bus?

I know the Picaxe can, but I want to use SF for all my projects.

Andrew

Re: I2C Slave mode? 8 years 3 weeks ago #8406

  • jmessina
  • jmessina's Avatar
  • Offline
  • Senior Boarder
  • Posts: 44
  • Thanks received: 189
The answer to your question is "yes", but I think the answer to the question you really meant to ask is "yes, but there's no library for slave mode so you'll have to write one yourself"

There's a few app notes on using the PIC18 MSSP in slave mode on the microchip site. It shouldn't be too hard to put one together. There's also this http://www.sfcompiler.co.uk/forum/viewtopic.php?t=314 you can check out. There's a link in the last post of the thread. I haven't tried it myself, but octal's usually pretty good at this sort of thing.

It may need some work, depending on the chip you're using.

Re: I2C Slave mode? 8 years 3 weeks ago #8412

  • bitfogav
  • bitfogav's Avatar
  • Offline
  • Fresh Boarder
  • Posts: 9
  • Thanks received: 53
Hi Jerry, that link that Octal posted has been broken for sometime now

Re: I2C Slave mode? 8 years 3 weeks ago #8414

  • Jon Chandler
  • Jon Chandler's Avatar
  • Offline
  • Moderator
  • Posts: 365
  • Thanks received: 352
I think Octal says it's pretty rough with many pieces missing too.

Re: I2C Slave mode? 8 years 3 weeks ago #8415

  • jmessina
  • jmessina's Avatar
  • Offline
  • Senior Boarder
  • Posts: 44
  • Thanks received: 189
It is a little rough and could use some addt'l work.

Didn't know that the link was no good. Here's the files if you're interested...

I2CSlave.bas
{
*****************************************************************************
*  Name    : I2CSlave.BAS                                                   *
*  Author  : Ahmed Lazreg                                                   *
*  Notice  : Copyright (c) 2008 Pocket MicroTechnics                        *
*          : All Rights Reserved                                            *
*  Date    : 15/07/2010                                                     *
*  Version : 1.0                                                            *
*  Notes   : This work is                                                   *
*            I2C slave code, based on Microchip AN734.                      *
*            Slave pic must have i2c hardware (SSP).                        * 
*            Older PIC18 Devices with the PIC16 State Machine               *
*            Refer to AN734 Page 17 for details about new 18F PICs          *
*                                                                           *
*            This work has been inspired by the port done by Gabi MIHAILA   *
*            on PROTON Basic forum.                                         *
*            Thanks to TimB for his help!!!                                 *
*****************************************************************************
}

Module I2CSlave
#option ISR_SHADOW = false

' Registers And bits associated with i2c hardware SSP


' SSPSTAT bits
Dim BF As SSPSTAT.0     ' Buffer Full Status flag
Dim UA As SSPSTAT.1     ' Update Address bit
Dim R_W As SSPSTAT.2    ' Read/Write bit information bit
Dim Start As SSPSTAT.3  ' Start bit
Dim STOPP As SSPSTAT.4  ' STOPP bit
Dim D_A As SSPSTAT.5    ' Data/NOT_Address bit 
Dim CKE As SSPSTAT.6    ' SPI Clock Edge Select
Dim SMP As SSPSTAT.7    ' Sample bit


' SSPCON bits                                   Slave mode 7 bits
Dim SSPM0 As SSPCON1.0  ' SSP mode bits                 0
Dim SSPM1 As SSPCON1.1  ' "                             1
Dim SSPM2 As SSPCON1.2  ' "                             1
Dim SSPM3 As SSPCON1.3  ' "                             0
Dim CKP   As SSPCON1.4  ' Clock, 1 = Enable clock, 0 = clock stretch
Dim SSPEN As SSPCON1.5  ' SSP Enable Bit
Dim SSPOV As SSPCON1.6  ' Receive overflow indicator Bit. In receive mode, a
                          ' Byte is received While the SSPBUF is holding
                          ' previous Byte. Must be cleared in software.
Dim WCOL  As SSPCON1.7  ' Write collision detect Bit. In slave mode, 1 means
                          ' SSBUF written While transmitting previous Word.
                          ' Must be cleared in software.
                        

Dim SSPIF As PIR1.3     ' SSP Interrupt flag Bit

Const SLAVE_ADDR = $22   ' Even number, must match address sent by Master PIC
                          ' To Read from Slave, make address from Master = (address + 1)


Const DataBufferLen = 200    ' RX Buffer size 

Dim DataBufferIndex As Byte ' RX Buffer current Index

Public Dim DataBuffer(DataBufferLen) As Byte
Public Dim DataAvailable As Boolean

Dim CASE_SWITCH As Byte      ' States situation to be used by Select function

' There can be 5 possible i2c states, SSPSTAT register relevant bits
Const STATE1 = $09          ' D_A=0,S=1,R/W=0,BF=1. Master Tx, slave addr
Const STATE2 = $29          ' D_A=1,S=1,R/W=0,BF=1. Master Tx, Data
Const STATE3 = $0C          ' D_A=0,S=1,R/W=1,BF=0. Master Rx, slave addr+1
Const STATE4 = $2C          ' D_A=1,S=1,R/W=1,BF=0. Master Rx, Data with ACK
Const STATE5 = $28          ' D_A=1,S=1,R/W=0,BF=0. Master Rx, Data with NACK  


Interrupt isr_I2C(2)
      SSPIF = 0                                      
      CASE_SWITCH = SSPSTAT And %00101101              
      Select CASE_SWITCH
             
         Case STATE1  'Last Received byte from master was Slave Address
              SSPOV = 0                              
              CKP = 0                                
              DataAvailable = False
              DataBufferIndex = 0                   
              DataBuffer(DataBufferIndex) = SSPBUF  
              CKP = 1                                

         Case STATE2 'Last Received byte from master was Data Byte
              SSPOV = 0                              
              CKP = 0                                
              DataBuffer(DataBufferIndex) = SSPBUF
              Inc(DataBufferIndex)                  
              CKP = 1                                

         Case STATE3                                 
              CKP = 0                                
              SSPBUF = 0 'send dummy data for now (until I implement Slave To Master)
              CKP = 1                                

         Case STATE4                                 
              CKP = 0                                
              SSPBUF = 0  'send dummy data for now (until I implement Slave To Master)
              CKP = 1                                

         Case STATE5                                 
                                                     
                                                     
      EndSelect                                      

      //If SSPSTAT.booleans(4) Then  // I2C Stop received
      //   gDataAvailable = true
      //EndIf
      DataAvailable = SSPSTAT.booleans(4)  

End Interrupt
         
            


Sub InitI2C()
   Input(PORTC.3)            ' Set SCL and SDA as inputs
   Input(PORTC.4)

   'SSPCON1 = $36            ' SSP settings: i2c slave mode, 7-bit address, enable SSP
   'SSPCON1 = %00110111            ' SSP settings: i2c slave mode, 7-bit address, enable SSP
   SSPCON1 = %00111110  ' i2c Slave, 7 bit Addr, I2C Start/Stop interrupts enabled
   
   SSPADD = SLAVE_ADDR      ' Initial slave address setting
   SSPCON2.7 = 0            ' disable  general call address  
   SSPSTAT = 0              ' Clear SSP Status reg
   PIE1.3 = 1               ' Enable SSP interrupts (SSPIE)
   SSPIF = 0                ' Clear SSP Interrupt flag                        
   INTCON.6 = 1             ' Enable perpheral Interrupts
   INTCON.7 = 1             ' Enable Global Interrupts
End Sub

Public Sub EnableI2C_isr()
    Enable(isr_I2C)
End Sub

Public Sub DisableI2C_isr()
    Disable(isr_I2C)
End Sub

InitI2C()
DataAvailable = false

I2CSlaveTest.bas
{
*****************************************************************************
*  Name    : I2CSlaveTest.BAS                                               *
*  Author  : Ahmed Lazreg                                                   *
*  Notice  : Copyright (c) 2010 Pocket MicroTechnics                        *
*          : All Rights Reserved                                            *
*  Date    : 15/07/2010                                                     *
*  Version : 1.0                                                            *
*  Notes   : This prog uses the I2CSlave module to receive two bytes        *
*            from an I2C master.                                            *
*            Bytes will be used as follows:                                 *
*            First byte received is the command.                            *
*               - if zero, portB will be set to zero. (all pins low)        *
*               - if one, second byte in dataBuffer will be the value to    *
*                 output on portB.                                          *
*                                                                           *
*****************************************************************************
}


'Device = 18F8722
Device = 18F452
Clock = 10

Include "utils.bas"
Include "I2CSlave.bas"

Const CMD_LEDS_ON  As Byte = 1
Const CMD_LEDS_OFF As Byte = 2

SetAllDigital()

TRISB = 0
LATB  = $f

EnableI2C_isr()

While true
         ' INSERT Your code here, in this loop
  If I2CSlave.DataAvailable Then
    'I2CSlave.DisableI2C_isr()
    Select I2CSlave.DataBuffer(0) 
        Case CMD_LEDS_ON  : LATB = I2CSlave.DataBuffer(1)  
        Case CMD_LEDS_OFF : LATB = 0
    End Select
    
    I2CSlave.DataAvailable = False
    'I2CSlave.EnableI2C_isr()
  EndIf 
Wend

I2CMasterTest.bas
{
*****************************************************************************
*  Name    : I2CMasterTest.BAS                                              *
*  Author  : Ahmed Lazreg                                                   *
*  Notice  : Copyright (c) 2010 Pocket MicroTechnics                        *
*          : All Rights Reserved                                            *
*  Date    : 15/07/2010                                                     *
*  Version : 1.0                                                            *
*  Notes   : see the note on I2CSlaveTest.bas to understand what's done here*
*          :                                                                *
*****************************************************************************
}

Device = 18F452
Clock = 10

Include "utils.bas"
Include "i2c.bas"


Const SLAVE_ADDR = $22  'this need to be the same as in I2CSlave module

Const CMD_LEDS_ON  As Byte = 1  'same as in I2CSlaveTest
Const CMD_LEDS_OFF As Byte = 2  'same as in I2CSlaveTest


Dim i As Byte

SetAllDigital()

DelayMS(500) 'wait for slave to be ready
I2C.Initialize

i = 1

While true

    'send cmd to clear leds on portB
    I2C.Start
    I2C.WriteByte(SLAVE_ADDR)
    I2C.WriteByte(CMD_LEDS_OFF)
    I2C.Stop 
    
    DelayMS(500)
    
   'send cmd to PowerOn some leds on portB
    I2C.Start
    I2C.WriteByte(SLAVE_ADDR)
    I2C.WriteByte(CMD_LEDS_ON)
    I2C.WriteByte(i)  'this is second byte for the slave, it will be output to portB
    I2C.Stop 
    DelayMS(500)
    i = i + 1   'increment i for next iteration

Wend

You can get the app note (AN734) from the mchip website.

Re: I2C Slave mode? 8 years 2 weeks ago #8417

  • bitfogav
  • bitfogav's Avatar
  • Offline
  • Fresh Boarder
  • Posts: 9
  • Thanks received: 53
Thanks for posting that Jerry, In the mean time I was in-contact with Octal and he said.
I’ll try to find a bit of free time and make it fully compatible with all 18F MCUs.


Heres is the broken link zip file (which includes the app note (AN734) from the mchip website.



Many thanks to Octal for this.



Gavin
Attachments:
  • Page:
  • 1
  • 2
Time to create page: 0.267 seconds