mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 03:45:50 +08:00
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 <michallenc@seznam.cz>
This commit is contained in:
committed by
Alan C. Assis
parent
cbdc1a4108
commit
e96ef8abe3
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user