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.
Hi
i am facing an issue where MSP hangs while checking for UCTXSTT bit.
below is my code:
UCB1I2CSA = ucSlaveAddress;
UCB1CTL1 &= ~UCSWRST;
UCB1CTL1 |= UCTR | UCTXSTT; // I2C tx, start condition
while (((UCB1CTL1 & UCTXSTT) == 0) && (UCB1IFG & UCTXIFG));
if i remove ((UCB1CTL1 & UCTXSTT) and monitor only IFG flag it works and later i am checking for NACK. code works fine without any NACK after start condition is generated.
But why is it hanging when i am checking for UCTXSTT bit. ?
Thanks
Rekha
Hi Rekha,
Please refer to example code.
Is it possible device hangs on a repeated START condition?
Thanks,
Ling
Hi,
device will not hang on repeated start i mean when MSP is switched from Transmit mode to receiver mode.
initially start bit is sent and then i am polling for UCTXSTT bit to clear. but it never happens.
i even referred example code but it has interrupt based approach. but my code follows polling method.
attaching my file.
//I2C function// uint8_t ucRxdata[2] = { }; UCB1I2CSA = ucSlaveAddress; // set Slave Address as 0x55 UCB1CTL1 &= ~UCSWRST; UCB1CTL1 |= UCTR | UCTXSTT; // I2C tx, start condition for (g_uloopcount = 0; g_uloopcount < LOOP_COUNT; g_uloopcount++) { if (((UCB1CTL1 & UCTXSTT) == 0) && (UCB1IFG & UCTXIFG)) // if ((UCB1IFG & UCTXIFG)) { break; } } if (g_uloopcount == LOOP_COUNT) { /* Stop the I2C transmission */ UCB1CTL1 |= UCTXSTP; //send previous value return prev_value; } /* Check for NACK/ACK - after start+address byte */ if (UCB1IFG & UCNACKIFG) { /* Stop the I2C transmission */ UCB1CTL1 |= UCTXSTP; /* Clear the interrupt flag */ UCB1IFG &= ~UCNACKIFG; //should reset MSP if Battery Percentage I2C is called first time and encounters I2C error if(one_time_flag == false) { one_time_flag = true; return BatteryFuelGuageI2CMasterReceive(ucSlaveAddress, ucCmd, ucDataLength, prev_value); } else { //send previous value return prev_value; } } UCB1TXBUF = ucCmd; // wait until cmd got sent for (g_uloopcount = 0; g_uloopcount < LOOP_COUNT; g_uloopcount++) { if (UCB1IFG & UCTXIFG) { break; } } if (g_uloopcount == LOOP_COUNT) { /* Stop the I2C transmission */ UCB1CTL1 |= UCTXSTP; //send previous value return prev_value; } UCB1CTL1 &= ~UCTR; UCB1CTL1 |= UCTXSTT; //wait till the start condition is cleared for (g_uloopcount = 0; g_uloopcount < LOOP_COUNT; g_uloopcount++) { if ((UCB1CTL1 & UCTXSTT) == 0) { break; } } if (g_uloopcount == LOOP_COUNT) { /* Stop the I2C transmission */ UCB1CTL1 |= UCTXSTP; //send previous value return prev_value; } /* Check for ACK */ if (UCB1IFG & UCNACKIFG) { /* Stop the I2C transmission */ UCB1CTL1 |= UCTXSTP; /* Clear the interrupt flag */ UCB1IFG &= ~UCNACKIFG; //should reset MSP if Battery Percentage I2C is called first time and encounters I2C error if (one_time_flag == false) { one_time_flag = true; return BatteryFuelGuageI2CMasterReceive(ucSlaveAddress, ucCmd, ucDataLength, prev_value); } else { //send previous value return prev_value; } } unsigned int uiCounter = 0; unsigned int uiRxCounter = 2; while (uiRxCounter > 0) { for (g_uloopcount = 0; g_uloopcount < LOOP_COUNT; g_uloopcount++) { if (UCB1IFG & UCRXIFG) { break; } } if (g_uloopcount == LOOP_COUNT) { /* Stop the I2C transmission */ UCB1CTL1 |= UCTXSTP; //send previous value return prev_value; } /* Check for ACK */ if (UCB1IFG & UCNACKIFG) { /* Stop the I2C transmission */ UCB1CTL1 |= UCTXSTP; /* Clear the interrupt flag */ UCB1IFG &= ~UCNACKIFG; if (one_time_flag == false) { one_time_flag = true; return BatteryFuelGuageI2CMasterReceive(ucSlaveAddress, ucCmd, ucDataLength, prev_value); } else { //send previous value return prev_value; } } ucRxdata[uiCounter] = UCB1RXBUF; // Receive data from fuel gauge if (uiCounter == 0) { //Send stop condition. UCB1CTL1 |= UCTXSTP; } uiCounter++; uiRxCounter--; } UCB1IFG &= ~UCRXIFG; /* Clear USCI_B1 TX int flag */ UCB1IFG &= ~UCTXIFG; g_uBatteryInfo = (uint16_t) ucRxdata[0] << 8 | ucRxdata[1]; //Transmit received data byte by byte return g_uBatteryInfo;
Thanks
Rekha
As shown in User Guide (SLAU208Q) Fig 38-12, STT won't clear until you recognize TXIFG and put something into TXBUF.
So I can see how the if() in the code you attached can fail, but not how the while() you posted could hang (since there the sense of the test is reversed).
In any case, go through that Figure and assure that your code follows the required steps.
Bruce McKenney47378 said:As shown in User Guide (SLAU208Q) Fig 38-12, STT won't clear until you recognize TXIFG and put something into TXBUF
does this means my code is not checking for flags properly?
also i did not understand which figure you are talking about!!!
Yes, the indicated if() should only be checking for TXIFG, since until you act upon that STT will always be 1.
The Figure is the diagram in the F5 User Guide (Rev Q) p. 1006. There should be a link to this document on the Product page. I keep this (or equivalent) page open all the time when I'm trying to write I2C code.
thank you for your quick response.
ok i modified my code to monitor IFG flag -> look for NACK -> if ACK is received -> confirms that STT is cleared and i continue with code flow.
is my approach correct?
Thanks
Rekha
Sounds about right. (I don't have the diagram in front of me.)
You didn't mention it, but in response to the TXIFG you must actually write to TXBUF in order to proceed. (The bus is stalled until you do that.)
What does it do when you run it?
Hi,
yes i am writing to TxBUF in response to IFG flag.
when we run it : slave's register address is written to TXBUF, once this command is executed we restart I2C by changing MSP to receiver mode to receive data from slave.
Thank you very much for your constant support. i will go ahead and close this ticket.
**Attention** This is a public forum