STM32 F3 I2C driver from John Wharington

This commit is contained in:
Gregory Nutt 2013-07-30 10:35:17 -06:00
parent 4bdcceb3b3
commit 84150fd7ed
4 changed files with 2313 additions and 92 deletions

View File

@ -95,8 +95,7 @@ CHIP_ASRCS =
CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c
CHIP_CSRCS += stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c stm32_irq.c CHIP_CSRCS += stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c stm32_irq.c
CHIP_CSRCS += stm32_timerisr.c stm32_dma.c stm32_lowputc.c stm32_serial.c CHIP_CSRCS += stm32_timerisr.c stm32_dma.c stm32_lowputc.c stm32_serial.c
CHIP_CSRCS += stm32_spi.c stm32_sdio.c stm32_tim.c stm32_i2c.c stm32_waste.c CHIP_CSRCS += stm32_spi.c stm32_sdio.c stm32_tim.c stm32_waste.c stm32_ccm.c
CHIP_CSRCS += stm32_ccm.c
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
CHIP_ASRCS += stm32_vectors.S CHIP_ASRCS += stm32_vectors.S
@ -106,6 +105,12 @@ ifeq ($(CONFIG_NUTTX_KERNEL),y)
CHIP_CSRCS += stm32_userspace.c stm32_mpuinit.c CHIP_CSRCS += stm32_userspace.c stm32_mpuinit.c
endif endif
ifeq ($(CONFIG_STM32_STM32F30XX),y)
CHIP_CSRCS += stm32f30xx_i2c.c
else
CHIP_CSRCS += stm32_i2c.c
endif
ifeq ($(CONFIG_USBDEV),y) ifeq ($(CONFIG_USBDEV),y)
ifeq ($(CONFIG_STM32_USB),y) ifeq ($(CONFIG_STM32_USB),y)
CHIP_CSRCS += stm32_usbdev.c CHIP_CSRCS += stm32_usbdev.c

View File

@ -1,7 +1,7 @@
/************************************************************************************ /************************************************************************************
* arch/arm/src/stm32/chip/stm32f30xxx_i2c.h * arch/arm/src/stm32/chip/stm32f30xxx_i2c.h
* *
* Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -151,6 +151,7 @@
#define I2C_OAR1_OA1_7_SHIFT (1) /* Bits 1-7: 7-bit interface address */ #define I2C_OAR1_OA1_7_SHIFT (1) /* Bits 1-7: 7-bit interface address */
#define I2C_OAR1_OA1_7_MASK (0x7f << I2C_OAR1_OA1_7_SHIFT) #define I2C_OAR1_OA1_7_MASK (0x7f << I2C_OAR1_OA1_7_SHIFT)
#define I2C_OAR1_OA1MODE (1 << 10) /* Bit 10: Own Address 1 10-bit mode */ #define I2C_OAR1_OA1MODE (1 << 10) /* Bit 10: Own Address 1 10-bit mode */
#define I2C_OAR1_ONE (1 << 14) /* Bit 14: always keep on in software */
#define I2C_OAR1_OA1EN (1 << 15) /* Bit 15: Own Address 1 enable */ #define I2C_OAR1_OA1EN (1 << 15) /* Bit 15: Own Address 1 enable */
/* Own address register 2 */ /* Own address register 2 */
@ -174,16 +175,20 @@
#define I2C_TIMINGR_SCLL_SHIFT (0) /* Bits 0-7: SCL low period (master) */ #define I2C_TIMINGR_SCLL_SHIFT (0) /* Bits 0-7: SCL low period (master) */
#define I2C_TIMINGR_SCLL_MASK (0xff << I2C_TIMINGR_SCLL_SHIFT) #define I2C_TIMINGR_SCLL_MASK (0xff << I2C_TIMINGR_SCLL_SHIFT)
# define I2C_TIMINGR_SCLL(n) (((n)-1) << I2C_TIMINGR_SCLL_SHIFT) /* tSCLL = n x tPRESC */ # define I2C_TIMINGR_SCLL(n) (((n)-1) << I2C_TIMINGR_SCLL_SHIFT) /* tSCLL = n x tPRESC */
#define I2C_TIMINGR_SCLH_SHIFT (0) /* Bits 8-15: SCL high period (master) */
#define I2C_TIMINGR_SCLH_SHIFT (8) /* Bits 8-15: SCL high period (master) */
#define I2C_TIMINGR_SCLH_MASK (0xff << I2C_TIMINGR_SCLH_SHIFT) #define I2C_TIMINGR_SCLH_MASK (0xff << I2C_TIMINGR_SCLH_SHIFT)
# define I2C_TIMINGR_SCLH(n) (((n)-1) << I2C_TIMINGR_SCLH_SHIFT) /* tSCLH = n x tPRESC */ # define I2C_TIMINGR_SCLH(n) (((n)-1) << I2C_TIMINGR_SCLH_SHIFT) /* tSCLH = n x tPRESC */
#define I2C_TIMINGR_SDADEL_SHIFT (0) /* Bits 16-19: Data hold time */
#define I2C_TIMINGR_SDADEL_SHIFT (16) /* Bits 16-19: Data hold time */
#define I2C_TIMINGR_SDADEL_MASK (15 << I2C_TIMINGR_SDADEL_SHIFT) #define I2C_TIMINGR_SDADEL_MASK (15 << I2C_TIMINGR_SDADEL_SHIFT)
# define I2C_TIMINGR_SDADEL(n) ((n) << I2C_TIMINGR_SDADEL_SHIFT) /* tSDADEL= n x tPRESC */ # define I2C_TIMINGR_SDADEL(n) ((n) << I2C_TIMINGR_SDADEL_SHIFT) /* tSDADEL= n x tPRESC */
#define I2C_TIMINGR_SCLDEL_SHIFT (0) /* Bits 20-23: Data setup time */
#define I2C_TIMINGR_SCLDEL_SHIFT (20) /* Bits 20-23: Data setup time */
#define I2C_TIMINGR_SCLDEL_MASK (15 << I2C_TIMINGR_SCLDEL_SHIFT) #define I2C_TIMINGR_SCLDEL_MASK (15 << I2C_TIMINGR_SCLDEL_SHIFT)
# define I2C_TIMINGR_SCLDEL(n) (((n)-1) << I2C_TIMINGR_SCLDEL_SHIFT) /* tSCLDEL = n x tPRESC */ # define I2C_TIMINGR_SCLDEL(n) (((n)-1) << I2C_TIMINGR_SCLDEL_SHIFT) /* tSCLDEL = n x tPRESC */
#define I2C_TIMINGR_PRESC_SHIFT (0) /* Bits 28-31: Timing prescaler */
#define I2C_TIMINGR_PRESC_SHIFT (28) /* Bits 28-31: Timing prescaler */
#define I2C_TIMINGR_PRESC_MASK (15 << I2C_TIMINGR_PRESC_SHIFT) #define I2C_TIMINGR_PRESC_MASK (15 << I2C_TIMINGR_PRESC_SHIFT)
# define I2C_TIMINGR_PRESC(n) (((n)-1) << I2C_TIMINGR_PRESC_SHIFT) /* tPRESC = n x tI2CCLK */ # define I2C_TIMINGR_PRESC(n) (((n)-1) << I2C_TIMINGR_PRESC_SHIFT) /* tPRESC = n x tI2CCLK */
@ -224,6 +229,11 @@
#define I2C_ISR_ADDCODE_SHIFT (17) /* Bits 17-23: Address match code (slave) */ #define I2C_ISR_ADDCODE_SHIFT (17) /* Bits 17-23: Address match code (slave) */
#define I2C_ISR_ADDCODE_MASK (0x7f << I2C_ISR_ADDCODE_SHIFT) #define I2C_ISR_ADDCODE_MASK (0x7f << I2C_ISR_ADDCODE_SHIFT)
#define I2C_ISR_ERRORMASK (I2C_INT_BERR | I2C_INT_ARLO | I2C_INT_OVR | I2C_INT_PECERR | I2C_INT_TIMEOUT)
#define I2C_ICR_CLEARMASK (I2C_INT_ADDR | I2C_INT_NACK | I2C_INT_STOP | I2C_INT_BERR | I2C_INT_ARLO \
| I2C_INT_OVR | I2C_INT_PECERR | I2C_INT_TIMEOUT | I2C_INT_ALERT)
/* Packet error checking register */ /* Packet error checking register */
#define I2C_PECR_MASK (0xff) #define I2C_PECR_MASK (0xff)

View File

@ -43,20 +43,20 @@
* - Master operation, 100 kHz (standard) and 400 kHz (full speed) * - Master operation, 100 kHz (standard) and 400 kHz (full speed)
* - Multiple instances (shared bus) * - Multiple instances (shared bus)
* - Interrupt based operation * - Interrupt based operation
* *
* Structure naming: * Structure naming:
* - Device: structure as defined by the nuttx/i2c/i2c.h * - Device: structure as defined by the nuttx/i2c/i2c.h
* - Instance: represents each individual access to the I2C driver, obtained by * - Instance: represents each individual access to the I2C driver, obtained by
* the i2c_init(); it extends the Device structure from the nuttx/i2c/i2c.h; * the i2c_init(); it extends the Device structure from the nuttx/i2c/i2c.h;
* Instance points to OPS, to common I2C Hardware private data and contains * Instance points to OPS, to common I2C Hardware private data and contains
* its own private data, as frequency, address, mode of operation (in the future) * its own private data, as frequency, address, mode of operation (in the future)
* - Private: Private data of an I2C Hardware * - Private: Private data of an I2C Hardware
* *
* TODO * TODO
* - Check for all possible deadlocks (as BUSY='1' I2C needs to be reset in HW using the I2C_CR1_SWRST) * - Check for all possible deadlocks (as BUSY='1' I2C needs to be reset in HW using the I2C_CR1_SWRST)
* - SMBus support (hardware layer timings are already supported) and add SMBA gpio pin * - SMBus support (hardware layer timings are already supported) and add SMBA gpio pin
* - Slave support with multiple addresses (on multiple instances): * - Slave support with multiple addresses (on multiple instances):
* - 2 x 7-bit address or * - 2 x 7-bit address or
* - 1 x 10 bit adresses + 1 x 7 bit address (?) * - 1 x 10 bit adresses + 1 x 7 bit address (?)
* - plus the broadcast address (general call) * - plus the broadcast address (general call)
* - Multi-master support * - Multi-master support
@ -96,7 +96,6 @@
/* At least one I2C peripheral must be enabled */ /* At least one I2C peripheral must be enabled */
#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3) #if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3)
/* This implementation is for the STM32 F1, F2, and F4 only */ /* This implementation is for the STM32 F1, F2, and F4 only */
#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F20XX) || \ #if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F20XX) || \
@ -248,7 +247,7 @@ struct stm32_i2c_priv_s
sem_t sem_isr; /* Interrupt wait semaphore */ sem_t sem_isr; /* Interrupt wait semaphore */
#endif #endif
volatile uint8_t intstate; /* Interrupt handshake (see enum stm32_intstate_e) */ volatile uint8_t intstate; /* Interrupt handshake (see enum stm32_intstate_e) */
uint8_t msgc; /* Message count */ uint8_t msgc; /* Message count */
struct i2c_msg_s *msgv; /* Message list */ struct i2c_msg_s *msgv; /* Message list */
uint8_t *ptr; /* Current message buffer */ uint8_t *ptr; /* Current message buffer */
@ -275,7 +274,7 @@ struct stm32_i2c_inst_s
{ {
struct i2c_ops_s *ops; /* Standard I2C operations */ struct i2c_ops_s *ops; /* Standard I2C operations */
struct stm32_i2c_priv_s *priv; /* Common driver private data structure */ struct stm32_i2c_priv_s *priv; /* Common driver private data structure */
uint32_t frequency; /* Frequency used in this instantiation */ uint32_t frequency; /* Frequency used in this instantiation */
int address; /* Address used in this instantiation */ int address; /* Address used in this instantiation */
uint16_t flags; /* Flags used in this instantiation */ uint16_t flags; /* Flags used in this instantiation */
@ -355,7 +354,7 @@ static int stm32_i2c_transfer(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *m
************************************************************************************/ ************************************************************************************/
#ifdef CONFIG_STM32_I2C1 #ifdef CONFIG_STM32_I2C1
static const struct stm32_i2c_config_s stm32_i2c1_config = static const struct stm32_i2c_config_s stm32_i2c1_config =
{ {
.base = STM32_I2C1_BASE, .base = STM32_I2C1_BASE,
.clk_bit = RCC_APB1ENR_I2C1EN, .clk_bit = RCC_APB1ENR_I2C1EN,
@ -379,19 +378,19 @@ struct stm32_i2c_priv_s stm32_i2c1_priv =
.ptr = NULL, .ptr = NULL,
.dcnt = 0, .dcnt = 0,
.flags = 0, .flags = 0,
.status = 0 .status = 0
}; };
#endif #endif
#ifdef CONFIG_STM32_I2C2 #ifdef CONFIG_STM32_I2C2
static const struct stm32_i2c_config_s stm32_i2c2_config = static const struct stm32_i2c_config_s stm32_i2c2_config =
{ {
.base = STM32_I2C2_BASE, .base = STM32_I2C2_BASE,
.clk_bit = RCC_APB1ENR_I2C2EN, .clk_bit = RCC_APB1ENR_I2C2EN,
.reset_bit = RCC_APB1RSTR_I2C2RST, .reset_bit = RCC_APB1RSTR_I2C2RST,
.scl_pin = GPIO_I2C2_SCL, .scl_pin = GPIO_I2C2_SCL,
.sda_pin = GPIO_I2C2_SDA, .sda_pin = GPIO_I2C2_SDA,
#ifndef CONFIG_I2C_POLLED #ifndef CONFIG_I2C_POLLED
.isr = stm32_i2c2_isr, .isr = stm32_i2c2_isr,
.ev_irq = STM32_IRQ_I2C2EV, .ev_irq = STM32_IRQ_I2C2EV,
.er_irq = STM32_IRQ_I2C2ER .er_irq = STM32_IRQ_I2C2ER
@ -413,7 +412,7 @@ struct stm32_i2c_priv_s stm32_i2c2_priv =
#endif #endif
#ifdef CONFIG_STM32_I2C3 #ifdef CONFIG_STM32_I2C3
static const struct stm32_i2c_config_s stm32_i2c3_config = static const struct stm32_i2c_config_s stm32_i2c3_config =
{ {
.base = STM32_I2C3_BASE, .base = STM32_I2C3_BASE,
.clk_bit = RCC_APB1ENR_I2C3EN, .clk_bit = RCC_APB1ENR_I2C3EN,
@ -469,7 +468,7 @@ struct i2c_ops_s stm32_i2c_ops =
* Name: stm32_i2c_getreg * Name: stm32_i2c_getreg
* *
* Description: * Description:
* Get register value by offset * Get a 16-bit register value by offset
* *
************************************************************************************/ ************************************************************************************/
@ -483,7 +482,7 @@ static inline uint16_t stm32_i2c_getreg(FAR struct stm32_i2c_priv_s *priv,
* Name: stm32_i2c_putreg * Name: stm32_i2c_putreg
* *
* Description: * Description:
* Put register value by offset * Put a 16-bit register value by offset
* *
************************************************************************************/ ************************************************************************************/
@ -497,7 +496,7 @@ static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t o
* Name: stm32_i2c_modifyreg * Name: stm32_i2c_modifyreg
* *
* Description: * Description:
* Modify register value by offset * Modify a 16-bit register value by offset
* *
************************************************************************************/ ************************************************************************************/
@ -509,10 +508,10 @@ static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv,
} }
/************************************************************************************ /************************************************************************************
* Name: * Name: stm32_i2c_sem_wait
* *
* Description: * Description:
* * Take the exclusive access, waiting as necessary
* *
************************************************************************************/ ************************************************************************************/
@ -743,7 +742,7 @@ static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv)
if ((sr1 & I2C_SR1_TIMEOUT) != 0) if ((sr1 & I2C_SR1_TIMEOUT) != 0)
{ {
return; return;
} }
/* Calculate the elapsed time */ /* Calculate the elapsed time */
@ -957,13 +956,13 @@ static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, uint32_t frequ
{ {
/* Set the minimum allowed value */ /* Set the minimum allowed value */
speed = 4; speed = 4;
} }
ccr |= speed; ccr |= speed;
/* Set Maximum Rise Time for standard mode */ /* Set Maximum Rise Time for standard mode */
trise = freqmhz + 1; trise = freqmhz + 1;
} }
/* Configure speed in fast mode */ /* Configure speed in fast mode */
@ -994,13 +993,13 @@ static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, uint32_t frequ
{ {
/* Set the minimum allowed value */ /* Set the minimum allowed value */
speed = 1; speed = 1;
} }
ccr |= speed; ccr |= speed;
/* Set Maximum Rise Time for fast mode */ /* Set Maximum Rise Time for fast mode */
trise = (uint16_t)(((freqmhz * 300) / 1000) + 1); trise = (uint16_t)(((freqmhz * 300) / 1000) + 1);
} }
/* Write the new values of the CCR and TRISE registers */ /* Write the new values of the CCR and TRISE registers */
@ -1050,7 +1049,7 @@ static inline void stm32_i2c_clrstart(FAR struct stm32_i2c_priv_s *priv)
* "The [STOP] bit is set and cleared by software, cleared by hardware * "The [STOP] bit is set and cleared by software, cleared by hardware
* when a Stop condition is detected, set by hardware when a timeout * when a Stop condition is detected, set by hardware when a timeout
* error is detected. * error is detected.
* *
* "This [START] bit is set and cleared by software and cleared by hardware * "This [START] bit is set and cleared by software and cleared by hardware
* when start is sent or PE=0." The bit must be cleared by software if the * when start is sent or PE=0." The bit must be cleared by software if the
* START is never sent. * START is never sent.
@ -1165,9 +1164,9 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
/* Check for new trace setup */ /* Check for new trace setup */
stm32_i2c_tracenew(priv, status); stm32_i2c_tracenew(priv, status);
/* Was start bit sent */ /* Was start bit sent */
if ((status & I2C_SR1_SB) != 0) if ((status & I2C_SR1_SB) != 0)
{ {
stm32_i2c_traceevent(priv, I2CEVENT_SENDADDR, priv->msgc); stm32_i2c_traceevent(priv, I2CEVENT_SENDADDR, priv->msgc);
@ -1197,11 +1196,11 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
priv->msgc--; priv->msgc--;
} }
/* In 10-bit addressing mode, was first byte sent */ /* In 10-bit addressing mode, was first byte sent */
else if ((status & I2C_SR1_ADD10) != 0) else if ((status & I2C_SR1_ADD10) != 0)
{ {
/* TODO: Finish 10-bit mode addressing */ /* TODO: Finish 10-bit mode addressing */
} }
/* Was address sent, continue with either sending or reading data */ /* Was address sent, continue with either sending or reading data */
@ -1233,7 +1232,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
else if ((status & I2C_SR1_RXNE) != 0) else if ((status & I2C_SR1_RXNE) != 0)
{ {
/* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */ /* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */
if (priv->dcnt > 0) if (priv->dcnt > 0)
{ {
stm32_i2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt); stm32_i2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt);
@ -1255,7 +1254,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
priv->dcnt--; priv->dcnt--;
if (priv->dcnt == 1) if (priv->dcnt == 1)
{ {
stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0); stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0);
} }
#ifdef CONFIG_I2C_POLLED #ifdef CONFIG_I2C_POLLED
@ -1263,7 +1262,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
#endif #endif
} }
} }
/* Do we have more bytes to send, enable/disable buffer interrupts /* Do we have more bytes to send, enable/disable buffer interrupts
* (these ISRs could be replaced by DMAs) * (these ISRs could be replaced by DMAs)
*/ */
@ -1277,11 +1276,11 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
else if (priv->dcnt == 0) else if (priv->dcnt == 0)
{ {
stm32_i2c_traceevent(priv, I2CEVENT_DISITBUFEN, 0); stm32_i2c_traceevent(priv, I2CEVENT_DISITBUFEN, 0);
stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_ITBUFEN, 0); stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_ITBUFEN, 0);
} }
#endif #endif
/* Was last byte received or sent? Hmmm... the F2 and F4 seems to differ from /* Was last byte received or sent? Hmmm... the F2 and F4 seems to differ from
* the F1 in that BTF is not set after data is received (only RXNE). * the F1 in that BTF is not set after data is received (only RXNE).
*/ */
@ -1298,7 +1297,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
* *
* - continue with repeated start * - continue with repeated start
* - or just continue sending writeable part * - or just continue sending writeable part
* - or we close down by sending the stop bit * - or we close down by sending the stop bit
*/ */
if (priv->msgc > 0) if (priv->msgc > 0)
@ -1350,39 +1349,39 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
priv->msgv = NULL; priv->msgv = NULL;
} }
} }
/* Check for errors, in which case, stop the transfer and return
* Note that in master reception mode AF becomes set on last byte
* since ACK is not returned. We should ignore this error.
*/
if ((status & I2C_SR1_ERRORMASK) != 0)
{
stm32_i2c_traceevent(priv, I2CEVENT_ERROR, 0);
/* Clear interrupt flags */ /* Check for errors, in which case, stop the transfer and return
* Note that in master reception mode AF becomes set on last byte
* since ACK is not returned. We should ignore this error.
*/
stm32_i2c_putreg(priv, STM32_I2C_SR1_OFFSET, 0); if ((status & I2C_ISR_ERRORMASK) != 0)
{
stm32_i2c_traceevent(priv, I2CEVENT_ERROR, 0);
/* Is there a thread waiting for this event (there should be) */ /* Clear interrupt flags */
stm32_i2c_putreg(priv, STM32_I2C_SR1_OFFSET, 0);
/* Is there a thread waiting for this event (there should be) */
#ifndef CONFIG_I2C_POLLED #ifndef CONFIG_I2C_POLLED
if (priv->intstate == INTSTATE_WAITING) if (priv->intstate == INTSTATE_WAITING)
{ {
/* Yes.. inform the thread that the transfer is complete /* Yes.. inform the thread that the transfer is complete
* and wake it up. * and wake it up.
*/ */
sem_post( &priv->sem_isr ); sem_post( &priv->sem_isr );
priv->intstate = INTSTATE_DONE; priv->intstate = INTSTATE_DONE;
} }
#else #else
priv->intstate = INTSTATE_DONE; priv->intstate = INTSTATE_DONE;
#endif #endif
} }
priv->status = status; priv->status = status;
return OK; return OK;
} }
/************************************************************************************ /************************************************************************************
@ -1455,7 +1454,7 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
modifyreg32(STM32_RCC_APB1RSTR, priv->config->reset_bit, 0); modifyreg32(STM32_RCC_APB1RSTR, priv->config->reset_bit, 0);
/* Configure pins */ /* Configure pins */
if (stm32_configgpio(priv->config->scl_pin) < 0) if (stm32_configgpio(priv->config->scl_pin) < 0)
{ {
return ERROR; return ERROR;
@ -1468,7 +1467,7 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
} }
/* Attach ISRs */ /* Attach ISRs */
#ifndef CONFIG_I2C_POLLED #ifndef CONFIG_I2C_POLLED
irq_attach(priv->config->ev_irq, priv->config->isr); irq_attach(priv->config->ev_irq, priv->config->isr);
irq_attach(priv->config->er_irq, priv->config->isr); irq_attach(priv->config->er_irq, priv->config->isr);
@ -1482,9 +1481,9 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, (STM32_PCLK1_FREQUENCY / 1000000)); stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, (STM32_PCLK1_FREQUENCY / 1000000));
stm32_i2c_setclock(priv, 100000); stm32_i2c_setclock(priv, 100000);
/* Enable I2C */ /* Enable I2C */
stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_PE); stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_PE);
return OK; return OK;
} }
@ -1545,7 +1544,7 @@ static uint32_t stm32_i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32_t frequ
((struct stm32_i2c_inst_s *)dev)->frequency = frequency; ((struct stm32_i2c_inst_s *)dev)->frequency = frequency;
#endif #endif
stm32_i2c_sem_post(dev); stm32_i2c_sem_post(dev);
return ((struct stm32_i2c_inst_s *)dev)->frequency; return ((struct stm32_i2c_inst_s *)dev)->frequency;
} }
@ -1564,8 +1563,8 @@ static int stm32_i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
((struct stm32_i2c_inst_s *)dev)->address = addr; ((struct stm32_i2c_inst_s *)dev)->address = addr;
((struct stm32_i2c_inst_s *)dev)->flags = (nbits == 10) ? I2C_M_TEN : 0; ((struct stm32_i2c_inst_s *)dev)->flags = (nbits == 10) ? I2C_M_TEN : 0;
stm32_i2c_sem_post(dev); stm32_i2c_sem_post(dev);
return OK; return OK;
} }
/************************************************************************************ /************************************************************************************
@ -1611,7 +1610,7 @@ static int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *ms
*/ */
stm32_i2c_clrstart(priv); stm32_i2c_clrstart(priv);
/* Old transfers are done */ /* Old transfers are done */
priv->msgv = msgs; priv->msgv = msgs;
@ -1620,7 +1619,7 @@ static int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *ms
/* Reset I2C trace logic */ /* Reset I2C trace logic */
stm32_i2c_tracereset(priv); stm32_i2c_tracereset(priv);
/* Set I2C clock frequency (on change it toggles I2C_CR1_PE !) */ /* Set I2C clock frequency (on change it toggles I2C_CR1_PE !) */
stm32_i2c_setclock(priv, inst->frequency); stm32_i2c_setclock(priv, inst->frequency);
@ -1734,7 +1733,7 @@ static int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *ms
/* Dump the trace result */ /* Dump the trace result */
stm32_i2c_tracedump(priv); stm32_i2c_tracedump(priv);
/* Wait for any STOP in progress. NOTE: If we have to disable the FSMC /* Wait for any STOP in progress. NOTE: If we have to disable the FSMC
* then we cannot do this at the top of the loop, unfortunately. The STOP * then we cannot do this at the top of the loop, unfortunately. The STOP
* will not complete normally if the FSMC is enabled. * will not complete normally if the FSMC is enabled.
@ -1794,7 +1793,7 @@ int stm32_i2c_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
.buffer = buffer, .buffer = buffer,
.length = buflen .length = buflen
}; };
return stm32_i2c_process(dev, &msgv, 1); return stm32_i2c_process(dev, &msgv, 1);
} }
@ -1876,7 +1875,7 @@ FAR struct i2c_dev_s *up_i2cinitialize(int port)
# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation. # warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation.
return NULL; return NULL;
#endif #endif
/* Get I2C private structure */ /* Get I2C private structure */
switch (port) switch (port)
@ -1901,7 +1900,7 @@ FAR struct i2c_dev_s *up_i2cinitialize(int port)
} }
/* Allocate instance */ /* Allocate instance */
if (!(inst = kmalloc( sizeof(struct stm32_i2c_inst_s)))) if (!(inst = kmalloc( sizeof(struct stm32_i2c_inst_s))))
{ {
return NULL; return NULL;
@ -1916,17 +1915,17 @@ FAR struct i2c_dev_s *up_i2cinitialize(int port)
inst->flags = 0; inst->flags = 0;
/* Init private data for the first time, increment refs count, /* Init private data for the first time, increment refs count,
* power-up hardware and configure GPIOs. * power-up hardware and configure GPIOs.
*/ */
irqs = irqsave(); irqs = irqsave();
if ((volatile int)priv->refs++ == 0) if ((volatile int)priv->refs++ == 0)
{ {
stm32_i2c_sem_init( (struct i2c_dev_s *)inst ); stm32_i2c_sem_init( (struct i2c_dev_s *)inst );
stm32_i2c_init( priv ); stm32_i2c_init( priv );
} }
irqrestore(irqs); irqrestore(irqs);
return (struct i2c_dev_s *)inst; return (struct i2c_dev_s *)inst;
} }
@ -1942,12 +1941,12 @@ FAR 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)
{ {
int irqs; int irqs;
ASSERT(dev); ASSERT(dev);
/* Decrement refs and check for underflow */ /* Decrement refs and check for underflow */
if (((struct stm32_i2c_inst_s *)dev)->priv->refs == 0) if (((struct stm32_i2c_inst_s *)dev)->priv->refs == 0)
{ {
return ERROR; return ERROR;
} }
@ -2023,12 +2022,12 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
/* Clock the bus until any slaves currently driving it let it go. */ /* Clock the bus until any slaves currently driving it let it go. */
clock_count = 0; clock_count = 0;
while (!stm32_gpioread(sda_gpio)) while (!stm32_gpioread(sda_gpio))
{ {
/* Give up if we have tried too hard */ /* Give up if we have tried too hard */
if (clock_count++ > 10) if (clock_count++ > 10)
{ {
goto out; goto out;
} }
@ -2039,11 +2038,11 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
stretch_count = 0; stretch_count = 0;
while (!stm32_gpioread(scl_gpio)) while (!stm32_gpioread(scl_gpio))
{ {
/* Give up if we have tried too hard */ /* Give up if we have tried too hard */
if (stretch_count++ > 10) if (stretch_count++ > 10)
{ {
goto out; goto out;
} }
@ -2075,7 +2074,7 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
up_udelay(10); up_udelay(10);
/* Revert the GPIO configuration. */ /* Revert the GPIO configuration. */
stm32_unconfiggpio(sda_gpio); stm32_unconfiggpio(sda_gpio);
stm32_unconfiggpio(scl_gpio); stm32_unconfiggpio(scl_gpio);

File diff suppressed because it is too large Load Diff