mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 07:12:54 +08:00
arch/risc-v/src/mpfs/mpfs_i2c.c: Recover i2c from pending transactions in warm boot
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
committed by
Xiang Xiao
parent
2b10b38c1d
commit
df01c83c25
@@ -304,12 +304,57 @@ static uint32_t mpfs_i2c_timeout(int msgc, struct i2c_msg_s *msgv);
|
|||||||
static int mpfs_i2c_init(struct mpfs_i2c_priv_s *priv)
|
static int mpfs_i2c_init(struct mpfs_i2c_priv_s *priv)
|
||||||
{
|
{
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
uint32_t ctrl;
|
||||||
|
uint32_t status;
|
||||||
|
|
||||||
if (!priv->initialized)
|
if (!priv->initialized)
|
||||||
{
|
{
|
||||||
/* Clear any pending serial interrupt flag */
|
/* In case of warm boot, or after reset, check that the IP block is
|
||||||
|
* not already active and try to recover from any pending data
|
||||||
|
* transfer if it is.
|
||||||
|
*/
|
||||||
|
|
||||||
modifyreg32(MPFS_I2C_CTRL, MPFS_I2C_CTRL_SI_MASK, 0);
|
ctrl = getreg32(MPFS_I2C_CTRL);
|
||||||
|
if (ctrl != 0)
|
||||||
|
{
|
||||||
|
/* Check if the IP is enabled */
|
||||||
|
|
||||||
|
status = getreg32(MPFS_I2C_STATUS);
|
||||||
|
if (ctrl & MPFS_I2C_CTRL_ENS1_MASK)
|
||||||
|
{
|
||||||
|
if (status == MPFS_I2C_ST_RX_DATA_ACK)
|
||||||
|
{
|
||||||
|
/* In case the machine was in the middle of data RX, try to
|
||||||
|
* receive one byte and nack it
|
||||||
|
*/
|
||||||
|
|
||||||
|
modifyreg32(MPFS_I2C_CTRL, MPFS_I2C_CTRL_AA_MASK, 0);
|
||||||
|
modifyreg32(MPFS_I2C_CTRL, MPFS_I2C_CTRL_SI_MASK, 0);
|
||||||
|
usleep(100);
|
||||||
|
status = getreg32(MPFS_I2C_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != MPFS_I2C_ST_IDLE)
|
||||||
|
{
|
||||||
|
/* If the bus is not idle, send STOP */
|
||||||
|
|
||||||
|
modifyreg32(MPFS_I2C_CTRL, MPFS_I2C_CTRL_SI_MASK, 0);
|
||||||
|
modifyreg32(MPFS_I2C_CTRL, 0, MPFS_I2C_CTRL_STO_MASK);
|
||||||
|
usleep(100);
|
||||||
|
modifyreg32(MPFS_I2C_CTRL, MPFS_I2C_CTRL_SI_MASK, 0);
|
||||||
|
status = getreg32(MPFS_I2C_STATUS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != MPFS_I2C_ST_IDLE)
|
||||||
|
{
|
||||||
|
i2cerr("Bus not idle before init\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable IP and continue initialization */
|
||||||
|
|
||||||
|
putreg32(0, MPFS_I2C_CTRL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Attach interrupt */
|
/* Attach interrupt */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user