2020-12-24 11:20 AM
Im using STM32L4 how i2c master with 5 i2c slaves
In stm32l1 when using callback i can detect device using :
if (hi2c->Devaddress == I2C_ADDRESS1) // slave 1
{
}
In STm32L4 don't exist hi2c->Devaddress ..
Yu can help me .
BR.
Francesco
2020-12-24 11:47 AM
Not sure I understand. Is the STM32 the I2C master? Or a slave? Or is it acting as 5 different slaves?
Edit:
You can find the last slave address the master communicated with by looking at the I2C_CR2_SADD bits.
2020-12-24 11:56 AM
You'll either have to port over that functionality or overload the instance to include your own structure/state data
2020-12-24 12:08 PM
I have a master stm32l4 in i2c interrupt and in the callbac i want choose the actions consequentelly slave selected :
example in stm32l1
if (hi2c->Devaddress == I2C_ADDRESS_1) // slave 1
{
.................
}
// slave 2
if (hi2c->Devaddress == I2C_ADDRESS_2) // slave 2
{
.................
}
}
In stm32L4 ,how can i replace(hi2c->Devaddress == I2C_ADDRESS_1) , (hi2c->Devaddress == I2C_ADDRESS_2) ???
Thanks
2020-12-24 12:09 PM
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if (hi2c->Devaddress == I2C_ADDRESS_1) // slave 1
{
.................
}
// slave 2
if (hi2c->Devaddress == I2C_ADDRESS_2) // slave 2
{
.................
}
}
}
2020-12-24 12:24 PM
if (hi2c->Instance->CR2 & I2C_CR2_SADD == I2C_ADDRESS_1) // slave 1
{
...
}
2020-12-24 12:34 PM
ok i try to replace :
Before without the if the callback worked for me, now adding this if with the breakpoint stops me on the if and does not execute the rest of the code.
WHY?
Thanks
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if (hi2c->Instance->CR2 & I2C_CR2_SADD == SHT31_D_ADDR)
{
volatile uint16_t temperature = (result[0] << 8) + result[1];
temperature_val = -45+175*((float)temperature/65535);
volatile uint16_t humid = (result[3] << 8) + result[4];
humid_val = 100*((float)humid/65535);
HAL_I2C_Master_Transmit_IT(&hi2c1, SHT31_D_ADDR, i2c_data_cmd_MEAS, 2);
}
}
Thanks
2020-12-24 01:33 PM
Probably going to want to do that in a more stateful manner so you scan the slaves rather than lock into an infinite loop on one.
What possible point would there be for local/auto variables in this instance to be volatile?
Instead of using global variables and cluttering things up, might I suggest a structure beyond hi2c holding the data related to this i2c bus?
typedef struct _I2CFOO {
I2C_HandleTypeDef hi2c[1]; // at the front, so the address is the same
int DevAddress;
int Sequence;
volatile float temperature_val[4]; // stuff you'll change under interrupt
volatile float humid_val[4];
} I2CFOO;
I2CFOO foo[1];
foo->DevAddress = SHT31_D_ADDR;
HAL_I2C_Master_Transmit_IT(foo->hi2c, foo->DevAddress, i2c_data_cmd_MEAS, 2);
...
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
I2CFOO *foo = (I2CFOO *)hi2c; // Cast to the larger structure you're passing a pointer too
if (foo->DevAddress == SHT31_D_ADDR)
{
...
}
}