mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 03:05:40 +08:00
Fix for lpc17xx i2c single byte read timeout error problem from M.Kannan
This commit is contained in:
@@ -4687,7 +4687,11 @@
|
|||||||
the "wfi" sleep mode. This is needed with certain JTAG debuggers to
|
the "wfi" sleep mode. This is needed with certain JTAG debuggers to
|
||||||
to prevent the debug session from begin disconnected. From Ken Pettit
|
to prevent the debug session from begin disconnected. From Ken Pettit
|
||||||
(2013-5-7).
|
(2013-5-7).
|
||||||
* configs/mikroe-stm32f4/fulldemo/, nx/, nxlines/, nxtext/: Add more
|
* configs/mikroe-stm32f4/fulldemo/, nx/, nxlines/, nxtext/: Add more
|
||||||
configurationsf for the Mikroelektronika Multimedia STM32-M4 board.
|
configurationsf for the Mikroelektronika Multimedia STM32-M4 board.
|
||||||
From Ken Pettit (2013-5-7).
|
From Ken Pettit (2013-5-7).
|
||||||
*
|
* configs/mikroe-stm32f4/src/up_mio283qt2.c and other files: Integrate the
|
||||||
|
MIO283QT2 display on the Mikroelektronika Multimedia STM32-M4 board.
|
||||||
|
From Ken Pettit (2013-5-7).
|
||||||
|
* arch/arm/src/lpc17xx/lpc17_i2c.c: Fix for lpc17xx i2c single byte read
|
||||||
|
timeout error problem from M.Kannan (2013-5-8).
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* Copyright (C) 2011 Li Zhuoyi. All rights reserved.
|
* Copyright (C) 2011 Li Zhuoyi. All rights reserved.
|
||||||
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
|
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
|
||||||
* History: 0.1 2011-08-20 initial version
|
* History: 0.1 2011-08-20 initial version
|
||||||
*
|
*
|
||||||
* Derived from arch/arm/src/lpc31xx/lpc31_i2c.c
|
* Derived from arch/arm/src/lpc31xx/lpc31_i2c.c
|
||||||
*
|
*
|
||||||
* Author: David Hewson
|
* Author: David Hewson
|
||||||
@@ -199,7 +199,7 @@ static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
|
|||||||
DEBUGASSERT(dev != NULL);
|
DEBUGASSERT(dev != NULL);
|
||||||
DEBUGASSERT(nbits == 7 );
|
DEBUGASSERT(nbits == 7 );
|
||||||
|
|
||||||
priv->msg.addr = addr<<1;
|
priv->msg.addr = addr << 1;
|
||||||
priv->msg.flags = 0 ;
|
priv->msg.flags = 0 ;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -221,12 +221,12 @@ static int i2c_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int bufle
|
|||||||
|
|
||||||
DEBUGASSERT(dev != NULL);
|
DEBUGASSERT(dev != NULL);
|
||||||
|
|
||||||
priv->wrcnt = 0;
|
priv->wrcnt = 0;
|
||||||
priv->rdcnt = 0;
|
priv->rdcnt = 0;
|
||||||
priv->msg.addr &= ~0x01;
|
priv->msg.addr &= ~0x01;
|
||||||
priv->msg.buffer = (uint8_t*)buffer;
|
priv->msg.buffer = (uint8_t*)buffer;
|
||||||
priv->msg.length = buflen;
|
priv->msg.length = buflen;
|
||||||
|
|
||||||
ret = i2c_start(priv);
|
ret = i2c_start(priv);
|
||||||
|
|
||||||
return ret > 0 ? OK : -ETIMEDOUT;
|
return ret > 0 ? OK : -ETIMEDOUT;
|
||||||
@@ -248,9 +248,9 @@ static int i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
|
|||||||
|
|
||||||
DEBUGASSERT(dev != NULL);
|
DEBUGASSERT(dev != NULL);
|
||||||
|
|
||||||
priv->wrcnt = 0;
|
priv->wrcnt = 0;
|
||||||
priv->rdcnt = 0;
|
priv->rdcnt = 0;
|
||||||
priv->msg.addr |= 0x01;
|
priv->msg.addr |= 0x01;
|
||||||
priv->msg.buffer = buffer;
|
priv->msg.buffer = buffer;
|
||||||
priv->msg.length = buflen;
|
priv->msg.length = buflen;
|
||||||
|
|
||||||
@@ -273,8 +273,8 @@ static int i2c_start(struct lpc17_i2cdev_s *priv)
|
|||||||
|
|
||||||
sem_wait(&priv->mutex);
|
sem_wait(&priv->mutex);
|
||||||
|
|
||||||
putreg32(I2C_CONCLR_STAC|I2C_CONCLR_SIC, priv->base+LPC17_I2C_CONCLR_OFFSET);
|
putreg32(I2C_CONCLR_STAC | I2C_CONCLR_SIC, priv->base + LPC17_I2C_CONCLR_OFFSET);
|
||||||
putreg32(I2C_CONSET_STA, priv->base+LPC17_I2C_CONSET_OFFSET);
|
putreg32(I2C_CONSET_STA, priv->base + LPC17_I2C_CONSET_OFFSET);
|
||||||
|
|
||||||
wd_start(priv->timeout, I2C_TIMEOUT, i2c_timeout, 1, (uint32_t)priv);
|
wd_start(priv->timeout, I2C_TIMEOUT, i2c_timeout, 1, (uint32_t)priv);
|
||||||
sem_wait(&priv->wait);
|
sem_wait(&priv->wait);
|
||||||
@@ -291,7 +291,7 @@ static int i2c_start(struct lpc17_i2cdev_s *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Name: i2c_stop
|
* Name: i2c_stop
|
||||||
@@ -305,7 +305,7 @@ static void i2c_stop(struct lpc17_i2cdev_s *priv)
|
|||||||
{
|
{
|
||||||
if (priv->state != 0x38)
|
if (priv->state != 0x38)
|
||||||
{
|
{
|
||||||
putreg32(I2C_CONSET_STO|I2C_CONSET_AA,priv->base+LPC17_I2C_CONSET_OFFSET);
|
putreg32(I2C_CONSET_STO | I2C_CONSET_AA, priv->base + LPC17_I2C_CONSET_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
sem_post(&priv->wait);
|
sem_post(&priv->wait);
|
||||||
@@ -367,39 +367,39 @@ static int i2c_interrupt(int irq, FAR void *context)
|
|||||||
PANIC();
|
PANIC();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reference UM10360 19.10.5 */
|
/* Reference UM10360 19.10.5 */
|
||||||
|
|
||||||
state = getreg32(priv->base+LPC17_I2C_STAT_OFFSET);
|
state = getreg32(priv->base + LPC17_I2C_STAT_OFFSET);
|
||||||
putreg32(I2C_CONCLR_SIC, priv->base+LPC17_I2C_CONCLR_OFFSET);
|
putreg32(I2C_CONCLR_SIC, priv->base + LPC17_I2C_CONCLR_OFFSET);
|
||||||
priv->state = state;
|
priv->state = state;
|
||||||
state &= 0xf8;
|
state &= 0xf8;
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case 0x00: // Bus Error
|
case 0x00: // Bus Error
|
||||||
case 0x20:
|
case 0x20:
|
||||||
case 0x30:
|
case 0x30:
|
||||||
case 0x38:
|
case 0x38:
|
||||||
case 0x48:
|
case 0x48:
|
||||||
i2c_stop(priv);
|
i2c_stop(priv);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08: // START
|
case 0x08: // START
|
||||||
case 0x10: // Repeat START
|
case 0x10: // Repeat START
|
||||||
putreg32(priv->msg.addr, priv->base+LPC17_I2C_DAT_OFFSET);
|
putreg32(priv->msg.addr, priv->base + LPC17_I2C_DAT_OFFSET);
|
||||||
putreg32(I2C_CONCLR_STAC, priv->base+LPC17_I2C_CONCLR_OFFSET);
|
putreg32(I2C_CONCLR_STAC, priv->base + LPC17_I2C_CONCLR_OFFSET);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x18:
|
case 0x18:
|
||||||
priv->wrcnt = 0;
|
priv->wrcnt = 0;
|
||||||
putreg32(priv->msg.buffer[0], priv->base+LPC17_I2C_DAT_OFFSET);
|
putreg32(priv->msg.buffer[0], priv->base + LPC17_I2C_DAT_OFFSET);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x28:
|
case 0x28:
|
||||||
priv->wrcnt++;
|
priv->wrcnt++;
|
||||||
if (priv->wrcnt<priv->msg.length)
|
if (priv->wrcnt<priv->msg.length)
|
||||||
{
|
{
|
||||||
putreg32(priv->msg.buffer[priv->wrcnt],priv->base+LPC17_I2C_DAT_OFFSET);
|
putreg32(priv->msg.buffer[priv->wrcnt], priv->base + LPC17_I2C_DAT_OFFSET);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -408,20 +408,20 @@ static int i2c_interrupt(int irq, FAR void *context)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x40:
|
case 0x40:
|
||||||
priv->rdcnt = -1;
|
priv->rdcnt = 0;
|
||||||
putreg32(I2C_CONSET_AA, priv->base+LPC17_I2C_CONSET_OFFSET);
|
putreg32(I2C_CONSET_AA, priv->base + LPC17_I2C_CONSET_OFFSET);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x50:
|
case 0x50:
|
||||||
priv->rdcnt++;
|
|
||||||
if (priv->rdcnt < priv->msg.length)
|
if (priv->rdcnt < priv->msg.length)
|
||||||
{
|
{
|
||||||
priv->msg.buffer[priv->rdcnt] = getreg32(priv->base+LPC17_I2C_BUFR_OFFSET);
|
priv->msg.buffer[priv->rdcnt] = getreg32(priv->base + LPC17_I2C_BUFR_OFFSET);
|
||||||
|
priv->rdcnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->rdcnt>=priv->msg.length-1)
|
if (priv->rdcnt >= priv->msg.length)
|
||||||
{
|
{
|
||||||
putreg32(I2C_CONCLR_AAC|I2C_CONCLR_SIC, priv->base+LPC17_I2C_CONCLR_OFFSET);
|
putreg32(I2C_CONCLR_AAC | I2C_CONCLR_SIC, priv->base + LPC17_I2C_CONCLR_OFFSET);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -479,10 +479,10 @@ struct i2c_dev_s *up_i2cinitialize(int port)
|
|||||||
regval &= ~SYSCON_PCLKSEL0_I2C0_MASK;
|
regval &= ~SYSCON_PCLKSEL0_I2C0_MASK;
|
||||||
regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL0_I2C0_SHIFT);
|
regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL0_I2C0_SHIFT);
|
||||||
putreg32(regval, LPC17_SYSCON_PCLKSEL0);
|
putreg32(regval, LPC17_SYSCON_PCLKSEL0);
|
||||||
|
|
||||||
lpc17_configgpio(GPIO_I2C0_SCL);
|
lpc17_configgpio(GPIO_I2C0_SCL);
|
||||||
lpc17_configgpio(GPIO_I2C0_SDA);
|
lpc17_configgpio(GPIO_I2C0_SDA);
|
||||||
|
|
||||||
putreg32(LPC17_CCLK/CONFIG_I2C0_FREQ/2, priv->base + LPC17_I2C_SCLH_OFFSET);
|
putreg32(LPC17_CCLK/CONFIG_I2C0_FREQ/2, priv->base + LPC17_I2C_SCLH_OFFSET);
|
||||||
putreg32(LPC17_CCLK/CONFIG_I2C0_FREQ/2, priv->base + LPC17_I2C_SCLL_OFFSET);
|
putreg32(LPC17_CCLK/CONFIG_I2C0_FREQ/2, priv->base + LPC17_I2C_SCLL_OFFSET);
|
||||||
}
|
}
|
||||||
@@ -527,10 +527,10 @@ struct i2c_dev_s *up_i2cinitialize(int port)
|
|||||||
regval &= ~SYSCON_PCLKSEL1_I2C2_MASK;
|
regval &= ~SYSCON_PCLKSEL1_I2C2_MASK;
|
||||||
regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL1_I2C2_SHIFT);
|
regval |= (SYSCON_PCLKSEL_CCLK << SYSCON_PCLKSEL1_I2C2_SHIFT);
|
||||||
putreg32(regval, LPC17_SYSCON_PCLKSEL1);
|
putreg32(regval, LPC17_SYSCON_PCLKSEL1);
|
||||||
|
|
||||||
lpc17_configgpio(GPIO_I2C2_SCL);
|
lpc17_configgpio(GPIO_I2C2_SCL);
|
||||||
lpc17_configgpio(GPIO_I2C2_SDA);
|
lpc17_configgpio(GPIO_I2C2_SDA);
|
||||||
|
|
||||||
putreg32(LPC17_CCLK/CONFIG_I2C2_FREQ/2, priv->base + LPC17_I2C_SCLH_OFFSET);
|
putreg32(LPC17_CCLK/CONFIG_I2C2_FREQ/2, priv->base + LPC17_I2C_SCLH_OFFSET);
|
||||||
putreg32(LPC17_CCLK/CONFIG_I2C2_FREQ/2, priv->base + LPC17_I2C_SCLL_OFFSET);
|
putreg32(LPC17_CCLK/CONFIG_I2C2_FREQ/2, priv->base + LPC17_I2C_SCLL_OFFSET);
|
||||||
}
|
}
|
||||||
@@ -541,7 +541,7 @@ struct i2c_dev_s *up_i2cinitialize(int port)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
putreg32(I2C_CONSET_I2EN, priv->base+LPC17_I2C_CONSET_OFFSET);
|
putreg32(I2C_CONSET_I2EN, priv->base + LPC17_I2C_CONSET_OFFSET);
|
||||||
|
|
||||||
sem_init(&priv->mutex, 0, 1);
|
sem_init(&priv->mutex, 0, 1);
|
||||||
sem_init(&priv->wait, 0, 0);
|
sem_init(&priv->wait, 0, 0);
|
||||||
@@ -578,10 +578,10 @@ struct i2c_dev_s *up_i2cinitialize(int port)
|
|||||||
int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
|
int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
|
||||||
{
|
{
|
||||||
struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) dev;
|
struct lpc17_i2cdev_s *priv = (struct lpc17_i2cdev_s *) dev;
|
||||||
|
|
||||||
/* Disable I2C */
|
/* Disable I2C */
|
||||||
|
|
||||||
putreg32(I2C_CONCLRT_I2ENC, priv->base+LPC17_I2C_CONCLR_OFFSET);
|
putreg32(I2C_CONCLRT_I2ENC, priv->base + LPC17_I2C_CONCLR_OFFSET);
|
||||||
|
|
||||||
/* Reset data structures */
|
/* Reset data structures */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user