Sunday, 22 June 2014

I2C Communications between two dsPIC30F4012 Micro controller

I2C Introduction

Inter-Integrated Circuit

By Phillips semiconductor

   There are so many sensors out there which have I2C as the only option available for interfacing. The I2C-bus is a de facto world standard that is now implemented in over 1000 different ICs manufactured by more than 50 companies. Additionally, the versatile I2C-bus is used in various control architectures such as System Management Bus (SMBus), Power Management Bus (PMBus), Intelligent Platform Management Interface (IPMI), Display Data Channel (DDC) and Advanced Telecom Computing Architecture (ATCA).
   This tutorial and codes provided are mainly for dsPIC30F4012 but can be used for dsPIC30F4011 also without any change. It can be useful as a refernce for dsPIC33F series of micro-controller from Microchip. I have not interfaced any sensor to dsPIC30F but made two dsPIC's to communicate using I2C as medium.
   dsPIC30F4012 is a 16-bit micro-controller designed and produced by Microchip. These micro-controller are specially designed for DC Motor speed and position control application. This 28-pin PDIP package contains one I2C module besides having 1 SPI(Serial Peripheral Interface), 1 UART and 1 CAN(Controller Area Network) 2.0B Compliant for communication.
   The codes are tested on a pre-built Motor Control Board(MCB). This MCB is a development board build around dsPIC30F4012 micro-controller mounted with Maxon Motor. We need not to concern about board and its circuit. The Pins 17(SCL) and 18(SDA) of Micro-controller are of our interest. These two pins are SDA(Serial DAta) which is responsible for transmitting serial data and SCL(Serial CLock) which is generated by Master. The bus are pulled-up using resistors of 2 K-ohm.
   The I2C bus was developed in the early 1980's by Philips Semiconductors. Its original purpose was to provide an easy way to connect a CPU to peripheral chips in a TV-set.
    I²C is appropriate for peripherals where simplicity and low manufacturing cost are more important than speed. Common applications of the I²C bus are:
  • Reading configuration data from SPD EEPROMs on SDRAM, DDR SDRAM, DDR2 SDRAM memory sticks (DIMM) and other stacked PC boards
  • Supporting systems management for PCI cards, through an SMBus 2.0 connection.
  • Accessing NVRAM chips that keep user settings.
  • Accessing low speed DACs and ADCs.
  • Changing sound volume in intelligent speakers.
  • Turning on and turning off the power supply of system components.
   A particular strength of I²C is the capability of a micro-controller to control a network of device chips with just two general purpose I/O pins and software. Many other bus technologies used in similar applications, such as Serial Peripheral Interface Bus, require more pins and signals to connect devices.
These days most of the sensors have I2C interface. Gyros, Accelero-meters temperature sensors and list continues.
Accelerometer
3-Axis Gyroscope
Temperature Sensor

   So in order to fetch data out of these sensors they must be interfaced with I2C of the micro-controller. Before interfacing any sensor to dsPIC30F, if you interface two dsPICs, one acting as master and other as slave. Then it will be very easy for us to interface any sensor to dsPIC30F.
Now let us first move to basics of I2C.

Basic Characteristics


  • Two-wired bus SDA(Serial DAta) and SCL(Serial CLock)
  • Originally to interact with small no. of devices over short distances
  • Speed 100 kbps(Standard Mode),400 kbps(Fast Mode),3.4 Mbps(High-speed Mode)
  • Data transfer:Serial,8-bit oriented, Bi-directional
  • Master/Slave relationship with Multi-master
  • Master can operate as Transmitter or Receiver
  • Addressing 7-bit or 10-bit addressing
  • Maximum device limit capacitance 400 pF

I2C Features available in dsPIC30F4011/4012



  • Independent Master and Slave logic
  • Multi-Master support. No messages lost in arbitration
  • Detects 7-bit and 10-bit device addresses
  • Detects general call addresses as defined in the I2C protocol
  • Bus Repeater mode. Accept all messages as a slave regardless of the address
  • Automatic SCL clock stretching provides delays for the processor to respond to a slave data request
  • Supports 100 kHz and 400 kHz bus specifications
I2C bus have many devices connected to it. These devices may act as Master or slave.There are various ways in which devices can be configured. Web may have Multi-Master or one master and rest as slave. 


The above picture highlights the master-slave and receiver-transmitter relationships found on 
the I2C-bus. Note that these relationships are not permanent, but only depend on the 
direction of data transfer at that time. The transfer of data would proceed as follows:

1. Suppose micro-controller A wants to send information to micro-controller B:
– micro-controller A (master), addresses micro-controller B (slave)
– micro-controller A (master-transmitter), sends data to micro-controller B 
(slave-receiver)
– micro-controller A terminates the transfer.

2. If micro-controller A wants to receive information from micro-controller B:
– micro-controller A (master) addresses micro-controller B (slave)
– micro-controller A (master-receiver) receives data from micro-controller B 
(slave-transmitter)
– micro-controller A terminates the transfer.
Even in this case, the master (micro-controller A) generates the timing and terminates the 
transfer
   We will go in details in both of the above modes. In first mode i.e. master acting as transmitter and slave as receiver is simple and easy. Hardware setup is already shown above.

I2C Bus Protocol

  • The data transfer may be initiated only when the bus is not busy
  • During the data transfer, the data line must remain stable whenever the SCLx clock line is high. Any changes in the data line, while the SCLx clock line is high, will be interpreted as a Start or Stop condition.

Time Diagram

   Master is the device which sends start bit control serial clock line(either acting as transmitter or receiver) and sends or request data from particular slave then ether resart communication or stop it by sending stop bit. As per the value of I2CBRG registers the master generates clock. Let us have a look at code then we go through it in detail.


#include<p30f4012.h>
_FOSC(CSW_FSCM_OFF & XT); // To use the external crystal
_FWDT(WDT_OFF); // To disable the watchdog timer

void timer1_set(float); // Timer-1 settings
void i2c_set();
float T = 0.002;

void timer1_set(float Ts)  // ******* Timer-1 settings

{
IEC0bits.T1IE = 1;  // Enable Timer-1 interrupt
IFS0bits.T1IF = 0;  // Clear Timer-1 interrupt flag to get next interrupt
PR1 = 7373000*Ts;   // No of clk (count) per controller sampling time
TMR1 = 0;       // Initialise the Timer count
T1CON = 0x8000;     // Starts timer, Internal clock (Fosc/4), prescale 1:1

}

void i2c_set()

{
I2CCON = 0x8000;  //Enable I2C module
I2CBRG = 0x00A;

IEC0bits.MI2CIE = 1;

IFS0bits.MI2CIF = 0;
}

void main()

{
timer1_set(T); // Initialise Timer-1 settings & start timer
i2c_set();   //Initialise I2C Module

I2CCONbits.SEN = 1;

while(I2CCONbits.SEN);
I2CTRN = 0x10;
while(I2CSTATbits.TRSTAT);
// Continue until stop the power
for(;;);
}

// Interrupt service routine (ISR) for interrupt from Timer1

void __attribute__((interrupt, no_auto_psv)) _T1Interrupt (void)
{
IFS0bits.T1IF = 0; // Clear timer 1 interrupt flag

while(I2CSTATbits.ACKSTAT);

I2CTRN = 99;
while(I2CSTATbits.TRSTAT);

} // End of ISR of Timer 1


void __attribute__((interrupt, no_auto_psv)) _MI2CInterrupt (void)

{
IFS0bits.MI2CIF = 0;
}

   The above code is for MPLAB C30 Compiler which is available at Microchip. Here is the one which i have used to compile code. Skipping oscillator setting and timer interrupt setting we are moving directly to I2C settings and registers.
   I2C message comprises of addresses and data which is to be transmitted in a particular sequence.

  1. Master generates start bit, which is nothing but a falling edge when clock line is high. All devices on bus receives start bit and get ready for address to be transmitted by slave.
  2. After generating start bit Master writes address along with ReadWrite bit, to bus. Devices matches transmitted address with their address(if GCEN bit of I2CCON is cleared).The with the transmitted address responds with Acknowledge bit. Now there starts communication between responding slave and Master. No other device have control over any bus line.
  3. Upon receiving acknowledge from slave, Master then transmit data to bus. On reception of each byte of data slave send acknowledge bit to master.
  4. If master wants to read from slave, the bus must be turned in the other direction for the slave to send data to the master which is achieved by sending restart bit. To do this function without ending the message, the master sends a “Repeated Start”. The Repeated Start is followed with a device address byte containing the same device address as before and with the R/W= 1 to indicate slave transmission and master reception.
  5. Slave now sends data bytes to Master, Clock is generated by Master but clock stretching is under control of Slave.
  6. In order to end message stop bit is generated by Master which results in release of clock line and data line by Master.

   Control and Status Registers

   The I2C module has six user-accessible registers for I2C operation. The registers are accessible in either Byte or Word mode. These registers are described below.




  • Control Register (I2CCON): This register allows control of the I2C operation. This is a 16 bit wide registers which contains important setting such as enabling I2C module start enable bit stop bit and other.
  • Status Register (I2CSTAT): This register contains status flags indicating the module state during I2C operation.This contains bit which contains information of transmit and receive buffer. This is also 16 bit register.
  • Receive Buffer Register (I2CRCV): This is the buffer register from which data bytes can be read. The I2CRCV register is a read only register.It is only 8-bit wide for storing one byte of data.
  • Transmit Register (I2CTRN): This is the transmit register, bytes are written to this register during a transmit operation. The I2CTRN register is a read/write register. This is also 8 bit wide.
  • Address Register (I2CADD): The I2CADD register holds the slave device address. This is 10-bit wide as it can be configured in 7-bit or 10-bit mode.
  • Baud Rate Generator Reload Register (I2CBRG): Holds the baud rate generator reload value for the I2C module baud rate generator.This is responsible setting speed of serial clock.
  • Width of registers
       Now lets get into details of the these registers.

    Register I2CCON: Control Register
    Upper Byte:
    R/W-0                U-0              R/W-0              R/W-1              R/W-0              R/W-0              R/W-0              R/W-0
    HC
    I2CEN
    I2CSIDL
    SCLREL
    IPMIEN(1)
    A10M
    DISSLW
    SMEN
    bit 15                                                                                                                                                                     bit 8

    Lower Byte:
    R/W-0              R/W-0

    R/W-0

    R/W-0 HC

    R/W-0 HC

    R/W-0 HC

    R/W-0 HC

    R/W-0 HC
    GCEN
    STREN
    ACKDT
    ACKEN
    RCEN
    PEN
    RSEN
    SEN
    bit 7                                                                                                                                                                       bit 0

    bit 15   I2CEN: I2C Enable bit

    1 = Enables the I2C module and configures the SDA and SCL pins as serial port pins
    0 = Disables I2C module. All I2C pins are controlled by port functions
    This bit is set for enabling I2C module which is written in code as 
    I2CCONbits.I2CEN = 1;       
          bit 14   Unimplemented: Read as 0
          
          bit 13   I2CSIDL: Stop in Idle Mode bit
                     1 = Discontinue module operation when device enters an Idle mode
                     0 = Continue module operation in Idle mode
    This bit is cleared because we want module to continue in idle mode


          bit 12   SCLREL: SCL Release Control bit (when operating as I2C Slave)
                     1= Release SCL clock
                     0= Hold SCL clock low (clock stretch)
                     If STREN = 1
                     Bit is R/W (i.e., software may write ‘0’ to initiate stretch and write ‘1’ to                        release clock)
                     Hardware clear at beginning of slave transmission.
                     Hardware clear at end of slave reception.
                     if STREN = 0
                     Bit is R/S (i.e., software may only write ‘1’ to release clock)
                     Hardware clear at beginning of slave transmission.
    SCREL bit is cleared to release clock. It is coded as
    I2CCONbits.SCREL = 0;

          bit 11   IPMIEN: Intelligent Platform Management Interface (IPMI) Enable bit(1)
                                1 = Enable IPMI Support mode. All addresses Acknowledged
                     0 = IPMI mode not enabled
    IPMIEN mode is not enabled. 

    I2CCONbits.IPMIEN = 0;

          bit 10   A10M: 10-Bit Slave Address bit
    1 = I2CADD is a 10-bit slave address
    0 = I2CADD is a 7-bit slave address
    Set in 7 bit address mode

          bit 9    DISSLW: Disable Slew Rate Control bit
                     1 = Slew rate control disabled
                     0 = Slew rate control enabled
    Slew rate enabled in code

          bit 8    SMEN: SMBus Input Levels bit
          1 = Enable I/O pin thresholds compliant with SMBus specification
          0 = Disable SMBus input thresholds
    SMbus Disabled.

          bit 7    GCEN: General Call Enable bit (when operating as I2C slave)
    1 = Enable interrupt when a general call address is received in the I2CRSR (module is enabled for reception)
    0 = General call address disabled
    Since we have receiver with proper address and we do not want all devices to listen to Master so disabled General call enable bit.

          bit 6    STREN: SCL Clock Stretch Enable bit (when operating as I2C slave) Used in                          conjunction with SCLREL bit.
    1 = Enable software or receive clock stretching
    0 = Disable software or receive clock stretching
    This bit is cleared.

          bit 5     ACKDT: Acknowledge Data bit (When operating as I2C Master. Applicable
                 during master receive) Value that will be transmitted when the software initiates               an Acknowledge sequence.
    1 = Send NACK during acknowledge
    0 = Send ACK during acknowledge
    When we put Master in receiver mode then to send acknowledge to slave this bit is used. I will show the use of this bit in next tutorial where Master is receiver and slave is transmitter.

          bit 4      ACKEN:Acknowledge Sequence Enable bit(When operating as I2C master.                        Applicable during master receive.)
                      1= Initiate Acknowledge sequence on SDA and SCL pins, and transmit ACKDT                        data bit Hardware clear at end of master Acknowledge sequence.
                       0= Acknowledge sequence not in progress
    This bit is also meant for Master in  receiver mode.
          
          bit 3      RCEN:Receive Enable bit (when operating as I2C master)
                      1= Enables Receive mode for I2C. Hardware clear at end eighth bit of master                    receive data byte.
                       0= Receive sequence not in progress
    When master will act as receiver then this bit will be after sending Read bit.
          
          bit 2      PEN:Stop Condition Enable bit (when operating as I2C master)
                     1= Initiate Stop condition on SDA and SCL pins. Hardware clear at end of                           master Stop sequence
                      0= Stop condition not in progress
    To stop communication between Master and slave, Master generates stop bit.
          
          bit 1      RSEN:Repeated Start Condition Enable bit (when operating as I2C master)
                      1= Initiate Repeated Start condition on SDA and SCL pins. Hardware clear at                       end of master Repeated Start sequence 
                      0= Repeated Start condition not in progress
    When master wants to change mode from transmitter to receiver or vice-versa, then restart bit is generated by Master.

          bit 0      SEN:Start Condition Enable bit (when operating as I2C master)
                       1= Initiate Start condition on SDA and SCL pins. Hardware clear at                                     end of master Repeated Start sequence
    This bit is set for generating start bit.




    The above code is for master only the code for slave will be posted in next article.





















    No comments:

    Post a Comment