cancel
Showing results for 
Search instead for 
Did you mean: 

Configure a STM32 Board as I2C-Slave and read from it by using HAL_I2C_Mem_Read_IT

MTB
Associate

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

0 REPLIES 0