2021-09-13 12:03 PM
I've succesfully built an I2C connection between two STM32 boards by using HAL library with interrupts. It looks like this:
Master:
if button 1 is pushed -> HAL_I2C_Master_Transmit_IT(&hi2c1, 0xA0, &i2c_send_master, 1);
if button 2 is pushed -> HAL_I2C_Master_Receive_IT(&hi2c1, 0xA1, &i2c_receive_master, 1);
Callback functions:
HAL_I2C_MasterTxCpltCallback() and HAL_I2C_MasterRxCpltCallback() toggles an LED
Slave:
HAL_I2C_EnableListen_IT(&hi2c1) is called in main.
Callback functions:
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
HAL_I2C_DisableListen_IT(&hi2c1);
if(TransferDirection==0) //master write
{
HAL_I2C_Slave_Receive_IT(&hi2c1, &i2c_receive_slave, 1);
}
if(TransferDirection==1) //master read
{
HAL_I2C_Slave_Transmit_IT(&hi2c1, &i2c_send_slave, 1);
}
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
Toggle_LED();
HAL_I2C_EnableListen_IT(&hi2c1);
}
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
Toggle_LED();
HAL_I2C_EnableListen_IT(&hi2c1);
}
so far all works fine. If i push a button on the master board, an LED toggles on the master board and on the slave board.
What im trying now is to simulate a Sensor with my slave board.
I've succesfully read and wrote sensor registers by using HAL_I2C_Mem_Read_IT or
HAL_I2C_Mem_Write_IT.
I want to simulate the sensor registers on my slave with simple variables.
Master writes to slave:
For example: (sensor value register is at address 0x01 and has a value of 7)
Master(write):
i2c_write_master = 7;
HAL_I2C_Mem_Write_IT(&hi2c1, 0xA1, 0x01, 1, &i2c_write_master, 1);
Slave:
uint8_t receive_slave_mem[2];
Callback functions:
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
HAL_I2C_DisableListen_IT(&hi2c1);
if(TransferDirection == 0) //master write
{
HAL_I2C_Slave_Receive_IT(&hi2c1, receive_slave_mem, 2); //get register address and value
}
}
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if(receive_slave_mem[0]==0x01)
{
sensor_value = receive_slave_mem[1]; // -> sensor_value = 7;
}
HAL_I2C_EnableListen_IT(&hi2c1);
}
This is also working. My master board can write values to the variables with a specific virtual address on the slave board.
But now comes my problem. I cant implement a proper read function.
Lets take the same example:
Master reads from slave:
For example: (sensor value register is at address 0x01 and has a value of 7)
Master(read):
HAL_I2C_Mem_Read_IT(&hi2c1, 0xA1, 0x01, 1, &i2c_read_master, 1);
Slave:
Callback functions:
uint8_t receive_slave_mem[2];
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
HAL_I2C_DisableListen_IT(&hi2c1);
if(TransferDirection == 1) //master read
...
when my master uses HAL_I2C_Mem_Read_IT or HAL_I2C_Mem_Write_IT TransferDirection
in the HAL_I2C_AddrCallback form the slave is always 0 (=write) because the master sends
a write command with the register address first.
So how can i differentiate if my slave is receiving a HAL_I2C_Mem_Read_IT or a
HAL_I2C_Mem_Write_IT command?
Or is there another/better way to simulate that sensor behavier with my slave board via
I2C?
Regards
Steve