Helpful ReplyHot!How to do Multi Master I2C communication in PIC??

Page: 12 > Showing page 1 of 2
Author
alagappan_nachu
Junior Member
  • Total Posts : 106
  • Reward points : 0
  • Joined: 2014/11/28 00:22:25
  • Location: 0
  • Status: offline
2016/02/16 05:14:27 (permalink)
0

How to do Multi Master I2C communication in PIC??

Hi Techies,
i have 2 Master PIC 16f877a micro controller and one slave PCF8574.
I need to Read/Write slave ic using both PIC(Masters)
I dont know Multi Master I2C communication. but reading data sheet i followed few steps, but not worked!!
I followed these steps
1. Initiate I2C initialization and PIE1bits.SSPIE = 1 ( Enable interrupt )
2. Check BCLIF is set? before read/write, if not set, perform read/write
3. In program i cleared SSPIF after start,stop,restart condition.
 
 
Could anyone send me the simple example code for multi master??
 
Thanks
 
Alagappan
#1
NKurzman
A Guy on the Net
  • Total Posts : 17148
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: online
Re: How to do Multi Master I2C communication in PIC?? 2016/02/16 06:57:29 (permalink)
+1 (2)
No you check the collision flag after each operation. If it is set you give up on the current transmission. Wait then try again.

You also check clock and data are high before you send the start.
#2
Mysil
Super Member
  • Total Posts : 3295
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2016/02/16 09:10:26 (permalink)
+1 (2)
Hi,
Multimaster on a PIC16F877 may be challenging.
Most code and examples you may find on Microchip website,
is likely to have shortcuts and simplifications that will cause problems in a multimaster environment.
In general, Multiple masters require software to handle a lot more if's and but's than a single master. 
and when the bus is occupied, it have to wait before trying to Start again.
The first requirement is to check the 'P' bit in SSPSTAT register before trying to Start.
 
Do you have a Single I2C master  running reliably already?
If so, what code are you using?
If you have I2C running, you may try shorting SDA to ground for a moment while I2C is running, 
and observe if the code recover gracefully.
 
I have I2C running on a PIC16F886, but have never tried to run it on a multimaster bus.
And it is the Slave running on PIC16F886, the Master is running on a PIC18F26K22.
The Slave source code I use on PIC16F886 have been generated by MCC in MPLAB X for PIC18 and modified for use PIC16.
The MSSP modules in PIC16F877, PIC16F886 and PIC18F26K22 are somewhat similar,
so porting the Master code could possibly also be done.
I don't think MCC support PIC16F877 or PIC16F886.
 
There are No simple example code for multi master handling,
Attached is some code generated by MCC, and with my modifications.
 
Regards,
   Mysil
#3
alagappan_nachu
Junior Member
  • Total Posts : 106
  • Reward points : 0
  • Joined: 2014/11/28 00:22:25
  • Location: 0
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2016/02/23 02:38:32 (permalink)
0
I have 2 pic16f877a i2c master talking to single slave. If a slave is also controller, Can it detect from which master it is getting data?.
If i have two master which of same ic, how can i differentiate it one from another?
#4
ric
Super Member
  • Total Posts : 22101
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2016/02/23 02:54:27 (permalink)
+1 (2)
alagappan_nachu
I have 2 pic16f877a i2c master talking to single slave. If a slave is also controller, Can it detect from which master it is getting data?.

What do you mean "If a slave is also controller" ?
Do you mean it is a Microcontroller operating as a slave?
In any case, no, you can't detect which Master is talking to you directly, you would need to add some extra information to the data you send to denote which Master is sending the data.
 

If i have two master which of same ic, how can i differentiate it one from another?

You need to explain in more detail WHY you need to differentiate before possible solutions can be suggested.

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#5
alagappan_nachu
Junior Member
  • Total Posts : 106
  • Reward points : 0
  • Joined: 2014/11/28 00:22:25
  • Location: 0
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2016/02/23 04:43:44 (permalink)
0
Yes Ric,
 
Micro controller operating as slave. Just i am curious to know is there any way to differentiate. that's it.
#6
Mysil
Super Member
  • Total Posts : 3295
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2016/02/23 05:52:31 (permalink)
+1 (2)
 
A master or a slave is a matter of a role in the communication,
not wether the function is performed by a microcontroller, or not.
Also, the I2C protocol have no mandatory identification to distuinguish one master from another. 
In a multi-master bus, I2C slave is expected to respond to respond to whatever master did send the Start signal and address. It is also a purpose of the Repeat Start signal, to make sure that the same master is able to communicate with a slave, without beeing hijacked by another master.
 
There is nothing to prevent you from identifying one master from another by use of data in the bytes following the address.
It is quite common for the first byte after the write address to have a command / operation code / register pointer,
to indicate what kind of data or function is expected to happen next.
This is specified in the datasheet for sensors and other preprogrammed slaves.
If you design a network protocol for I2C communication between microcontrollers, you get to decide. 
 
In PIC microcontrollers with MSSP peripherals, the same MSSPx cannot act as slave and master at the same time. 
For those chips that have two MSSP peripherals, it is possible to connect both to the same SDA and SCL lines, and program one to be slave and the other to act as master.
In PIC32, and I think also most 16 bit PIC chips, the same I2C peripheral may monitor the bus as a slave, while also beeing able to control the same bus as master.
 
Regards,
   Mysil
post edited by Mysil - 2016/02/23 05:55:14
#7
NiKHiL
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2017/11/24 05:02:22
  • Location: India
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/20 01:42:00 (permalink)
0
Hi Mysil,
             I have a doubt regarding your statement "The first requirement is to check the 'P' bit in SSPSTAT register before trying to Start.".
A 'P' bit in SSPSTAT will be set only after sending a Stop condition. But before executing first master read/write 'P' bit will be clear, so waiting for the 'P' bit to set may leads to infinite loop condition. So because of this i used to check for start bit, if it is clear proceed. 
My scenario is also same, two pics 16F877a and 18F45k50 as masters and DS3232 as slave. It will works fine for a random time, say 15mins, 25mins, 1hr, 5hrs like that, after that both controllers stop reading. I simulated this code in proteus, and found that after some time SCL pin is pulled low indefinitely. Pull up resistors are 10K, when the resistor values are reduced(tried 4k7,3k3, 2k2) it woks more time and then stops(with 10k got 15mins avge and with 2k2 got 7hrs max).
When I kept one controller and removed the other controller from the board it works fine and never gets hang. So when both works together problem occurs.
 
PIC16F877A  - MPLAB xide - MPASM
PIC18F45K50- MPLAB xide - xc8 V1.44
 
Please suggest any area i should cross check.
 
Thanks 
Nikhil
post edited by NiKHiL - 2019/03/20 03:01:09
#8
Mysil
Super Member
  • Total Posts : 3295
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/20 05:46:28 (permalink) ☄ Helpfulby NiKHiL 2019/03/21 00:55:54
+2 (2)
Hi,
Testing that (SSPSTATbits.S == 0) is good, to check that bus is not occupied before sending Start signal sequence.
 
You should still check that 'Arbitration lost', aka. 'Bus collision' have not occurred during Start signal or Address transfer.
In MSSP peripheral in 8 bit PIC devices, the Bus Collision bit is in a Interrupt Flag register,
and should be checked, even if interrupts are not used.
If two master devices happen to call the same slave at the same time,
they may even get thru the whole address transfer, and conflict may be detected as bus collision during data transfer.
 
The difference is that if Arbitration loss is detected during Start signal, or Address transfer,
then transaction should be retried with new Start signal by the driver.
If however Bus Collision is detected during Data transfer, then failed transfer should be reported to application code, and retry procedure be dcideded there. 
 
If any kind of error or disturbance happen while master is Reading data from Slave,
and Slave is transmitting data containing 0 bit,
then you may end up with a 'stuck bus': 
Slave is holding SDA line Low to send a 0 bit, waiting for Master to send the next SCL pulse.
But if Master have been Reset from Watchdog Reset, program Crash, debugger program update,
or other reason, then restarted Master program, will see the bus as Busy. 
 
To clear the bus, you may disable the MSSP peripheral, and clock the SCL line by bitbanging,
using the TRIS bit for SCL pin.  9 clock pulses should be sufficient.
Then make a Stop signal sequence, before enabling MSSP peripheral. 
 
    Mysil
#9
NiKHiL
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2017/11/24 05:02:22
  • Location: India
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/20 06:10:10 (permalink)
0
Thanks for the reply.
"To clear the bus, you may disable the MSSP peripheral, and clock the SCL line by bitbanging,
using the TRIS bit for SCL pin.  9 clock pulses should be sufficient." You meant,
 
clear SSPEN
configure SCL as output using tris.
send 9 pulses, Then send a Stop condition
then again configure as input using tris and then enable SSPEN
post edited by NiKHiL - 2019/03/20 06:15:25
#10
qhb
Superb Member
  • Total Posts : 9657
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/20 06:15:57 (permalink)
+2 (2)
It's better to toggle the TRIS bit rather than the PORT bit, so you only ever drive the line low, never high.
Particularly with two Masters on the bus, you could potentially have both of them trying to drive the clock signal in opposite directions.
 
#11
pcbbc
Super Member
  • Total Posts : 819
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/20 06:38:18 (permalink)
+2 (2)
How will you control contention for the resources on the PCF8574 IO expander if both PICs want to use it?
A simpler solution might be to make one of the PIC 16f877a the Master and have it own the PCF8574 exclusively.
Then make the other PIC 16f877a a slave, and have the master service any necessary requests for the PCF8574 coming from the slave PIC.
#12
NiKHiL
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2017/11/24 05:02:22
  • Location: India
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/20 06:55:42 (permalink)
0
Hi Pcbbc
Actually I am implementing I2C multi master multi slave communication with two controllers and one RTC in the bus.
PIC16F877A and PIC18F45K50 have master and slave mode but one mode at a time. RTC DS3232 is in slave mode. Both controller read time from RTC every sec. PIC16F877A writes some data to PIC18F45K50 in random manner and vice versa. So initially both controller will be in slave mode. When one wants to read/write data from the slave, first change to master mode by checking idle bus conditions, do communication and then switch back to slave mode. This is the structure. So i think never two masters will read RTC at the same time. Now i am experiencing some problem and trying to debug it.
Thanks for the reply
#13
NiKHiL
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2017/11/24 05:02:22
  • Location: India
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/20 07:01:28 (permalink)
0
thanks Mysil and qhb.
 
This is what i understood from your comments
 
// this function will be called when BCLIF bit is set
void I2cErrorOccured() {
     I2C_SSPEN_BIT = CLEAR;               // disable MSSP module
     for (uint8 i=0; i<18; i++) {             // toggle tris for 9 pulses
          TRIS_CLK = (uint8)~TRIS_CLK;
          __delay_us(10);                        // for reducing speed to about 100KHZ(not sure its needed or not)
     }
     LAT_DAT = CLEAR;                         // clear SDA pin
     LAT_CLK = SET;                             // set SCL pin
     __delay_us(10);                            // for reducing speed to about 100KHZ(not sure its needed or not)
     LAT_DAT = SET;                             // set SDA pin
     I2C_SSPEN_BIT = SET;                   // enable MSSP module

     I2C_BCLIF_BIT = 0;                        // clear bus collision flag bit
     I2cInitSlave();                                // switch back to slave mode
     __delay_ms(2);
}
 Is it correct?.
post edited by NiKHiL - 2019/03/21 00:25:54
#14
pcbbc
Super Member
  • Total Posts : 819
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/20 13:33:26 (permalink)
+2 (2)
nikhilmsWhen one wants to read/write data from the slave, first change to master mode by checking idle bus conditions, do communication and then switch back to slave mode. This is the structure. So i think never two masters will read RTC at the same time. Now i am experiencing some problem and trying to debug it.
Fine unless...
Both devices check the bus is idle at exactly the same time.... they both discover it is...
Both devices decide it is fine to switch to master mode, which they do...
Both devices attempt to send on the bus simultaneously.
Both devices receive a bus collision.

Just assuming two devices won’t do something at the same time because it is either unlikely, or you have checked some pre-condition (which may change on the very next clock) isn’t going to help.

That’s my understanding anyway.
#15
Mysil
Super Member
  • Total Posts : 3295
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/21 02:30:05 (permalink)
+2 (2)
Hi,
According to Philips - NXP  I2C specification, 
Arbitration Lost, is not an error in I2C multimaster  operations.
This do not mean that it cannot happen,
it means that a Bus Collision signal during Start signal sequence, or during Address transfer,
is part of the protocol, that it is a situation that must be expected to happen, and should be handled and retried by software.
See also:
https://www.nxp.com/docs/en/user-guide/UM10204.pdf
 
    Mysil
#16
Mysil
Super Member
  • Total Posts : 3295
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/21 03:19:46 (permalink)
0
Hi,
Here is my code to check, and if needed clear I2C bus where a slave is holding SDA line Low,
because of a Read transfer that have been failed.
Code watch the state of signal lines for a while, to detect if another Master is already active,
before trying to manipulate the SCL signal.
There are a number of Macro's used to  access registers used for SDA and SCL lines:
/** **************************************************************
 *    Internal function to Check state of I2C bus and toggle SCL signal if needed.
 *
 *    Restriction:
 *        This function work for devices with I2C SDA pin RC4 and SCL pin RC3,
 *        That is 28 pin devices without PPS rerouting.
 *
 *        Mysil    2018 - 05 - 08    Modified for MCC PPS pin macros.
 */
#if     I2Cx_Master_MSSP_Channel == 0    // I2C_INSTANCE == 0
  #define    SCLx_LAT    SCL_LAT        //    LATAbits.LATA1
  #define    SCLx_PORT    SCL_PORT    //    PORTAbits.RA1
  #define    SCLx_TRIS    SCL_TRIS    //    TRISAbits.TRISA1
  #define    SDAx_LAT    SDA_LAT        //    LATAbits.LATA2
  #define    SDAx_PORT    SDA_PORT    //    PORTAbits.RA2
  #define    SDAx_TRIS    SDA_TRIS    //    TRISAbits.TRISA2
#elif I2Cx_Master_MSSP_Channel == 1
  #define    SCLx_LAT    SCL1_LAT    //    LATBbits.LATB6
  #define    SCLx_PORT    SCL1_PORT    //    PORTBbits.RB6
  #define    SCLx_TRIS    SCL1_TRIS    //    TRISBbits.TRISB6
  #define    SDAx_LAT    SDA1_LAT    //    LATBbits.LATB4
  #define    SDAx_PORT    SDA1_PORT    //    PORTBbits.RB4
  #define    SDAx_TRIS    SDA1_TRIS    //    TRISBbits.TRISB4
#elif I2Cx_Master_MSSP_Channel == 2
  #define    SCLx_LAT    SCL2_LAT    //    LATBbits.LATB6
  #define    SCLx_PORT    SCL2_PORT    //    PORTBbits.RB6
  #define    SCLx_TRIS    SCL2_TRIS    //    TRISBbits.TRISB6
  #define    SDAx_LAT    SDA2_LAT    //    LATBbits.LATB4
  #define    SDAx_PORT    SDA2_PORT    //    PORTBbits.RB4
  #define    SDAx_TRIS    SDA2_TRIS    //    TRISBbits.TRISB4
#endif

#if    !(defined SCLx_PORT) && !(defined SDAx_TRIS)
#define    SCLx_LAT    LATCbits.LATC3
#define    SCLx_PORT    PORTCbits.RC3
#define    SCLx_TRIS    TRISCbits.TRISC3
#define    SDAx_LAT    LATCbits.LATC4
#define    SDAx_PORT     PORTCbits.RC4
#define    SDAx_TRIS      TRISCbits.TRISC4
#endif


static void I2C_Check(void)
{    static    int    Collision = 0;
    int c,    i,    n;                        // Check State of the I2C bus
    if (I2C_MASTER_ENABLE_CONTROL_BIT == 1)     // SSP1CON1bits.SSPEN == 1)        // Enabled
    {    if (BCLxIF)                        // Bus collision has occurred
        {    BCLxIF = 0;                    // Clear    // if (SSP1STATbits.S == 0 && SSP1STATbits.P == 0) { SSP1CON1bits.SSPEN = 0;    } else
            Collision += 1;
            if (Collision == 100)
                I2C_MASTER_ENABLE_CONTROL_BIT = 0;    // SSP1CON1bits.SSPEN = 0;    // Disable I2C
    }    }
    if (I2C_MASTER_ENABLE_CONTROL_BIT == 0)     // SSP1CON1bits.SSPEN == 0)        // Not enabled
    {    if (SCLx_PORT == 0)                // Clock line busy
        {    n = 10000;
            while (SCLx_PORT == 0)
            {    n--;
                if (n == 0)                // Clock line timeout is error.
                    __debug_break();    //    while(1);
        }    }
        n = 10000;                        // Test if Data line stay low all the time.
        while (SDAx_PORT == 0)            // Data line busy
        {    n--;
            if ( n == 0)                // Data line timeout
            {                            // Data line jammed
                c = 0;                    // Try to clock the bus
                SCLx_LAT = 0;            // Low
                for ( i = 0; i < 9; i++)
                {    SCLx_TRIS = 0;        // Output
                    __delay_ms(1);        // 1 millisecond
                    if (SDAx_PORT == 0)    // Data line busy
                        c += 1;
                    SCLx_TRIS = 1;        // Let Clock line go High
                    __delay_ms(1);        // 1 millisecond
                }
                                        // Try to signal Stop condition
                SCLx_TRIS = 0;            // Clock line Low
                SDAx_TRIS = 0;            // Data line Low
                __delay_ms(1);            // 1 millisecond
                SCLx_TRIS = 1;            // Let Clock line go High
                __delay_ms(1);            // 1 millisecond
                SDAx_TRIS = 1;            // Data line High
                __delay_ms(1);            // 1 millisecond

                if (c < 8)
                    n = 10;
        }    }
}    }
 

One millisecond delay between toggles, is much longer than needed, 
100 kHz I2C signal frequency is 5 microsecond between each signal edges.
 
    Mysil
 
post edited by Mysil - 2019/03/21 03:28:22
#17
NiKHiL
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2017/11/24 05:02:22
  • Location: India
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/21 05:50:56 (permalink)
0
Hi Mysil,
Thanks for the reference code. . . 
 
if (n == 0) // Clock line timeout is error.
__debug_break(); // while(1);
Is this a software break point for debugging?. If so, what should i do  when control comes here?.
 
When collision count reaches 100, SSPEN will be cleared, and at which condition should I enable SSPEN again?.
#18
Mysil
Super Member
  • Total Posts : 3295
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/22 17:41:25 (permalink)
0
Hi,
SCL line beeing held constantly Low is not a common situation.
It may happen by broken wiring, pull-up resistor disconnected,
or by I2C slave device beeing debugged, holding a Clock Stretch state.
There is nothing the master can do about SCL line == Low, except waiting for slave to release the signal.
The  __debug_break(); is a possibility to examine what is going on,
the software breakpoint will not be activated, if a production build.
__debug_break(); may not be available on PIC16F877A, it should work in PIC18 device.
You may continue the program from the debugger.
 
SDA line == Low,
This, the master code can do something about:
Clocking the I2C bus and making Stop signal sequence, is done in the code following.
 
I usually call the code in message #17 with MSSP peripheral already disabled,
and Enable SSPEN in the calling function, after returning.
 
    Mysil
#19
NiKHiL
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2017/11/24 05:02:22
  • Location: India
  • Status: offline
Re: How to do Multi Master I2C communication in PIC?? 2019/03/23 06:19:17 (permalink)
0
Can I enable/disable Watchdog timer during run time in PIC16F877A?.
Newer pic has WDTCON register, but in 16F877A it is added in Configuration words. It is for resetting devices in I2C bus when stuck. 
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5