cancel
Showing results for 
Search instead for 
Did you mean: 

How to fix the I2C slave issue with STM32G070? HAL_I2C_ListenCpltCallback, HAL_I2C_AddrCallback, HAL_I2C_SlaveRxCpltCallback, HAL_I2C_SlaveTxCpltCallback

MrLKovacs
Associate II

Hi,

I'm trying to setup a stm32g070kb (32pin) MCU as I2C slave by using CubeIDE.

I would like to create a code which will work same as I2C Eeprom, but when I ask the stm32 (with another MCU) to return me a register or registers value, the returned registers are shifted by 1 register.

On this picture I recorded the communication between I2C Eprom and STM32G070 slave.

The gap in the STM32 communication makes the request shift by 1 byte for the master MCU, the eeprom doesn't have the gap.0693W00000aJJ7hQAG.jpg 

here is the code:

// emulated I2C RAM
static uint8_t my_i2c_ram[128];
static uint8_t my_i2c_offset; 	// index of current RAM cell
static uint8_t first=1;	// first byte --> new my_i2c_offset
 
 
 
 
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
{
	first = 1;
	HAL_I2C_EnableListen_IT(hi2c); // slave is ready again
}
 
 
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
 
	if( TransferDirection==I2C_DIRECTION_TRANSMIT )
	{
		if( first )
		{
			HAL_I2C_Slave_Seq_Receive_IT(hi2c, &my_i2c_offset, 1, I2C_NEXT_FRAME);
		}
		else
		{
			HAL_I2C_Slave_Seq_Receive_IT(hi2c, &my_i2c_ram[my_i2c_offset], 1, I2C_NEXT_FRAME);
		}
	}
	else
	{
		HAL_I2C_Slave_Seq_Transmit_IT(hi2c, &my_i2c_ram[my_i2c_offset], 1, I2C_NEXT_FRAME);
	}
}
 
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
	if(first)
	{
		first = 0;
	}
	else
	{
		my_i2c_offset++;
	}
	HAL_I2C_Slave_Seq_Receive_IT(hi2c, &my_i2c_ram[my_i2c_offset], 1, I2C_NEXT_FRAME);
}
 
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
 
	my_i2c_offset++;
	HAL_I2C_Slave_Seq_Transmit_IT(hi2c, &my_i2c_ram[my_i2c_offset], 1, I2C_NEXT_FRAME);
}
 
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
{
 
	if( HAL_I2C_GetError(hi2c)==HAL_I2C_ERROR_AF )
	{
		// transaction terminated by master
		my_i2c_offset--;
	}
	else
	{
		myerror = HAL_I2C_GetError(hi2c) ;
	}
}

and the CubeIDE settings:

0693W00000aJJBPQA4.png

8 REPLIES 8
AScha.3
Chief II

the clk long low time is "clock stretching" .

if you dont want, try setting "enable":

0693W00000aJJVkQAO.png

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

Thanks AScha.3 for the quick respond, I have tried that and with disabled clock streching the master can't even detect the stm32 slaves address .

AScha.3
Chief II

so we know: the "gap" is needed clock-stretching , because slave quite slow responding.

and so this is no error.

if you get 1+ register number , your counting is wrong somewhere then. 🙂

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

I'm sure it's not my misscounting because (as I described it) I ask the STM32 in the same way as I ask the EEprom.

I use an arduino as a master I2C to ask two slaves, STM32 with address 0x48 and the EEprom with 0x50 address.

I use this library #include <Eeprom24C01_02.h>

and I use the example code to ask bytes from both eeprom and stm32.

i2ceeprom(0x50);
i2cSTM(0x48);
 
 
 
//-----------------------------------------
 
        Serial.println("EE read lib bytes");delay(10);
        
        const byte count = 30;
        byte outputBytes[count] = { 0 };
        i2ceeprom.readBytes(0, count, outputBytes);
 
        // Print read bytes.
        for (byte i = 0; i < count; i++)
        {
            Serial.write(outputBytes[i]);
            Serial.print(" ");
        }
 
 
//------------------------------------------------------------------
 
        Serial.println("STM read lib bytes");delay(10);
        
        const byte count = 30;
        byte outputBytes[count] = { 0 };
        i2cSTM.readBytes(0, count, outputBytes);
 
        // Print read bytes.
        for (byte i = 0; i < count; i++)
        {
            Serial.write(outputBytes[i]);
            Serial.print(" ");
        }

I wrote the same data to each slave:

! " # $ % & ' ( ) * + , - . / 0 1 2 3 1 9 9 7 8 9 : ; < = >

this is what I get from the STM32 and from the EEprom:

0693W00000aJU7iQAG.pngthe fist byte always rubbish and the rest are shifted.

I'm usinf the same code to ask so I'm sure the problem is with the STM slave settings or the code I'm using in CubeIDE.

Piranha
Chief II

There seems to be two problems:

  1. Your master device doesn't understand the clock stretching.
  2. The HAL broken bloatware is too slow - at 64 MHz the 40 us means 2560 clock cycles.
MrLKovacs
Associate II

thanks,

  1. when I enable clock stretching , I can write data succesfully to the stm32 but it answers incorrectly, when I checked it with the oscilloscope looked like the dataline polarity changed. ???
  2. the stm is running on 64mhz , are you suggesting delay for the master while stm answering?
Piranha
Chief II

I'm just stating the fact (40 us), which can be seen in your oscilloscope images. Also I suggest to stop clicking CubeMX and using a broken bloatware and instead develop a normal code.

MrLKovacs
Associate II

The first picture was taken with 16MHz here is a new picture with 64MHz.

The "gap" is much shorter but the behavior is still the same.

I added also another picture with clock stretching enabled, the data line stayed high instead of low.

The eeprom request is still perfect. I know cubemx has issues but if someone could help me to find which bit or flag I have to change or clear to make it work as eeprom, I would greatly appreciate it.

0693W00000aJdWwQAK.jpg