mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 11:56:10 +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;
|
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
|
* 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 */
|
/* Clear interrupt and check ISR again */
|
||||||
|
|
||||||
icjx_write(priv, ICJX_CTRL_WORD_4, ICJX_CTRL_WORD_4_EOI, ICJX_NOB1);
|
icjx_write(priv, ICJX_CTRL_WORD_4, ICJX_CTRL_WORD_4_EOI, ICJX_NOB1);
|
||||||
|
|||||||
Reference in New Issue
Block a user