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.

MSP430F5438 : I2C, Data on falling edge ??

Other Parts Discussed in Thread: MSP430F5438

Hello,

I have the MSPEXP4305438 with the MSP430F5438. I try to implement I2C communication but it doesn't work.

It is in slave mode and I simply use the example code for slave mode.

When the slave receives its address, it sends a number, but the number received is wrong. 

When I look the I2C lines at the scope, I can see that the MSP send data on falling edge and not on rising edge !! So the 8th bit of data is not taken in account !

How can I resolve this problem ?

Thanks.

This is the code :

 

#include "msp430x54x.h"

unsigned char TXData;
unsigned char i=0;

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

P3SEL |= 0x06; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode
UCB0I2COA = 0x48; // Own Address is 048h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCTXIE + UCSTTIE + UCSTPIE; // Enable TX interrupt
// Enable Start condition interrupt
TXData = 0; // Used to hold TX data

__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
__no_operation(); // For debugger
}

// USCI_B0 State ISR
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
switch(__even_in_range(UCB0IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: // Vector 6: STTIFG
UCB0IFG &= ~UCSTTIFG; // Clear start condition int flag
break;
case 8: // Vector 8: STPIFG
TXData++; // Increment TXData
UCB0IFG &= ~UCSTPIFG; // Clear stop condition int flag
break;
case 10: break; // Vector 10: RXIFG
case 12: // Vector 12: TXIFG
UCB0TXBUF = TXData; // TX data
break;
default: break;
}
}
  • Damien Gotfroi said:
    When I look the I2C lines at the scope, I can see that the MSP send data on falling edge and not on rising edge !! So the 8th bit of data is not taken in account

    YOur description of whaat the MSP does is incompatible with the I2C way of how things work. And irrelevant.
    The MSP doesn't send on fallign edge or risign edge. I2C specs are that the data lien is allowed to change while SCL is low. Not a tthe beginning or the end, not after or before or at an edge, but any time while SCL is low. Takign into accoutn that the maximum clock cycle on 100kHz is 10µs, the data output should be done within 10µs after the clock has gone low (or else the slave should hold hte clock low for any required additional time), to ensure the data lien change is completed before the master ends the clock cycle even at fastest speed.
    Howeverr sending the data on the rising edge would be too late in any case., as after SCL has gone high, SDA must not change at all. Chaning the data after the falling edge of SCL is the only correct way.

    Who is the master in this system? Maybe the master does not support clock stretching (rather unusual, but the demo code requires this to be allowed - the timings are not really tight for higher clock rates.

    Well, I didn't use the MSP as I2C slave yet, but whenever I used it as master, I didn't have any problems. And for the data transfer, there is not much of a difference between master and slave receiver.

    One other thing I could imagine is that your master clock appears delayed on the MSP, because of line capacitance, overly strong pullups or somethign like that. Check the hardware. Impedances, currents.

  • Yes of course, but i mean SDA change while SCL is high !! and SDA is locked when SCL is low.
    The master is a USB-I2C converter and it works at 100kHZ (with a PIC slave it works very fine).
    For the delay, it's a good idea, but i have looked the I2C line with the scope directly on MSP pin, so the delay is in intern but in this case i couldn't do anything.
  • I've found the problem.

    When the address is received by the MSP, it holds SCL low before generate ACK. When TXBUF is loaded, it generates ACK and send data.

    For my little USB-I2C converter, the ACK must be generate BEFORE SCL was held ! Otherwise, it considers SDA low while SCL is held as an ACK, and the first next rising edge on SCL is for the first data bit. But for the MSP it's the ACK bit ! So all bit are shifted by one.

    Is there a way to generate the ACK before SCL was held on the MSP ?

    Thank you.

  • Damien Gotfroi said:
    Is there a way to generate the ACK before SCL was held on the MSP ?

    Well, the MSP cannont look into the future. The clock stretching on the ACk bit is to give you a chance to decide whether to continue (handle TXBUF/RXBUF) or end (set stop or repeated start).

    However, the ACK must be accepted after SCL goes high again. That's the I2C standard. As long as SCL is low, SDA may change as often as someone wishes. While SCL is low, one of the peers (and not even the addressed slave or the master but anyone) may play a samba tune on SDA and it is a don't care still. If someone interprets SDA while SCL is low, it is a plain and clear violation of the I2C standard. All that counts is the state immediately after (or at) the rising edge. Nothing else matters. Period.

**Attention** This is a public forum