According to I2C specifications, when so-called "combined format" is used,
there should be "repeated START" in between configuration stage (internal start and stop addresses, and the number of bytes to read) and READ function, but no STOP.
When the interface encounters STOP, it "forgets" the submitted read parameters, so the next stand-alone READ doesn't know where to read from, and NAKs.
These Callback functions are called from the I2C interrupt handler. You shouldn't make other API calls from them. HAL_I2C_Master_Transmit_IT() check timeouts etc which might not work from an interrupt handler. This might a reason for slow execution, but regardless it's bad practice. A safer route is to set a global (and volatile) variable, and check for it in the main loop:
volatile bool RxComplete = false;
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) {
RxComplete = true;
}
void main(void) {
while (true) {
if (RxComplete) {
RxComplete = false;
HAL_I2C_Master_Transmit_IT(&hi2c1,0x28<<1,0,0);
}
}
}
In fact, in my copy of FreeRTOS 9.0, there's a bug in HAL_I2C_Master_Transmit_IT(). It calls
I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG)
But the signature is
static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
The argument Timeout gets the value I2C_TIMEOUT_BUSY_FLAG, which is not a timeout period. I haven't checked if newer versions fix this bug.
In general, I suggest to set/clear a GPIO pin at select points in your code. This will be very telling to track down where the delay is.
Best Answer
The MEM functios can directly read and write devices that have register address based access. They write the register addresss before reading or writing the register data. Most chips are like this. The non-MEM functions just do simple reads and writes.