Veo que una vez que se escribe la dirección del esclavo en el manejador de interrupción, obtengo un Fallo ACK de inmediato, pero cuando hago lo mismo con el enfoque de sondeo, sí obtengo un ACK y pasa a leer los valores del dispositivo.
Con las interrupciones, veo que el ISR se activa sólo una vez (en la que escribe la dirección del esclavo) y nunca es llamado de nuevo. Mis configuraciones i2c están bien, pero hay algo con las interrupciones que parece que me estoy perdiendo.
Enfoque de sondeo
HAL_StatusTypeDef HAL_I2C_Master_Transmit (I2C *hi2c, uint8_t *data, uint8_t size)
{
GenerateStartCondition();
// validate the completion of start condition
while (!GetFlagStatus(hi2c->Instance, I2C_SR1_SB) && HAL_Timeout(5));
// write slave address along with write bit
I2C_WriteSlaveAddress(hi2c, WRITE);
// wait for address to be sent
while (!GetFlagStatus(hi2c->Instance, I2C_SR1_ADDR) && HAL_Timeout(5));
// clear address flag
I2C_ClearADDRFlag(hi2c->Instance);
// write data to DR ...
}
Con interrupciones:
void HAL_StartI2CInterrupts() {
GenerateStartCondition();
// setting control bits
hi2c->Instance->CR2 |= I2C_CR2_ITBUFEN;
hi2c->Instance->CR2 |= I2C_CR2_ITEVTEN;
hi2c->Instance->CR2 |= I2C_CR2_ITERREN;
void I2C1_EV_IRQHandler ()
{
uint8_t event_interrupt = (hi2c->Instance->CR2 & I2C_CR2_ITEVTEN) >> I2C_CR2_ITEVTEN_Pos;
uint8_t buffer_interrupt = (hi2c->Instance->CR2 & I2C_CR2_ITBUFEN) >> I2C_CR2_ITBUFEN_Pos;
uint8_t var;
if (event_interrupt)
{
// validate the completion of START condition
var = (hi2c->Instance->SR1 & I2C_SR1_SB) >> I2C_SR1_SB_Pos;
if (var)
{
if (hi2c->I2C_State == I2C_TX_BUSY)
{
I2C_WriteSlaveAddress(hi2c, WRITE);
}
}
// check ADDR bit ...
}
}