Skip to content

Commit

Permalink
arch/risc-v/src/mpfs/mpfs_i2c.c: Clean up using priv->status and STOP…
Browse files Browse the repository at this point in the history
… interrupts

- There are occasional extra STOPs being sent due to an IP bug when using an
  FPGA based I2C. Add a flag "inflight" to mask out extra STOP interrupts when
  using the FPGA based implementation
- There are no MPFS_I2C_ST_STOP_SENT irq's "initally". It is just already
  either success or still in progress

Signed-off-by: Jukka Laitinen <[email protected]>
  • Loading branch information
Jukka Laitinen committed Sep 11, 2023
1 parent 537e3ff commit bcf02ad
Showing 1 changed file with 36 additions and 34 deletions.
70 changes: 36 additions & 34 deletions arch/risc-v/src/mpfs/mpfs_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ struct mpfs_i2c_priv_s

bool initialized; /* Bus initialization status */
bool fpga; /* FPGA i2c */
bool inflight; /* Transfer ongoing */
};

#ifndef CONFIG_MPFS_COREI2C
Expand Down Expand Up @@ -447,6 +448,8 @@ static int mpfs_i2c_irq(int cpuint, void *context, void *arg)
{
priv->tx_idx = 0u;
}

priv->inflight = true;
break;

case MPFS_I2C_ST_LOST_ARB:
Expand Down Expand Up @@ -479,7 +482,7 @@ static int mpfs_i2c_irq(int cpuint, void *context, void *arg)
clear_irq = 0u;
modifyreg32(MPFS_I2C_CTRL, 0, MPFS_I2C_CTRL_STA_MASK);

/* Jump to the next message */
/* Jump to the next message */

priv->msgid++;
}
Expand All @@ -498,7 +501,7 @@ static int mpfs_i2c_irq(int cpuint, void *context, void *arg)
clear_irq = 0u;
modifyreg32(MPFS_I2C_CTRL, 0, MPFS_I2C_CTRL_STA_MASK);

/* Jump to the next message */
/* Jump to the next message */

priv->msgid++;
}
Expand Down Expand Up @@ -566,12 +569,33 @@ static int mpfs_i2c_irq(int cpuint, void *context, void *arg)
break;

case MPFS_I2C_ST_IDLE:
case MPFS_I2C_ST_STOP_SENT:

/* No activity, bus idle */

break;

case MPFS_I2C_ST_STOP_SENT:

/* FPGA driver terminates all transactions with STOP sent irq
* if there has been no errors, the transfer succeeded.
* Due to the IP bug that extra data & STOPs can be sent after
* the actual transaction, filter out any extra stops with
* priv->inflight flag
*/

if (priv->inflight)
{
if (priv->status == MPFS_I2C_IN_PROGRESS)
{
priv->status = MPFS_I2C_SUCCESS;
}

nxsem_post(&priv->sem_isr);
}

priv->inflight = false;
break;

case MPFS_I2C_ST_RESET_ACTIVATED:
case MPFS_I2C_ST_BUS_ERROR: /* Bus errors */
default:
Expand All @@ -586,31 +610,12 @@ static int mpfs_i2c_irq(int cpuint, void *context, void *arg)
break;
}

if (priv->fpga)
{
/* FPGA driver terminates all transactions with STOP sent irq */
if (!priv->fpga && priv->status != MPFS_I2C_IN_PROGRESS)
{
/* MSS I2C has no STOP sent irq */

if (status == MPFS_I2C_ST_STOP_SENT)
{
/* Don't post on a new request, STOPs possible initially */

if (!((priv->rx_idx == 0 && priv->rx_size > 0) ||
(priv->tx_idx == 0 && priv->tx_size > 0)))
{
nxsem_post(&priv->sem_isr);
}
else if (priv->status == MPFS_I2C_FAILED)
{
nxsem_post(&priv->sem_isr);
}
}
}
else if (priv->status != MPFS_I2C_IN_PROGRESS)
{
/* MSS I2C has no STOP SENT irq */

nxsem_post(&priv->sem_isr);
}
nxsem_post(&priv->sem_isr);
}

if (clear_irq)
{
Expand Down Expand Up @@ -642,7 +647,7 @@ static int mpfs_i2c_irq(int cpuint, void *context, void *arg)
static void mpfs_i2c_sendstart(struct mpfs_i2c_priv_s *priv)
{
up_enable_irq(priv->plic_irq);
modifyreg32(MPFS_I2C_CTRL, MPFS_I2C_CTRL_STA_MASK, MPFS_I2C_CTRL_STA_MASK);
modifyreg32(MPFS_I2C_CTRL, 0, MPFS_I2C_CTRL_STA_MASK);
}

static int mpfs_i2c_transfer(struct i2c_master_s *dev,
Expand All @@ -661,11 +666,6 @@ static int mpfs_i2c_transfer(struct i2c_master_s *dev,
return ret;
}

if (priv->status != MPFS_I2C_SUCCESS)
{
priv->status = MPFS_I2C_SUCCESS;
}

priv->msgv = msgs;

for (int i = 0; i < count; i++)
Expand Down Expand Up @@ -728,6 +728,7 @@ static int mpfs_i2c_transfer(struct i2c_master_s *dev,
if (mpfs_i2c_sem_waitdone(priv) < 0)
{
i2cinfo("Message %" PRIu8 " timed out.\n", priv->msgid);
priv->inflight = false;
ret = -ETIMEDOUT;
break;
}
Expand All @@ -741,7 +742,6 @@ static int mpfs_i2c_transfer(struct i2c_master_s *dev,
}
else
{
priv->status = MPFS_I2C_SUCCESS;
ret = OK;
}
}
Expand Down Expand Up @@ -784,6 +784,8 @@ static int mpfs_i2c_reset(struct i2c_master_s *dev)

up_disable_irq(priv->plic_irq);

priv->inflight = false;
priv->status = MPFS_I2C_SUCCESS;
priv->initialized = false;

ret = mpfs_i2c_init(priv);
Expand Down

0 comments on commit bcf02ad

Please sign in to comment.