cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Slave RX callback doesn't called

MichaelR
Associate III

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?

2 REPLIES 2
Karl Yamashita
Lead III

Did you enable the NVIC for the slave?

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

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