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 <michall...@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 <michall...@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);

Reply via email to