1
\$\begingroup\$

Trying to understand why the while loop is behaving weirdly.

HAL_MasterReceiveInterrupt() enables the control bits for I2C and continues to loop unless the STATE is READY - in other words, when the data is fully read but I see the it executing outside the while loop. So while loop shouldn't end until the the return value from the function is I2C_READY

The output looks as follows:

RXing...
Printing buffer values...
Stopping transmission

Instead of:

RXing...
Stopping transmission
Printing buffer values // now that we are outside the loop

what's up with the sequence of execution?

I2C_State HAL_MasterReceiveInterrupt(void)
{
 I2C_State i2cState = I2C_handle_p->I2C_State;
 if (i2cState != I2C_RX_BUSY && i2cState != I2C_TX_BUSY)
 {
 printf ("RXing...\n");
 I2C_handle_p->I2C_State = I2C_RX_BUSY;
 GenerateStartCondition(I2C_handle_p);
 I2C_SetCtrlBits(); // enable i2c control bits
 }
 return i2cState;
}
static void I2C_StopTransmission(void)
{
 printf ("Stopping transmission...\n\n");
 // disable control bits
 I2C_handle_p->pI2Cx->CR2 &= ~(1 << I2C_CR2_ITEVTEN_Pos);
 I2C_handle_p->pI2Cx->CR2 &= ~(1 << I2C_CR2_ITBUFEN_Pos);
 // restore struct
 I2C_handle_p->I2C_State = I2C_READY;
 I2C_handle_p->rxBufferLength = BYTES_PER_TRANSACTION;
} 
// app.c
void ReadVal() {
 while (HAL_MasterReceiveInterrupt() != I2C_READY);
 printf ("Printing buffer values..."); // assuming I2C read operation is completed
 while(1);
}
asked Apr 6, 2020 at 21:49
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Who calls the I2C_StopTransmission? But anyway, the I2C_StopTransmission sets the I2C_READY, so it shall be the last call before you execute "Printing buffer values". And HAL_MasterReceiveInterrupt changes the staus from I2C_READY to I2C_BUSY. So the sequence is as follows:

"Printing buffer values"
"Printing buffer values"
"Printing buffer values"
n x times
"RXing..."
"Stopping transmission..."
"Printing buffer values"
"Printing buffer values"
"Printing buffer values"
n x times

EDIT:

 if (i2cState != I2C_RX_BUSY && i2cState != I2C_TX_BUSY)

if it's not rx_busy and it's not tx_ busy then

I2C_handle_p->I2C_State = I2C_RX_BUSY;

?? then it's rx_busy??

Further, you ask a state that obviously is set by system and then you override it?

answered Apr 6, 2020 at 22:39
\$\endgroup\$
1
  • \$\begingroup\$ ah, so the initial value stored in i2cState is I2C_READY, hence the while loop doesn't get executed to begin with. But there's still a strange behavior that I'm not able to understand regarding getting out of the while loop even though i2cState is not I2C_READY (hence the prints). also, would it be better to add say I2C_NOTREADY so the initial value is not I2C_READY? in regards to later comment, the initial value is not expected to be either I2C_RX_BUSY or I2C_TX_BUSY \$\endgroup\$ Commented Apr 6, 2020 at 23:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.