2020-08-11 04:00 AM
I have an STM32G4 using the HAL function HAL_I2C_Slave_Transmit to respond with some data when requested by a master on the I2C bus. In the image below you can see the device sends 0xFF followed by the actual data it was meant to send (the data I am expecting is 0x11 0x01 0x00).
If I instead use HAL_I2C_Slave_Transmit_IT then I get a worse result, as shown below:
I have tried this with the minimal test program below so I don't believe it's anything to do with my full program having a delay:
/* USER CODE BEGIN 2 */
typedef struct {
char id;
char payload[2];
} I2C_RSP_TO_MASTER;
I2C_RSP_TO_MASTER I2C_response;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
I2C_response.id = 0x11;
I2C_response.payload[0] = 0x01;
I2C_response.payload[1] = 0x00;
HAL_I2C_Slave_Transmit(&hi2c2, (uint8_t*) &I2C_response, 3, 10);
while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY) {
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
For my current testing the master is an Arduino Nano using the Arduino function:
Wire.requestFrom(ADDR, 4);
I am requesting 4 bytes because the initial byte is garbage (0xFF). The STM32 is clocked at 128MHz so I don't believe it is possible that it is running too slowly to respond to the first byte - I think it must be a problem with the HAL! Any advice?
2020-08-11 04:49 AM
What is the definition of I2C_response? Is there another variable before payload? Probably pointing to payload directly is better.
You should probably be using a larger timeout as well. 10ms is not much time. If you want it to be blocking, use HAL_MAX_DELAY
HAL_I2C_Slave_Transmit(&hi2c2, (uint8_t*) &I2C_response.payload, 3, HAL_MAX_DELAY);
2020-08-11 06:00 AM
I've updated my post with code that includes the rest of the i2c_response definition. It is just those three bytes. Using HAL_MAX_DELAY does not seem to change the 0xFF behaviour.
2020-08-11 06:36 AM
> I've updated my post
Well, you also changed the code. In the previous version, payload was 3 bytes.
2020-08-11 06:38 AM
Yes, I tried different things. Previously the 'id' field was commented out and I tried putting all the data in the 'payload' fields by adding a byte there - but it made no difference. Running the code above has the same result as before.
2020-08-12 02:13 AM
The code is nonsense. I don't see any code where slave would be responding to master. I see only code where slave is non-stop trying to "transmit" on it's own. Do you even understand why slave is called slave? That's because it cannot initiate a transfer!
2020-08-12 06:27 AM
> I see only code where slave is non-stop trying to "transmit" on it's own.
The code waits for the master to initiate and then sends a response while the master continues to clock SCL. That's how it works.