Skip to main content
Visitor II
July 21, 2024
Question

I2C Slave RX callback doesn't called

  • July 21, 2024
  • 1 reply
  • 985 views

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: 

MichaelR_0-1721544888128.png

 

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, &reg, 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: 

MichaelR_1-1721545083709.png

 

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?

    This topic has been closed for replies.

    1 reply

    Graduate II
    July 23, 2024

    Did you enable the NVIC for the slave?

    MichaelRAuthor
    Visitor II
    July 23, 2024

    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