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?

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can 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