cancel
Showing results for 
Search instead for 
Did you mean: 

How to make my stm32 mcu which is a i2c slave respond with a known data upon address match

AR_26
Associate II

My stm32 mcu is a i2c slave device.

  1. When master sends the address on the bus, I want stm32 to respond with a known byte upon address match. How can I do that?
  2. I want to send different type of data with different size to the stm32 slave. How can I make my stm32 interpret what kind of data master has sent ?

Generally, I2C slaves have a dedicated register for a specific data. But since this is stm32 mcu it does not have a resister map to store different kind of data in a separate register. It has to interpret everything from what it receives in the RXDR register.

5 REPLIES 5
TDK
Guru

Which STM32? There are hundreds of chips.

Generally, you will want to interpret the incoming bytes as you receive them. The I2C peripheral is complicated, you need to interpret in realtime and populate outgoing buffers accordingly.

If you're a fan of HAL, look at some examples:

https://github.com/STMicroelectronics/STM32CubeF4/blob/a86ecaa2fb63029596ba7dabadab2d9c2c139560/Projects/STM32469I-Discovery/Examples/I2C/I2C_TwoBoards_ComPolling/Src/main.c

If you feel a post has answered your question, please click "Accept as Solution".
AR_26
Associate II

@TDK​ This is STM32G031. Is there a way to define a protocol between master and slave so that slave can do some interpretation?

I am currently using the Slave Receive HAL API to receive data into a buffer,

uint8_t data[10];
HAL_I2C_Slave_Receive_IT(&hi2c1, data, sizeof(data))

> Is there a way to define a protocol between master and slave so that slave can do some interpretation?

Of course. The only limitation to this is your ability to program that protocol. I2C is complicated, particularly if you're using interrupts. It may take some time to figure out. I would start with blocking calls and progress to non-blocking once that is working.

If you feel a post has answered your question, please click "Accept as Solution".
AR_26
Associate II

@TDK​ Thanks ! Any ideas on point 1 in my orginal question

My stm32 mcu is a i2c slave device.

  1. When master sends the address on the bus, I want stm32 to respond with a known byte upon address match. How can I do that?

I am using Listen Mode APIs as below,

void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c,
                                 uint8_t TransferDirection,
                                 uint16_t AddrMatchCode)
{
	if(hi2c->Instance == I2C1)
	{
		uint8_t id = 0xA0;
		if(TransferDirection == I2C_DIRECTION_TRANSMIT)
			HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, data, sizeof(data),I2C_FIRST_FRAME);
		else
			HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, &id, 1, I2C_LAST_FRAME);
	}
}
 
 
int main(void) 
{
   ....
   while(1)
   {
        ....
        HAL_I2C_EnableListen_IT(&hi2c1);
   }
 
}

Every-time I send a read command, it enter HAL_I2C_Slave_Transmit_IT but does not send out the data. Because inside the IRQ handler there is condition which checks the ADDR flag and since that is true it just returns from there.

I would look at and follow the cube examples for guidance. Looks like this one does almost exactly what you want:
https://github.com/STMicroelectronics/STM32CubeF4/blob/a86ecaa2fb63029596ba7dabadab2d9c2c139560/Projects/STM32469I-Discovery/Examples/I2C/I2C_TwoBoards_RestartComIT/Src/main.c
The code for the G0 family should be similar if not identical.
If you feel a post has answered your question, please click "Accept as Solution".