2023-03-20 12:57 AM
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.
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:
2023-03-20 03:03 AM
the clk long low time is "clock stretching" .
if you dont want, try setting "enable":
2023-03-20 03:25 AM
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 .
2023-03-21 02:11 AM
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. :)
2023-03-22 03:24 AM
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:
the 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.
2023-03-22 11:32 AM
There seems to be two problems:
2023-03-23 04:48 AM
thanks,
2023-03-23 03:07 PM
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.
2023-03-24 01:39 AM
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.