📄 i2c state machine.c
字号:
// //
// Parameters: None //
// //
// Return: Status of I2C Stop condition //
// false: I2C Stop condition not finished //
// true: I2C Stop condition finished //
// //
// Description: This function is called from within the SPI main state //
// machine. //
// It executes a state machine that implements the I2C Stop //
// condition by setting SDA to 0 while SCL is 1. //
//--------------------------------------------------------------------------//
bool I2C_Execute_STOP(void)
{
bool Return_Value = false;
static t_I2C_Sub_States I2C_STOP_SM_State = I2C_SET_LOW_SCL_SDA;
switch(I2C_STOP_SM_State)
{
// state SET_LOW_SCL_SDA
case I2C_SET_LOW_SCL_SDA:
// state transition SET_LOW_SCL_SDA -> SET_HIGH_SCL
I2C_STOP_SM_State = I2C_SET_HIGH_SCL;
I2C_Set_Low_SCL();
I2C_Set_Low_SDA();
break;
// state SET_HIGH_SCL
case I2C_SET_HIGH_SCL:
// state transition SET_HIGH_SCL -> SET_HIGH_SDA
I2C_STOP_SM_State = I2C_SET_HIGH_SDA;
I2C_Set_High_SCL();
break;
// state SET_HIGH_SDA
case I2C_SET_HIGH_SDA:
// state transition SET_HIGH_SDA -> SET_LOW_SCL_SDA
I2C_STOP_SM_State = I2C_SET_LOW_SCL_SDA;
I2C_Set_High_SDA();
Return_Value = true; // SM is finished
break;
}
return(Return_Value);
}
//--------------------------------------------------------------------------//
// Function: Execute_WRITE //
// //
// Access: Private //
// //
// Parameters: None //
// //
// Return: Status of I2C Write operation //
// false: I2C Byte transfer not finished //
// true: I2C Byte transfer finished //
// //
// Description: This function is called from within the SPI main state //
// machine. //
// It executes a state machine that transfers a value, stored //
// in member variable m_Current_Transfer.Byte via I2C. //
// The number of bits to be transferred is stored in member //
// variable m_Current_Transfer.Bit_Count. //
//--------------------------------------------------------------------------//
bool I2C_Execute_WRITE(void)
{
bool Return_Value = false;
static t_I2C_Sub_States I2C_WRITE_SM_State = I2C_SET_LEVEL_SDA;
static int I2C_WRITE_SM_State_Counter = 0;
switch(I2C_WRITE_SM_State)
{
// state SET_LEVEL_SDA
case I2C_SET_LEVEL_SDA:
// state transition SET_LEVEL_SDA -> SET_HIGH_SCL
I2C_WRITE_SM_State = I2C_SET_HIGH_SCL;
// extract one bit from byte to be transferred at the time and transfer it
if((m_Current_Transfer.Byte << I2C_WRITE_SM_State_Counter++) & 0x80)
{
I2C_Set_High_SDA();
}
else
{
I2C_Set_Low_SDA();
}
break;
// state SET_HIGH_SCL
case I2C_SET_HIGH_SCL:
// state transition SET_HIGH_SCL -> SET_LOW_SCL
I2C_WRITE_SM_State = I2C_SET_LOW_SCL;
I2C_Set_High_SCL();
break;
// state SET_LOW_SCL
case I2C_SET_LOW_SCL:
// state transition SET_LOW_SCL -> SET_LEVEL_SDA
I2C_WRITE_SM_State = I2C_SET_LEVEL_SDA;
I2C_Set_Low_SCL();
// reset SM counter if all bits transferred
if(I2C_WRITE_SM_State_Counter == m_Current_Transfer.Bit_Count)
{
I2C_WRITE_SM_State_Counter = 0;
Return_Value = true; // SM is finished
}
break;
}
return(Return_Value);
}
//--------------------------------------------------------------------------//
// Function: Execute_READ //
// //
// Access: Private //
// //
// Parameters: None //
// //
// Return: Status of I2C Read operation //
// false: I2C Byte Read not finished //
// true: I2C Byte Read finished //
// //
// Description: This function is called from within the SPI main state //
// machine. //
// It executes a state machine that reads a value from the //
// Slave device and stores it in m_Current_Message.Byte. //
// The number of bits to be transferred is stored in member //
// variable m_Current_Transfer.Bit_Count. //
//--------------------------------------------------------------------------//
bool I2C_Execute_READ(void)
{
bool Return_Value = false;
static t_I2C_Sub_States I2C_READ_SM_State = I2C_SET_SDA_INPUT;
static int I2C_READ_SM_State_Counter = 0;
switch(I2C_READ_SM_State)
{
// state SET_SDA_INPUT
case I2C_SET_SDA_INPUT:
// state transition SET_SDA_INPUT -> SET_HIGH_SCL
I2C_READ_SM_State = I2C_SET_HIGH_SCL;
I2C_Set_SDA_Input();
break;
// state SET_HIGH_SCL
case I2C_SET_HIGH_SCL:
// state transition SET_HIGH_SCL -> READ_SDA
I2C_READ_SM_State = I2C_READ_SDA;
I2C_Set_High_SCL();
break;
// state READ_SDA
case I2C_READ_SDA:
// state transition READ_SDA -> SET_LOW_SCL
I2C_READ_SM_State = I2C_SET_LOW_SCL;
// read next bit and store it in m_Current_Transfer.Byte
m_Current_Transfer.Byte = (m_Current_Transfer.Byte << 1) | (I2C_Read_SDA() & 0xfe);
I2C_READ_SM_State_Counter++;
break;
// state SET_LOW_SCL
case I2C_SET_LOW_SCL:
I2C_Set_Low_SCL();
// reset SM if all bits have been read, otherwise read next bit
if(I2C_READ_SM_State_Counter == m_Current_Transfer.Bit_Count)
{
// state transition SET_LOW_SCL -> SET_SDA_OUTPUT
I2C_READ_SM_State = I2C_SET_SDA_OUTPUT;
I2C_READ_SM_State_Counter = 0;
}
else
{
// state transition SET_LOW_SCL -> SET_HIGH_SCL
I2C_READ_SM_State = I2C_SET_HIGH_SCL;
}
break;
// state SET_SDA_OUTPUT
case I2C_SET_SDA_OUTPUT:
// state transition SET_SDA_OUTPUT -> SET_SDA_INPUT
I2C_READ_SM_State = I2C_SET_SDA_INPUT;
I2C_Set_SDA_Output();
Return_Value = true; // SM is finished
break;
}
return(Return_Value);
}
//--------------------------------------------------------------------------//
// Function: Execute_CHECK_ACK //
// //
// Access: Private //
// //
// Parameters: None //
// //
// Return: Status of I2C Acknowledge operation //
// false: I2C Acknowledge cycle not finished //
// true: I2C Acknowledge cycle finished //
// //
// Description: This function is called from within the SPI main state //
// machine. //
// It executes a state machine that reads the value on SDA //
// returned during the acknowledge cycle and stores it in //
// member variable ACK_State. //
//--------------------------------------------------------------------------//
bool I2C_Execute_CHECK_ACK(void)
{
bool Return_Value = false;
static t_I2C_Sub_States I2C_TEST_ACK_SM_State = I2C_SET_SDA_INPUT;
switch(I2C_TEST_ACK_SM_State)
{
// state SET_SDA_INPUT
case I2C_SET_SDA_INPUT:
// state transition SET_SDA_INPUT -> SET_HIGH_SCL
I2C_TEST_ACK_SM_State = I2C_SET_HIGH_SCL;
I2C_Set_SDA_Input();
break;
// state SET_HIGH_SCL
case I2C_SET_HIGH_SCL:
// state transition SET_HIGH_SCL -> READ_SDA
I2C_TEST_ACK_SM_State = I2C_READ_SDA;
I2C_Set_High_SCL();
break;
// state READ_SDA
case I2C_READ_SDA:
// state transition READ_SDA -> SET_LOW_SCL
I2C_TEST_ACK_SM_State = I2C_SET_LOW_SCL;
// read SDA and assign value to variable that holds error state
m_ACK_Error = I2C_Read_SDA();
break;
// state SET_LOW_SCL
case I2C_SET_LOW_SCL:
// state transition SET_LOW_SCL -> SET_SDA_OUTPUT
I2C_TEST_ACK_SM_State = I2C_SET_SDA_OUTPUT;
I2C_Set_Low_SCL();
break;
// state SET_SDA_OUTPUT
case I2C_SET_SDA_OUTPUT:
// state transition SET_SDA_OUTPUT -> SET_SDA_INPUT
I2C_TEST_ACK_SM_State = I2C_SET_SDA_INPUT;
I2C_Set_SDA_Output();
Return_Value = true; // SM is finished
break;
}
return(Return_Value);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -