2024-07-21 12:06 AM
Hello everyone
I am using NUCLEO-H563ZI as master I2C, and STM32F412G-DISCO board as slave I2C, which should mimic temperature sensor TMP117.
I am trying to send from master to slave a register number to read from, but the rx callback in the slave doesn't called.
Master configuration:
Master code:
int16_t TMP117_ReadTemperature(uint8_t TMP117_ADDRESS)
{
uint8_t data[2];
uint16_t i2c_address=TMP117_ADDRESS<<1;
uint8_t reg=TEMP_RESULT;
const uint16_t TIME_OUT=100;
HAL_StatusTypeDef err=HAL_I2C_Master_Transmit(&hi2c1, i2c_address, ®, 1, TIME_OUT);
if (HAL_I2C_Master_Receive(&hi2c1, TMP117_ADDRESS<<1, data, 2, HAL_MAX_DELAY)!=HAL_OK){
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_RESET);
}
int16_t temp = (data[0] << 8) | data[1];
return temp;
}
Slave configuration:
Slave code:
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
if (hi2c->Instance == I2C1){
if (TransferDirection == I2C_DIRECTION_TRANSMIT)
{
// Master is writing data to the slave
i2c_state = I2C_STATE_RECEIVE_REGISTER;
HAL_StatusTypeDef err=HAL_I2C_Slave_Receive_IT(hi2c, &i2c_register_address, 1);
//HAL_Delay(100);
char tx;
sprintf(tx,"I2C status: %d",err);
HAL_UART_Transmit(&huart2,tx,sizeof(tx),100);
}
else
{
// Master is reading data from the slave
i2c_state = I2C_STATE_READ_DATA;
Process_I2C_Read(hi2c);
}
}
}
/* Received I2C communication has terminated. */
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if (hi2c->Instance == I2C1){
if (i2c_state == I2C_STATE_RECEIVE_REGISTER)
{
// Register address has been received, now prepare to receive the data
i2c_state = I2C_STATE_RECEIVE_DATA;
HAL_I2C_Slave_Receive_IT(hi2c, (uint8_t *)&TMP117_Registers[i2c_register_address], 2);
}
else if (i2c_state == I2C_STATE_RECEIVE_DATA)
{
// Data has been received, process the write operation
i2c_state = I2C_STATE_IDLE;
// Re-enable address match callback
HAL_I2C_EnableListen_IT(hi2c);
}
}
}
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if (hi2c->Instance == I2C1){
i2c_state = I2C_STATE_IDLE;
HAL_I2C_EnableListen_IT(hi2c);
}
}
float tempReading(void) {
const float V25=0.76;
const float Avg_Slope=0.0025;
const float VDD=3.3;
float temp;
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
uint16_t tempCount=HAL_ADC_GetValue(&hadc1);
temp=((VDD*tempCount/4095.0f-V25)/Avg_Slope+25.0f);
HAL_ADC_Stop(&hadc1);
return temp;
}
void Process_I2C_Read(I2C_HandleTypeDef *hi2c)
{
if (i2c_register_address==0) {
TMP117_Registers[i2c_register_address]=tempReading()/0.0078125;
}
uint16_t value = TMP117_Registers[i2c_register_address];
uint8_t data[2] = {value >> 8, value & 0xFF};
HAL_I2C_Slave_Transmit_IT(hi2c, data, 2);
/* USER CODE END 3 */
}
At HAL_I2C_AddrCallback, err==HAL_BUSY, and HAL_I2C_SlaveRxCpltCallback isn't called, so register number doesn't received.
Do anyone have an idea what is wrong?
2024-07-22 07:55 PM
Did you enable the NVIC for the slave?
2024-07-22 11:36 PM
Yes, the NVIC is enabled.
Another information after further debugging: the master indicates that the communication is HAL_OK, but the slave indicates after the first received byte HAL_BUSY.
When than the master asks to receive 2 bytes, it gets twice the slave address with the Read/Write byte high