You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2025/07/18 15:08:44 UTC
(nuttx) branch master updated: drivers/ioexpander/icjx.c: reconfigure icjx after undervoltage
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e96ef8abe3 drivers/ioexpander/icjx.c: reconfigure icjx after undervoltage
e96ef8abe3 is described below
commit e96ef8abe35e731f4f561027da854c82a1a13886
Author: Michal Lenc <mi...@seznam.cz>
AuthorDate: Fri Jul 18 14:19:00 2025 +0200
drivers/ioexpander/icjx.c: reconfigure icjx after undervoltage
According to a reference manual, VCC and VDD undervoltage
and VDD burst leads to the reset of all registers.
Therefore we have to reconfigure the expander to make
it functional again.
Signed-off-by: Michal Lenc <mi...@seznam.cz>
---
drivers/ioexpander/icjx.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/drivers/ioexpander/icjx.c b/drivers/ioexpander/icjx.c
index 2ac573044a..4d7ca3efdb 100644
--- a/drivers/ioexpander/icjx.c
+++ b/drivers/ioexpander/icjx.c
@@ -932,6 +932,74 @@ static int icjx_detach(FAR struct ioexpander_dev_s *dev, FAR void *handle)
return OK;
}
+/****************************************************************************
+ * Name: icjx_reconfigure
+ *
+ * Description:
+ * Reconfigure icjx chip. This might be required if VCC or VDD drops
+ * below a limit or if VDD burst occurs as registers are reset to a
+ * default state.
+ *
+ * Input Parameters:
+ * priv - Private icjx data structure.
+ *
+ * Returned Value:
+ * 0 on success, else a negative error code
+ *
+ ****************************************************************************/
+
+static int icjx_reconfigure(FAR struct icjx_dev_s *priv)
+{
+ FAR struct icjx_config_s *config = priv->config;
+ uint8_t regval;
+ uint16_t direction;
+ int ret;
+
+ ret = nxmutex_lock(&priv->lock);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ /* Re-enable pull ups */
+
+ regval = (config->current_src << 4) | config->current_src;
+ icjx_write(priv, ICJX_CTRL_WORD_2_A, regval, ICJX_NOB1);
+ icjx_write(priv, ICJX_CTRL_WORD_2_B, regval, ICJX_NOB1);
+
+ /* Re-enable filters */
+
+ if (config->filters != ICJX_CTRL_WORD_FILTER_DISABLED)
+ {
+ regval = ICJX_CTRL_WORD_3_ICLK;
+ }
+ else
+ {
+ regval = ICJX_CTRL_WORD_3_DIS;
+ }
+
+ icjx_write(priv, ICJX_CTRL_WORD_3_B, regval, ICJX_NOB1);
+ regval = (config->filters << 4) | config->filters;
+ icjx_write(priv, ICJX_CTRL_WORD_1_A, regval, ICJX_NOB1);
+ icjx_write(priv, ICJX_CTRL_WORD_1_B, regval, ICJX_NOB1);
+
+ /* Re-enable outputs */
+
+ icjx_read(priv, ICJX_CTRL_WORD_2_A, &direction, ICJX_NOB2);
+ direction |= priv->outpins & 0xf ? ICJX_CTRL_WORD_2_NIOL : 0;
+ direction |= priv->outpins & 0xf0 ? ICJX_CTRL_WORD_2_NIOH : 0;
+ direction |= priv->outpins & 0xf00 ? ICJX_CTRL_WORD_2_NIOL << 8 : 0;
+ direction |= priv->outpins & 0xf000 ? ICJX_CTRL_WORD_2_NIOH << 8 : 0;
+ icjx_write(priv, ICJX_CTRL_WORD_2_A, direction, ICJX_NOB2);
+
+ /* Re-enable interrupts */
+
+ icjx_write(priv, ICJX_CHNG_INT_EN_A, priv->irqpins, ICJX_NOB2);
+
+ nxmutex_unlock(&priv->lock);
+ return 0;
+}
+
/****************************************************************************
* Name: icjx_interrupt_worker
*
@@ -978,6 +1046,18 @@ static void icjx_interrupt_worker(void *arg)
}
}
+ if (((isr >> 8) & (ICJX_ISR_B_IUSA | ICJX_ISR_B_IUSD |
+ ICJX_ISR_B_ISD)) != 0)
+ {
+ /* According to a reference manual, VCC and VDD undervoltage
+ * and VDD burst leads to the reset of all registers.
+ * Therefore we have to reconfigure the expander to make
+ * it functional again.
+ */
+
+ icjx_reconfigure(priv);
+ }
+
/* Clear interrupt and check ISR again */
icjx_write(priv, ICJX_CTRL_WORD_4, ICJX_CTRL_WORD_4_EOI, ICJX_NOB1);