Add support for stm32 F4 I2C3

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4333 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-01-25 19:31:01 +00:00
parent e7da66183d
commit 3ce7ab5031
2 changed files with 88 additions and 15 deletions

View File

@ -127,7 +127,7 @@
#define STM32_UART5_BASE 0x40005000 /* 0x40005000-0x400053ff: UART5 */
#define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff: I2C1 */
#define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005Bff: I2C2 */
#define STM32_I2C3_BASE 0x40005800 /* 0x40005c00-0x40005fff: I2C3 */
#define STM32_I2C3_BASE 0x40005C00 /* 0x40005c00-0x40005fff: I2C3 */
#define STM32_CAN1_BASE 0x40006400 /* 0x40006400-0x400067ff: bxCAN1 */
#define STM32_CAN2_BASE 0x40006800 /* 0x40006800-0x40006bff: bxCAN2 */
#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff: Power control PWR */

View File

@ -96,7 +96,7 @@
#include "stm32_i2c.h"
#include "stm32_waste.h"
#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2)
#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3)
/************************************************************************************
* Pre-processor Definitions
@ -141,7 +141,7 @@
#ifndef CONFIG_I2C_TRACE
# define stm32_i2c_tracereset(p)
# define stm32_i2c_tracenew(p,s)
# define stm32_i3c_traceevent(p,e,a)
# define stm32_i2c_traceevent(p,e,a)
# define stm32_i2c_tracedump(p)
#endif
@ -253,7 +253,7 @@ static inline void stm32_i2c_sem_destroy(FAR struct i2c_dev_s *dev);
#ifdef CONFIG_I2C_TRACE
static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv);
static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t status);
static void stm32_i3c_traceevent(FAR struct stm32_i2c_priv_s *priv,
static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv,
enum stm32_trace_e event, uint32_t parm);
static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv);
#endif
@ -275,6 +275,9 @@ static int stm32_i2c1_isr(int irq, void *context);
#ifdef CONFIG_STM32_I2C2
static int stm32_i2c2_isr(int irq, void *context);
#endif
#ifdef CONFIG_STM32_I2C3
static int stm32_i2c3_isr(int irq, void *context);
#endif
#endif
static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv);
static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv);
@ -330,6 +333,22 @@ struct stm32_i2c_priv_s stm32_i2c2_priv =
};
#endif
#ifdef CONFIG_STM32_I2C3
struct stm32_i2c_priv_s stm32_i2c3_priv =
{
.base = STM32_I2C3_BASE,
.refs = 0,
.intstate = INTSTATE_IDLE,
.msgc = 0,
.msgv = NULL,
.ptr = NULL,
.dcnt = 0,
.flags = 0,
.status = 0
};
#endif
/* Device Structures, Instantiation */
struct i2c_ops_s stm32_i2c_ops =
@ -681,7 +700,7 @@ static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t statu
}
}
static void stm32_i3c_traceevent(FAR struct stm32_i2c_priv_s *priv,
static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv,
enum stm32_trace_e event, uint32_t parm)
{
/* Add the event to the trace entry (possibly overwriting a previous trace
@ -957,7 +976,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
if ((status & I2C_SR1_SB) != 0)
{
stm32_i3c_traceevent(priv, I2CEVENT_SB, priv->msgc);
stm32_i2c_traceevent(priv, I2CEVENT_SB, priv->msgc);
/* Get run-time data */
@ -995,13 +1014,13 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
else if ((priv->flags & I2C_M_READ) == 0 && (status & (I2C_SR1_ADDR | I2C_SR1_TXE)) != 0)
{
stm32_i3c_traceevent(priv, I2CEVENT_READ, priv->dcnt);
stm32_i2c_traceevent(priv, I2CEVENT_READ, priv->dcnt);
if (--priv->dcnt >= 0)
{
/* Send a byte */
stm32_i3c_traceevent(priv, I2CEVENT_SENDBYTE, *priv->ptr);
stm32_i2c_traceevent(priv, I2CEVENT_SENDBYTE, *priv->ptr);
stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, *priv->ptr++);
}
}
@ -1011,7 +1030,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
/* Enable RxNE and TxE buffers in order to receive one or multiple bytes */
#ifndef CONFIG_I2C_POLLED
stm32_i3c_traceevent(priv, I2CEVENT_ITBUFEN, 0);
stm32_i2c_traceevent(priv, I2CEVENT_ITBUFEN, 0);
stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_ITBUFEN);
#endif
}
@ -1022,7 +1041,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
{
/* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */
stm32_i3c_traceevent(priv, I2CEVENT_RXNE, priv->dcnt);
stm32_i2c_traceevent(priv, I2CEVENT_RXNE, priv->dcnt);
if (--priv->dcnt >= 0)
{
*priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET);
@ -1043,12 +1062,12 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
#ifndef CONFIG_I2C_POLLED
if (priv->dcnt > 0)
{
stm32_i3c_traceevent(priv, I2CEVENT_REITBUFEN, 0);
stm32_i2c_traceevent(priv, I2CEVENT_REITBUFEN, 0);
stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_ITBUFEN);
}
else if (priv->dcnt == 0)
{
stm32_i3c_traceevent(priv, I2CEVENT_DISITBUFEN, 0);
stm32_i2c_traceevent(priv, I2CEVENT_DISITBUFEN, 0);
stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_ITBUFEN, 0);
}
#endif
@ -1069,7 +1088,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
if (priv->msgc > 0)
{
stm32_i3c_traceevent(priv, I2CEVENT_BTFSTART, priv->msgc);
stm32_i2c_traceevent(priv, I2CEVENT_BTFSTART, priv->msgc);
if (priv->msgv->flags & I2C_M_NORESTART)
{
priv->ptr = priv->msgv->buffer;
@ -1091,7 +1110,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
}
else if (priv->msgv)
{
stm32_i3c_traceevent(priv, I2CEVENT_BTFSTOP, 0);
stm32_i2c_traceevent(priv, I2CEVENT_BTFSTOP, 0);
stm32_i2c_sendstop(priv);
/* Is there a thread waiting for this event (there should be) */
@ -1123,7 +1142,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
if ((status & I2C_SR1_ERRORMASK) != 0)
{
stm32_i3c_traceevent(priv, I2CEVENT_ERROR, 0);
stm32_i2c_traceevent(priv, I2CEVENT_ERROR, 0);
/* Clear interrupt flags */
@ -1180,6 +1199,21 @@ static int stm32_i2c2_isr(int irq, void *context)
return stm32_i2c_isr(&stm32_i2c2_priv);
}
#endif
/************************************************************************************
* Name: stm32_i2c3_isr
*
* Description:
* I2C2 interrupt service routine
*
************************************************************************************/
#ifdef CONFIG_STM32_I2C3
static int stm32_i2c2_isr(int irq, void *context)
{
return stm32_i2c_isr(&stm32_i2c3_priv);
}
#endif
#endif
/************************************************************************************
@ -1268,6 +1302,40 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
break;
#endif
#ifdef CONFIG_STM32_I2C3
case STM32_I2C3_BASE:
/* Enable power and reset the peripheral */
modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_I2C3EN);
modifyreg32(STM32_RCC_APB1RSTR, 0, RCC_APB1RSTR_I2C3RST);
modifyreg32(STM32_RCC_APB1RSTR, RCC_APB1RSTR_I2C3RST, 0);
/* Configure pins */
if (stm32_configgpio(GPIO_I2C3_SCL) < 0)
{
return ERROR;
}
if (stm32_configgpio(GPIO_I2C3_SDA) < 0)
{
stm32_unconfiggpio(GPIO_I2C3_SCL);
return ERROR;
}
/* Attach ISRs */
#ifndef CONFIG_I2C_POLLED
irq_attach(STM32_IRQ_I2C3EV, stm32_i2c3_isr);
irq_attach(STM32_IRQ_I2C3ER, stm32_i2c3_isr);
up_enable_irq(STM32_IRQ_I2C3EV);
up_enable_irq(STM32_IRQ_I2C3ER);
#endif
break;
#endif
default:
return ERROR;
}
@ -1701,6 +1769,11 @@ FAR struct i2c_dev_s *up_i2cinitialize(int port)
case 2:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C3
case 3:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv;
break;
#endif
default:
return NULL;