This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430 I2C multi master mode

Hi All,

I am working on I2C multi master mode of MSP430. I checked with TI sample application but there is no any application which is demonstrate MSP430 as multi-master mode.

Can any body give me sample application which is demonstrate MSP430 in multi master mode? What care I should take when arbitration occur? I developed my application which is runs MSP430 in multi-master moder. In my application I am taking care of arbitration but it is some time hang when it read data from i2c slave.

My observation is that when arbitration occur my MSP430 become slave mode, so I am giving reset to I2C controller and set MSP as Master and giving STOP condition.

Here is the code for arbitration interrupt.

        UCB0IFG &= ~UCALIFG; 
        UCB0CTL1 |= UCSWRST;                      // Enable SW reset
        UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC+ UCMM;     // I2C Master, synchronous mode
        UCB0I2COA = 0x24;
        UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
        UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
        UCB0BR1 = 0;
        UCB0I2CSA = 0x09;                         // Slave Address is 048h
        UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation     
       // __delay_cycles(20);                     // Delay required between transaction
          UCB0CTL1 |= UCTXSTP;
          __delay_cycles(30);                     // Delay required between transaction

What I am missing for I2C multi -Master mode of MSP430? Can any body help me?  My ultimate goal is read/write on slave using MSP430 in multi-master mode.

 

Thanks & Regards

Hitesh Patel

  • Krunal Patil said:
    I checked with TI sample application but there is no any application which is demonstrate MSP430 as multi-master mode.

    For a reason. This is rather complex and subject for an appnote rather than a simple example. And it is so uncommon that maybe nobody bothered to invest his time writing one.

    Krunal Patil said:
    What care I should take when arbitration occur

    Arbitration occurs (or is detected) when your master wants to send a high bit but detects a low bit on the data line. Then someone else must have put this bit there (another master). Since until this point the data (actually the slave address) was identical, no harm is done and the 'loser' simply aborts its operation, silently for the bus.
    You need to wait then until a stop condition is detected, and you can try anew.

    Krunal Patil said:
    My observation is that when arbitration occur my MSP430 become slave mode

    Yes. When another master was sending, then you might be the target, so the I2C module goes into slave mode.

    Krunal Patil said:
    I am giving reset to I2C controller and set MSP as Master and giving STOP condition.

    No. Forcibly sending a stop will interrupt the other masters transfer. You rather need to wait for a stop being detected, then reset the I2C module and restart the transfer.

  • Thanks Jens-Michael fro your quick response,

    So when I get arbitration flag, My MSP become slave and check for STOP condition,when stop condition flag is set, I have to reset my MSP and then start to read/write data on my slave.

    I will check it and get back to you if I have any query,,,

    Here I am attaching the code which I have implemented. It works for few arbitration then gets hang.

    3162.i2c_mulitmaster.txt
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //******************************************************************************
    // MSP430F54x Demo - USCI_B0 I2C Master RX multiple bytes from MSP430 Slave
    //
    // Description: This demo connects two MSP430's via the I2C bus. The slave
    // transmits to the master. This is the MASTER CODE. It continuously
    // receives an array of data and demonstrates how to implement an I2C
    // master receiver receiving multiple bytes using the USCI_B0 TX interrupt.
    // ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.045MHz
    //
    // /|\ /|\
    // MSP430F5438 10k 10k MSP430F5438
    // slave | | master
    // ----------------- | | -----------------
    // -|XIN P3.1/UCB0SDA|<-|----+->|P3.1/UCB0SDA XIN|-
    // | | | | |
    // -|XOUT | | | XOUT|-
    // | P3.2/UCB0SCL|<-+------>|P3.2/UCB0SCL |
    // | | | |
    //
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Thanks & Regards,

    Hitesh Patel

  • I'm in the same situation. It's strange TI doesn't support with better documentation this situation.
  • You can't write complete and exhaustive documentation for every possible application. This is like buying a PC for applicaiton development and askign for a complete documentation on how to write any thinkable PC program. Maybe including complete source code for all programs anyone could ever write.

    However, I agree that the multi master operation is a very rare case and neither documentation nor the code examples provide a step-by-step walkthough.
    But this is the job of engineers: implementing the application based on the description of the hardware. And the description is fairly complete.


    About the code posted above (somehow I never answered this back in 2011)
    1) I see a label and goto statements. These are a proper source of problems. And not necessary in this case at all. To jump to the start of the while(1) loop, a simple continue would do, as long as it does not happen inside another while or for loop.
    2) a while loop that incremens a variable for a delay/timing is really nto a good idea. COmpiler optimization and other influences may lead to unpredictable results. In any case, the tiem needed for 20 loops isvery very short. Maybe way shorter than the time needed to jsu tsend a single bit though I2C, let alone a complete start sequence.
    3) in the ISR, the USCI is reset and a stop is sent on arbitration lost. That's bad. If arbitration is lost, the USCI shall not continue. Someone else is using the bus. If you reset the bus and then send a stop, thsi will break the other one's communication. All slaves shall reset their communication when detecting a stop OR start condition. So if arbitration is lost, either wait for detecting a stop or just wait some time and try again. And don't wake from LPM, as main doesn't know that the transfer was aborted due to arbitration loss.
    In general, your ISR doesn't tell main why it was exiting LPM, so main can only guess. You should set a global flag with the result (and maybe leave it to main to retry in case of arbitration loss). Remember to mark this global flag as volatile.

    Regarding the label thing: If you want to jump to the start of an outer loop by a condition inside an inner loop, this can be done this way:
    while(1){
    count = 0;
    do {
    count++;
    if(count==20) break;
    } while (condition1);
    if(count == 20) continue;
    }

    However, it is better to use a timer timeout instead of counting up a variable. More predictable and reliable and not subject to current MCLK speed, interruptions or compiler optimizations.
    Oh, and UCB0I2CSA = 0x09 won't address a slave with 048h. It will generate a start byte of 0x12 for write and 0x13 for read operations. :)

**Attention** This is a public forum