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);