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);
}
1 Answer 1
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?
-
\$\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 thoughi2cState
is notI2C_READY
(hence the prints). also, would it be better to add sayI2C_NOTREADY
so the initial value is notI2C_READY
? in regards to later comment, the initial value is not expected to be eitherI2C_RX_BUSY
orI2C_TX_BUSY
\$\endgroup\$xyf– xyf2020年04月06日 23:26:42 +00:00Commented Apr 6, 2020 at 23:26