-
Notifications
You must be signed in to change notification settings - Fork 101
Description
Tested on R7FA4E10B2CFM.
Preparation:
r_iic_master is opened (p_api->open) and in result STIE/SPIE interrupts are disabled (iic_master_open_hw_master)
Bug trigger:
If another master (or an EMI event) changes the SDA line state (easily simulated by grounding SDA to GND for a moment), the IIC module will silently (because SPIE interrupt is disabled) detect the I2C stop and set ICSR2_b.STOP flag.
Effects:
- User attempts (for example) to read data by calling p_api->read
- In iic_master_run_hw_master STIE, SPIE interrupts will be enabled.
- Since the ICSR2_b.STOP flag is set, this will trigger the eri interrupt
- iic_master_err_master will detect the IIC_MASTER_ERR_EVENT_STOP flag and send I2C_MASTER_EVENT_RX_COMPLETE to the user before receiving any data
- iic_master_err_master will also disable STIE/SPIE interrupts
- iic_master_rxi_master will continue receiving data in the background (user application will assume the transfer has already completed) and (if the data buffer was on the stack) will corrupt the memory
- After all data has beed transferred, iic_master_rxi_master will send an I2C STOP, which will set (again) silently (because SPIE interrupt is disabled) the ICSR2_b.STOP flag
- Bug is triggered again and is ready to affect a new transfer
Temporary walkaround:
My quick fix is to check before each p_api->read/p_api->write call if the ICSR2_b.STOP flag is set and clear it.
It will limit the bug trigger window to time between p_api->read/p_api->write call and
p_ctrl->p_reg->ICIER = IIC_MASTER_INTERRUPT_ENABLE_INIT_MASK | R_IIC0_ICIER_STIE_Msk | R_IIC0_ICIER_SPIE_Msk; line in iic_master_run_hw_master.
Additional comment:
This walkaround is not ideal, because this bug can be also triggered by EMI event during transmission.
In my opinion additional checks should be implemented in iic_master_err_master to check if IIC_MASTER_ERR_EVENT_STOP is valid (all data has been transferred) before sending the I2C_MASTER_EVENT_xX_COMPLETE event to the user app.
If the IIC_MASTER_ERR_EVENT_STOP is invalid - abort the transmission (including sending the I2C_MASTER_EVENT_ABORTED event to the user app because transferred data is potentialy damaged).