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.

Missing 9th clock bit on I2C START of MSP430F2618 when slave device is present

Other Parts Discussed in Thread: MSP430F2618, TLV320ADC3101

Hi,

I'm using the following code to configure the UCB1 of an msp430F2618 for I2C communication as master with the TLV320ADC3101 Eval board from TI.
The I2C address of the ADC3101 is 0x30. When I initiate the START I only get 8 clock bytes on SCL line, though the slave device seems to respond as the
data line is held low after the 8th clock bit. If I put the wrong address for the slave device and rerun the code, I see the 9th acknowledge clock bit and the data line
goes high after the 8th clock bit as expected since there is no responding I2C device. 

Why is this 9th clock bit not being generated by the MSP430 acting as master?

Thanks,
Teddy

 //-------------------------------------------------------

// Configure UCB1 for I2C communications with ADC3101
//--------------------------------------------------------
  P5SEL |= 0x06;                           // Assign I2C pins to USCI_B1 (P5.1=SDZ, P5.2=SCL
  UCB1CTL1 |= UCSWRST;          // Enable SW reset
  UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;    // I2C Master, synchronous mode
  UCB1CTL1 = UCSSEL_2 + UCSWRST;           // Use SMCLK, keep SW reset
  UCB1BR0 = 40;                            // fSCL = SMCLK/40
  UCB1BR1 = 0;

  UCB1I2CSA = 0x018;                      // ADC3101 on the Eval board Slave Address is 0x030 (30>>1 = 0x18)
  UC1IFG &= ~0x0C;                         // clear any pending UC1 interrupts
   UCB1CTL1 &= ~UCSWRST;       // Clear SW reset, resume operation 

  UCB1CTL1 |= 0x10;                    // Set in transmit mode
  UCB1CTL1 |= 0x2;                       // initiate a START pulse
  while(1);

  • Teddy13640 said:
    When I initiate the START I only get 8 clock bytes on SCL line, though the slave device seems to respond as the
    data line is held low after the 8th clock bit.

    It stops there because the slave has responded and the hardware does not know how to continue. At this moment, there are two possible choices: either you write somethign to TXBUF so it can be sent, or you set the UCSTP bit to end the transfer.
    In general, when UCTR is set (I2C master send), the USCI will stop at the ACK bit if ACK is set, until either UCSTP is set or data is provided to TXBUF.
    If the slave does not resopond (or sends a NACK as response to a transmitted byte), there is only one choice: the transmission ends immediately (and UCNACKIFG is set).

    So the observed behavior is exactly as to expect.

  • Thanks Jens-Michael,

     

    I tried issuing the STOP right after the completion of the 8 bit address and the 9th bit appeared!

    Best Regards,

    Teddy

     

  • Teddy13640 said:
    I tried issuing the STOP right after the completion of the 8 bit address and the 9th bit appeared!


    That's it. :)

    The 'correct' moment to do so is when UCSTT is reset by the hardware. It means that the hardware has sent the address and is waiting for user action.
    At this point you should check for UCNACKIFG bit. If it is set, the slave hasn't answered, if it is clear, the slave answered.

    btw: UCTXIFG is set the moment you set UCSTT, and resets if you write something to TXBUF or if UCNACKIFG is set (which also would discard anything written to TXBUF too)

  • I'm afraid that following the initiation of the START, my UCTXSTT (I'm using UCB1) never clears. If I follow the start with a character transmit, then it clears shortly after the write to UCB1TXBUF. The data sheet is rather deceiving on this point.

    Teddy

  • Perhaps you should post your code then. Beyod this point (actiually before already) everything is plain guessing.

    Generally, the users guide part about the I2C is quite good. Especially the flow diagrams.

  • Here is the code that works to do the following:

    1) START with transmit for address 0x30
    2) Transmit character 0x05 (a register number)
    3) START with receive to get contents of register returned
    4) Sometime later, read the received character

    The problem I have is indicated in red. I would expect to look for the START to be completed so that I know it is safe to put the character into the UCB1TXBUF.
    But the code never exits the while() statement. Moving the while() statement to after the filling of the TXBUF works, but at this point, I don't
    care if the START has completed because I have already initiated the next operation (the byte transmit). It makes me wonder, if I fill the TXBUF, and then issue a START
    will this work too?

    Teddy

    //-------------------------------------------------------

    // Configure UCB1 for I2C communications with ADC3101

    //--------------------------------------------------------

      P5SEL |= 0x06;                           // Assign I2C pins to USCI_B1 (P5.1=SDZ, P5.2=SCL

      P5OUT |= 1;                              //

      P5DIR |= 1;                              // P5.0 will be connected to the /RESET pin on the ADC3101

      P5DIR &= ~1;                             // ADC3101 data sheet calls for a minimum 10ns reset pulse

      P5DIR |= 1;  


      UCB1CTL1 |= UCSWRST;                     // Enable SW reset

      UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;    // I2C Master, synchronous mode

      UCB1CTL1 = UCSSEL_2 + UCSWRST;           // Use SMCLK, keep SW reset

      UCB1BR0 = 35;                            // fSCL = SMCLK/160 = ~100kHz,the divisor for 16MHz

      UCB1BR1 = 0;

      UCB1I2CSA = 0x018;                      // ADC3101 on the Eval board Slave Address is 0x030 (30>>1 = 0x18

      UC1IFG &= ~0x0C;                         // clear any pending Tx/Rx UCB1 interrupts

      UCB1I2CIE |= 0x0f;                      // Enable interrupts for NAK,STOP,START and Arbitration loss

      UC1IE &= ~0x0c;                        // Disable TX and RX interrupts for USB1


       UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation 

       __bic_SR_register(GIE);                  // Enable interrupts

       UC1IE |= 8;                              // Allow Tx interrupts


       while(1)

       {

       //======================================

       // START and send command byte

       //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

       UCB1CTL1 |= 0x10; // Set in transmit mode

       UCB1CTL1 |= 0x2; // initiate a START pulse


       while(UCB1CTL1 & 2);  // wait for completion of START before we transmit a byte


       UCB1TXBUF = 0x5;   // transmit the char


       for(i=0; i<30; i++)

           aa[i] = UC1IFG;

       for(j=0; j<190; j++);

       //======================================

       // START and send command byte

       //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

       //UCB1CTL1 |= 0x10; // Set in transmit mode

       UCB1CTL1 &= ~0x10; // Set in transmit mode

       UCB1CTL1 |= 0x2; // initiate a START pulse

       for(i=0; i<30; i++)

           bb[i] = UC1IFG;

       for(j=0; j<80; j++);

       UCB1CTL1 |= 0x4;     // initiate a STOP pulse

       abc = 1;            // just a point to set a breakpoint

       abc = UCB1RXBUF;    // see what the slave device has returned


    }

  • Why do you use numeric constants instead of the defines? It's just another source for errors. (they seem to be correct here, but anyway...)

    Teddy13640 said:
    UCB1I2CIE |= 0x0f;                      // Enable interrupts for NAK,STOP,START and Arbitration loss
    [...]
      __bic_SR_register(GIE);                  // Enable interrupts

     

    Hmmm, you enable interrupts for UCNACKIFG, bu tyou don't seem to have a proper ISR for them.

    Wo what happens if the USCI gets a NACK form the slave and sets UCNACKIFG? right, it is jumping from your while loop into the UCNACKIFG ISR, which doesn't exist, so it is jumping into the void right at the moment UCTXSTT clears. And you'll never see your code leavign the while loop.

    Teddy13640 said:
      UCB1BR0 = 35;                            // fSCL = SMCLK/160 = ~100kHz,the divisor for 16MHz

    ??? UCB1BR0 = 35 is exactly SMCLK/35, so 100kHz are only set if SMCLK is 3.5MHz.

     


  • I find it easier to use constants, it allows me to look at the definitions of the registers and know exactly what bits are involved. The ".h" header files
    provided by TI and other don't always match the bit "names" in the data sheets so they confuse me more than using constants.

    Sorry, but I didn't include the ISRs as I wanted to concentrate on the START command for the I2C operation.

    (By the way, for anyone else reading this, I mistakenly provided a command to disable rather than enable interrupts "__bic_SR_register(GIE)" should be __bis to enable.)

    As for the clock speed, I'm merely trying to match the I2C rate of the EVAL board I'm connected to. I have the EVAL board execute the I2C command, then try to replicate
    it with my MSP430 acting as a 2nd master on the bus. It allows me to compare the two easily on my Oscope.

    In the end, I'm still baffled that the START command does not always include the 9th clock bit. If the slave does not respond to the start, or you provide a nonexistant
    slave address then you'll get a NAK, or in the case of no slave, no response that is treated as a NAK. But if the MSP430 doesn't clock that 9th bit, how do you know that
    a NAK occurred? Seems to me that the MSP430 must do the 9th clock in order to confirm an ACK or NAK. If the 9th bit only shows up when you follow it with
    a I2C TX, then you're past worrying what response you got from the START.

    I think I'd better review the state diagrams in the family data sheet.

    Thanks for all the help,
    Teddy 

     

     

     

     

     

  • Teddy13640 said:
    I find it easier to use constants, it allows me to look at the definitions of the registers and know exactly what bits are involved.


    But use of the defines makes it easier to see what is indended to happen. A numeric constant may be wrong or right, intentional or not. A define tells what was intended to happen with the register. Especially for 3rd party analysis :)

    Teddy13640 said:
    In the end, I'm still baffled that the START command does not always include the 9th clock bit.

    Oh, it does. It just doesn't complete the 9th bit until it know how to proceed.
    This is allowed operation, since the slave is expected to pull SDA low (for ACK) after the faling edge of SCL and keep it stable until the rising edge. That the USCI analyzes the SDA state before it rises SCL again doesn't interfere with the specs - and gives the software time to decide how to continue.
    The USCI could as well complete the clock cycle and stall then, but with SCL high, changes on SDA would be considered a start/stop condition.
    And in case of a read cycle, the slave would start sending the first bit if the 9th address bit were complete.

    It's not obvious on the first glance, but the moment when a bit is (has to be) valid depends on the edges of the clock signal, not on completed clock cycles.

     

  • Jens-Michael Gross said:
    The USCI could as well complete the clock cycle and stall then, but with SCL high, changes on SDA would be considered a start/stop condition.
    And in case of a read cycle, the slave would start sending the first bit if the 9th address bit were complete.

    It's not obvious on the first glance, but the moment when a bit is (has to be) valid depends on the edges of the clock signal, not on completed clock cycles.

    I did not understand this. The USCI could complete the clock cycle and stall. After that the SCL can be low. After this if the SDA is high or low stable how it should interpret it as data. So what is the problem is sending the 9th cycle? If the NACK has to be sent the SDA should simply be kept high no?

  • Gautam Bhat said:
    If the NACK has to be sent the SDA should simply be kept high no?

    Yes. But it has to be high on the rising edge of the clock and then keep stable. (remember, SDA is evaluated at the rising edge of SCL, and not while SCL is low. Durign SCL=0, SDA can even oscillate. What counts is the state when SCL goes high, and then SDA must remain stable.
    A stop condition, however, is a rising edge on SDA when SCL is high. Which is impossible if SDA is high already. Lowering it during SCL=1 would be a start condition, resulting in an immediate start/stop which also would violate the timing restrictions.
    So to send a stop after a NACK, the master needs to start the transfer of a new byte. Here, the master can pull SDA low (hoping the slave will not send another byte with the first bit low while it ot a NACK already) and can then, after thsi first (dummy) bit, perform a stop condition.

    That's what I meant.

**Attention** This is a public forum