diff --git a/boards/limifrog-v1/include/periph_conf.h b/boards/limifrog-v1/include/periph_conf.h index 020caa4abe89..edd475914488 100644 --- a/boards/limifrog-v1/include/periph_conf.h +++ b/boards/limifrog-v1/include/periph_conf.h @@ -131,45 +131,30 @@ static const timer_conf_t timer_config[] = { /** * @name I2C configuration - * @{ + * @{ */ #define I2C_NUMOF (2U) #define I2C_0_EN 1 #define I2C_1_EN 1 + +static const i2c_conf_t i2c_cfg[] = { + /* Device, SCL-, SDA-Pin, AF, Event-, Error-IRQ, Clock enable */ + {I2C1, GPIO_PIN(PORT_B, 8), GPIO_PIN(PORT_B, 9), 4, + I2C1_EV_IRQn, I2C1_ER_IRQn, RCC_APB1ENR_I2C1EN}, + {I2C2, GPIO_PIN(PORT_B, 10), GPIO_PIN(PORT_B, 11), 4, + I2C2_EV_IRQn, I2C2_ER_IRQn, RCC_APB1ENR_I2C2EN}, +}; + #define I2C_IRQ_PRIO 1 #define I2C_APBCLK (36000000U) /* I2C 0 device configuration */ -#define I2C_0_DEV I2C1 -#define I2C_0_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_I2C1EN) -#define I2C_0_CLKDIS() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN)) -#define I2C_0_EVT_IRQ I2C1_EV_IRQn #define I2C_0_EVT_ISR isr_i2c1_ev -#define I2C_0_ERR_IRQ I2C1_ER_IRQn #define I2C_0_ERR_ISR isr_i2c1_er -/* I2C 0 pin configuration */ -#define I2C_0_PORT_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOBEN) -#define I2C_0_PORT GPIOB -#define I2C_0_SCL_PIN 8 -#define I2C_0_SCL_AF 4 -#define I2C_0_SDA_PIN 9 -#define I2C_0_SDA_AF 4 - -/* I2C 1 device configuration */ -#define I2C_1_DEV I2C2 /* ST VL6180X, ST LSM6DS3, ST LIS3MDL, ST SLPS25H */ -#define I2C_1_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_I2C2EN) -#define I2C_1_CLKDIS() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C2EN)) -#define I2C_1_EVT_IRQ I2C2_EV_IRQn + +/* I2C 1 device configuration [ST VL6180X, ST LSM6DS3, ST LIS3MDL, ST SLPS25H]*/ #define I2C_1_EVT_ISR isr_i2c2_ev -#define I2C_1_ERR_IRQ I2C2_ER_IRQn #define I2C_1_ERR_ISR isr_i2c2_er -/* I2C 1 pin configuration */ -#define I2C_1_PORT_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOBEN) -#define I2C_1_PORT GPIOB -#define I2C_1_SCL_PIN 10 -#define I2C_1_SCL_AF 4 -#define I2C_1_SDA_PIN 11 -#define I2C_1_SDA_AF 4 /** @} */ #ifdef __cplusplus diff --git a/boards/nucleo-l1/include/periph_conf.h b/boards/nucleo-l1/include/periph_conf.h index 833a1c95d002..be03bd8059d4 100644 --- a/boards/nucleo-l1/include/periph_conf.h +++ b/boards/nucleo-l1/include/periph_conf.h @@ -236,28 +236,30 @@ static const timer_conf_t timer_config[] = { /** * @name I2C configuration - * @{ + * @{ */ -#define I2C_NUMOF (1U) +#define I2C_NUMOF (2U) #define I2C_0_EN 1 +#define I2C_1_EN 1 + +static const i2c_conf_t i2c_cfg[] = { + /* Device, SCL-, SDA-Pin, AF, Event-, Error-IRQ, Clock enable */ + {I2C1, GPIO_PIN(PORT_B, 8), GPIO_PIN(PORT_B, 9), 4, + I2C1_EV_IRQn, I2C1_ER_IRQn, RCC_APB1ENR_I2C1EN}, + {I2C2, GPIO_PIN(PORT_B, 10), GPIO_PIN(PORT_B, 11), 4, + I2C2_EV_IRQn, I2C2_ER_IRQn, RCC_APB1ENR_I2C2EN}, +}; + #define I2C_IRQ_PRIO 1 #define I2C_APBCLK (36000000U) /* I2C 0 device configuration */ -#define I2C_0_DEV I2C1 -#define I2C_0_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_I2C1EN) -#define I2C_0_CLKDIS() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN)) -#define I2C_0_EVT_IRQ I2C1_EV_IRQn #define I2C_0_EVT_ISR isr_i2c1_ev -#define I2C_0_ERR_IRQ I2C1_ER_IRQn #define I2C_0_ERR_ISR isr_i2c1_er -/* I2C 0 pin configuration */ -#define I2C_0_PORT_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOBEN) -#define I2C_0_PORT GPIOB -#define I2C_0_SCL_PIN 8 -#define I2C_0_SCL_AF 4 -#define I2C_0_SDA_PIN 9 -#define I2C_0_SDA_AF 4 + +/* I2C 1 device configuration */ +#define I2C_1_EVT_ISR isr_i2c2_ev +#define I2C_1_ERR_ISR isr_i2c2_er /** @} */ #ifdef __cplusplus diff --git a/cpu/stm32l1/include/periph_cpu.h b/cpu/stm32l1/include/periph_cpu.h index a20ef4586e41..57bbafc17f85 100644 --- a/cpu/stm32l1/include/periph_cpu.h +++ b/cpu/stm32l1/include/periph_cpu.h @@ -100,7 +100,7 @@ typedef struct { } timer_conf_t; /** - * @brief declare needed generic SPI functions + * @brief declare needed generic SPI functions * @{ */ #define PERIPH_SPI_NEEDS_TRANSFER_BYTES @@ -108,6 +108,19 @@ typedef struct { #define PERIPH_SPI_NEEDS_TRANSFER_REGS /** @} */ +/** + * @brief I2C device configuration + */ +typedef struct { + I2C_TypeDef *dev; /**< Pointer to the used I2C device */ + gpio_t scl_pin; /**< Pin used for SCL */ + gpio_t sda_pin; /**< Pin used for SDA */ + uint8_t af_scl_sda; /**< SCL or SDA AF */ + uint8_t ev_irqn; /**< I2C device Event Interrupt */ + uint8_t er_irqn; /**< I2C device Error Interrupt */ + uint32_t clk_en; /**< Clock enable register */ +} i2c_conf_t; + #ifdef __cplusplus } #endif diff --git a/cpu/stm32l1/periph/i2c.c b/cpu/stm32l1/periph/i2c.c index a3afd4e0c15c..0d790b9ee838 100644 --- a/cpu/stm32l1/periph/i2c.c +++ b/cpu/stm32l1/periph/i2c.c @@ -34,13 +34,10 @@ #define ENABLE_DEBUG (0) #include "debug.h" -/* guard file in case no I2C device is defined */ -#if I2C_NUMOF - /* static function definitions */ static void _i2c_init(I2C_TypeDef *i2c, int ccr); static void _toggle_pins(GPIO_TypeDef *port, int pin_scl, int pin_sda); -static void _pin_config(GPIO_TypeDef *port, int pin_scl, int pin_sda); +static void _pin_config(i2c_t dev, GPIO_TypeDef *port, int pin_scl, int pin_sda); static void _start(I2C_TypeDef *dev, uint8_t address, uint8_t rw_flag); static inline void _clear_addr(I2C_TypeDef *dev); static inline void _write(I2C_TypeDef *dev, char *data, int length); @@ -57,18 +54,16 @@ static mutex_t locks[] = { [I2C_1] = MUTEX_INIT, #endif #if I2C_2_EN - [I2C_2] = MUTEX_INIT + [I2C_2] = MUTEX_INIT, #endif #if I2C_3_EN - [I2C_3] = MUTEX_INIT + [I2C_3] = MUTEX_INIT, #endif }; int i2c_init_master(i2c_t dev, i2c_speed_t speed) { - I2C_TypeDef *i2c; - GPIO_TypeDef *port; - int pin_scl = 0, pin_sda = 0; + I2C_TypeDef *i2c = i2c_cfg[dev].dev; int ccr; /* read speed configuration */ @@ -85,27 +80,16 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed) return -2; } - /* read static device configuration */ - switch (dev) { -#if I2C_0_EN - case I2C_0: - i2c = I2C_0_DEV; - port = I2C_0_PORT; - pin_scl = I2C_0_SCL_PIN; - pin_sda = I2C_0_SDA_PIN; - I2C_0_CLKEN(); - I2C_0_PORT_CLKEN(); - NVIC_SetPriority(I2C_0_ERR_IRQ, I2C_IRQ_PRIO); - NVIC_EnableIRQ(I2C_0_ERR_IRQ); - break; -#endif + i2c_poweron(dev); - default: - return -1; - } + /* I2C port clk enable */ + RCC->AHBENR |= RCC_AHBENR_GPIOBEN; + + NVIC_SetPriority(i2c_cfg[dev].er_irqn, I2C_IRQ_PRIO); + NVIC_EnableIRQ(i2c_cfg[dev].er_irqn); /* configure pins */ - _pin_config(port, pin_scl, pin_sda); + _pin_config(dev, GPIOB, i2c_cfg[dev].scl_pin, i2c_cfg[dev].sda_pin); /* configure device */ _i2c_init(i2c, ccr); @@ -116,9 +100,9 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed) /* disable peripheral */ i2c->CR1 &= ~I2C_CR1_PE; /* toggle both pins to reset analog filter */ - _toggle_pins(port, pin_scl, pin_sda); + _toggle_pins(GPIOB, i2c_cfg[dev].scl_pin, i2c_cfg[dev].sda_pin); /* reset pins for alternate function */ - _pin_config(port, pin_scl, pin_sda); + _pin_config(dev, GPIOB, i2c_cfg[dev].scl_pin, i2c_cfg[dev].sda_pin); /* make peripheral soft reset */ i2c->CR1 |= I2C_CR1_SWRST; i2c->CR1 &= ~I2C_CR1_SWRST; @@ -142,7 +126,7 @@ static void _i2c_init(I2C_TypeDef *i2c, int ccr) i2c->CR1 |= I2C_CR1_PE; } -static void _pin_config(GPIO_TypeDef *port, int pin_scl, int pin_sda) +static void _pin_config(i2c_t dev, GPIO_TypeDef *port, int pin_scl, int pin_sda) { /* Set GPIOs to AF mode */ port->MODER &= ~(3 << (2 * pin_scl)); @@ -167,20 +151,20 @@ static void _pin_config(GPIO_TypeDef *port, int pin_scl, int pin_sda) /* Configure GPIOs to for the I2C alternate function */ if (pin_scl < 8) { port->AFR[0] &= ~(0xf << (4 * pin_scl)); - port->AFR[0] |= (I2C_0_SCL_AF << (4 * pin_scl)); + port->AFR[0] |= (i2c_cfg[dev].af_scl_sda << (4 * pin_scl)); } else { port->AFR[1] &= ~(0xf << (4 * (pin_scl - 8))); - port->AFR[1] |= (I2C_0_SCL_AF << (4 * (pin_scl - 8))); + port->AFR[1] |= (i2c_cfg[dev].af_scl_sda << (4 * (pin_scl - 8))); } if (pin_sda < 8) { port->AFR[0] &= ~(0xf << (4 * pin_sda)); - port->AFR[0] |= (I2C_0_SDA_AF << (4 * pin_sda)); + port->AFR[0] |= (i2c_cfg[dev].af_scl_sda << (4 * pin_sda)); } else { port->AFR[1] &= ~(0xf << (4 * (pin_sda - 8))); - port->AFR[1] |= (I2C_0_SDA_AF << (4 * (pin_sda - 8))); + port->AFR[1] |= (i2c_cfg[dev].af_scl_sda << (4 * (pin_sda - 8))); } } @@ -215,18 +199,12 @@ static void _toggle_pins(GPIO_TypeDef *port, int pin_scl, int pin_sda) int i2c_acquire(i2c_t dev) { - if (dev >= I2C_NUMOF) { - return -1; - } mutex_lock(&locks[dev]); return 0; } int i2c_release(i2c_t dev) { - if (dev >= I2C_NUMOF) { - return -1; - } mutex_unlock(&locks[dev]); return 0; } @@ -240,18 +218,7 @@ int i2c_read_bytes(i2c_t dev, uint8_t address, char *data, int length) { unsigned int state; int i = 0; - I2C_TypeDef *i2c; - - switch (dev) { -#if I2C_0_EN - case I2C_0: - i2c = I2C_0_DEV; - break; -#endif - - default: - return -1; - } + I2C_TypeDef *i2c = i2c_cfg[dev].dev; switch (length) { case 1: @@ -369,18 +336,7 @@ int i2c_read_reg(i2c_t dev, uint8_t address, uint8_t reg, char *data) int i2c_read_regs(i2c_t dev, uint8_t address, uint8_t reg, char *data, int length) { - I2C_TypeDef *i2c; - - switch (dev) { -#if I2C_0_EN - case I2C_0: - i2c = I2C_0_DEV; - break; -#endif - - default: - return -1; - } + I2C_TypeDef *i2c = i2c_cfg[dev].dev; /* send start condition and slave address */ DEBUG("Send slave address and clear ADDR flag\n"); @@ -400,23 +356,7 @@ int i2c_write_byte(i2c_t dev, uint8_t address, char data) int i2c_write_bytes(i2c_t dev, uint8_t address, char *data, int length) { - I2C_TypeDef *i2c; - - switch (dev) { -#if I2C_0_EN - case I2C_0: - i2c = I2C_0_DEV; - break; -#endif -#if I2C_1_EN - case I2C_1: - i2c = I2C_1_DEV; - break; -#endif - - default: - return -1; - } + I2C_TypeDef *i2c = i2c_cfg[dev].dev; /* start transmission and send slave address */ DEBUG("sending start sequence\n"); @@ -438,18 +378,7 @@ int i2c_write_reg(i2c_t dev, uint8_t address, uint8_t reg, char data) int i2c_write_regs(i2c_t dev, uint8_t address, uint8_t reg, char *data, int length) { - I2C_TypeDef *i2c; - - switch (dev) { -#if I2C_0_EN - case I2C_0: - i2c = I2C_0_DEV; - break; -#endif - - default: - return -1; - } + I2C_TypeDef *i2c = i2c_cfg[dev].dev; /* start transmission and send slave address */ _start(i2c, address, I2C_FLAG_WRITE); @@ -466,36 +395,13 @@ int i2c_write_regs(i2c_t dev, uint8_t address, uint8_t reg, char *data, int leng void i2c_poweron(i2c_t dev) { - switch (dev) { -#if I2C_0_EN - case I2C_0: - I2C_0_CLKEN(); - break; -#endif -#if I2C_1_EN - case I2C_1: - I2C_1_CLKEN(); - break; -#endif - } + RCC->APB1ENR |= i2c_cfg[dev].clk_en; } void i2c_poweroff(i2c_t dev) { - switch (dev) { -#if I2C_0_EN - case I2C_0: - while (I2C_0_DEV->SR2 & I2C_SR2_BUSY); - I2C_0_CLKDIS(); - break; -#endif -#if I2C_1_EN - case I2C_1: - while (I2C_0_DEV->SR2 & I2C_SR2_BUSY); - I2C_0_CLKDIS(); - break; -#endif - } + while (i2c_cfg[dev].dev->SR2 & I2C_SR2_BUSY); + RCC->APB1ENR &= ~(i2c_cfg[dev].clk_en); } static void _start(I2C_TypeDef *dev, uint8_t address, uint8_t rw_flag) @@ -555,11 +461,10 @@ static inline void _stop(I2C_TypeDef *dev) dev->CR1 |= I2C_CR1_STOP; } -#if I2C_0_EN void I2C_0_ERR_ISR(void) { - unsigned state = I2C_0_DEV->SR1; - DEBUG("\n\n### I2C ERROR OCCURED ###\n"); + unsigned state = I2C1->SR1; + DEBUG("\n\n### I2C_0 ERROR OCCURED ###\n"); DEBUG("status: %08x\n", state); if (state & I2C_SR1_OVR) { DEBUG("OVR\n"); @@ -584,6 +489,32 @@ void I2C_0_ERR_ISR(void) } while (1); } -#endif /* I2C_0_EN */ -#endif /* I2C_NUMOF */ +void I2C_1_ERR_ISR(void) +{ + unsigned state = I2C2->SR1; + DEBUG("\n\n### I2C_1 ERROR OCCURED ###\n"); + DEBUG("status: %08x\n", state); + if (state & I2C_SR1_OVR) { + DEBUG("OVR\n"); + } + if (state & I2C_SR1_AF) { + DEBUG("AF\n"); + } + if (state & I2C_SR1_ARLO) { + DEBUG("ARLO\n"); + } + if (state & I2C_SR1_BERR) { + DEBUG("BERR\n"); + } + if (state & I2C_SR1_PECERR) { + DEBUG("PECERR\n"); + } + if (state & I2C_SR1_TIMEOUT) { + DEBUG("TIMEOUT\n"); + } + if (state & I2C_SR1_SMBALERT) { + DEBUG("SMBALERT\n"); + } + while (1); +}