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.

MSP430FR2532: EUSCI B i2c data not send

Part Number: MSP430FR2532

Hi,

i have a problem in understanding the i2c communication.

I have setup eusci b for the i2c and I am trying to read / write an VL53L0X sensor with it. The problem is, that whenevery I want to write something, my logic analyzer says, I'm writing 0xFF. When I do a step-by-step debugging, I can see that I am writing the correct data, so I guess there is a loop or delay missing, but i cannot find where...

First of all, my initilization code:

void i2cInit() {
UCB0CTLW0 |= UCSWRST; // put into SW Reset
UCB0CTLW0 |= UCSSEL_3; // choose SMCLK
UCB0BRW = 40; // set prescaler = 80 => 100 kHz
UCB0CTLW0 |= UCMODE_3; // put into I2C Mode
UCB0CTLW0 |= UCMST; // put into MASTER mode
UCB0I2CSA = 0x29; // slave addr = 0x29
UCB0TBCNT = 1; // default byte count = 1
UCB0CTLW1 |= UCASTP_2; // auto STOP mode

P1SEL1 &= ~BIT3; // P1.3 = SCL
P1SEL0 |= BIT3;

P1SEL1 &= ~BIT2; // P1.2 = SDA
P1SEL0 |= BIT2;

UCB0CTLW0 &= ~UCSWRST; // get out of SW Reset

__delay_cycles(10000);
}

then my read register code

int i2cReadReg(uint8_t reg, uint8_t *dest, uint16_t timeout) {
int toCounter = 0;
UCB0TBCNT = 1;
UCB0CTLW0 |= UCTR; // put into Tx mode
UCB0CTLW0 |= UCTXSTT; // gen START
while(UCB0CTLW0 & UCTXSTT) // wait for START to be sent
{
if(toCounter++ > timeout)
return -1;
}
UCB0TXBUF = reg; // write register
while (UCB0IFG & !UCTXIFG) // wait for Tx buffer to be empty
{
if(toCounter++ > timeout)
return -2;
}
while (UCB0CTL1 & UCTXSTP) // wait for STOP
{
if(toCounter++ > timeout)
return -3;
}

UCB0CTLW0 &= ~UCTR; // put into Rx mode
UCB0CTLW0 |= UCTXSTT; // gen START
while(UCB0CTLW0 & UCTXSTT) // wait for START to be sent
{
if(toCounter++ > timeout)
return -4;
}
while (UCB0IFG & !UCRXIFG) // wait for Rx Data to arrive
{
if(toCounter++ > timeout)
return -5;
}
*dest = UCB0RXBUF;
while (UCB0CTL1 & UCTXSTP) // wait for STOP
{
if(toCounter++ > timeout)
return -6;
}
return 1;
}

below you can see images of the logic analyzer with the debug active and without. I tried adding some __delay_cycles between start and data set, before start... did not help. 
What am I doing wrong?

PS: sorry somewhow the "code" tag threw an error for me...

Without Debug:

With Debug:



  • First up, use the insert code widget for your code to put it into a handier scrollable window.

    You include a timeout at each step which is a good idea but fail to reset the counter at each step. Given the timeouts, you need to check the error number returned to see where your code dies. Assuming you don't use a debugger which would be the best way.

    Your code to wait on the TXSTP bit to clear is useless unless you have set TXSTP to generate a stop. Which you don't want to do after sending the register address and before a repeated start. I see other problems like writing to TBCNT without putting the I2C hardware in reset first so there are probably many more problems. Such as the autostop mode not working well for transmitting a register address before doing a repeated start to read mode.

    You probably need to read the documentation again and look at the TI code examples.

**Attention** This is a public forum