Merged in david_s5/nuttx/master_stm32_f4_i2c (pull request #490)
stm32:stm32f40xxx I2C ensure proper isr handling Injecting data errors that causes a STOP to be perceived by the driver, will continually re-enter the isr with SB not set and BTF and RxNE set. This changes allows the interrupts to be cleared and propagates a I2C_SR1_TIMEOUT to the waiting task. Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
parent
05f2e9cdc1
commit
a3364b5bd9
@ -1250,12 +1250,24 @@ static int stm32_i2c_isr_process(struct stm32_i2c_priv_s *priv)
|
||||
priv->status = status;
|
||||
|
||||
/* Any new message should begin with "Start" condition
|
||||
* Situation priv->msgc == 0 came from DMA RX handler and should be managed
|
||||
* However there were 2 situations where that was not true
|
||||
* Situation 1: priv->msgc == 0 came from DMA RX handler and should
|
||||
* be managed
|
||||
*
|
||||
* Situation 2: If an error is injected that looks like a STOP the
|
||||
* interrupt will be reentered with some status that will be incorrect. This
|
||||
* will ensure that the error handler will clear the interrupt enables and
|
||||
* return the error to the waiting task.
|
||||
*/
|
||||
|
||||
if (priv->dcnt == -1 && priv->msgc != 0 && (status & I2C_SR1_SB) == 0)
|
||||
{
|
||||
#ifdef CONFIG_STM32_I2C_DMA
|
||||
return OK;
|
||||
#else
|
||||
priv->status |= I2C_SR1_TIMEOUT;
|
||||
goto state_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check if this is a new transmission so to set up the
|
||||
@ -2026,6 +2038,9 @@ static int stm32_i2c_isr_process(struct stm32_i2c_priv_s *priv)
|
||||
|
||||
/* Clear interrupt flags */
|
||||
|
||||
#ifndef CONFIG_STM32_I2C_DMA
|
||||
state_error:
|
||||
#endif
|
||||
stm32_i2c_putreg(priv, STM32_I2C_SR1_OFFSET, 0);
|
||||
|
||||
priv->dcnt = -1;
|
||||
|
Loading…
Reference in New Issue
Block a user