Merged in ziggurat29/nuttx/stm32l4_i2c_lcd_mjkdz_001 (pull request #30)
get I2C working for STM32L4
This commit is contained in:
commit
0d2698a710
@ -141,12 +141,12 @@ CHIP_CSRCS += stm32l4_exti_pwr.c
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_RTC),y)
|
ifeq ($(CONFIG_RTC),y)
|
||||||
CHIP_CSRCS += stm32l4_rtcc.c
|
|
||||||
ifeq ($(CONFIG_RTC_ALARM),y)
|
ifeq ($(CONFIG_RTC_ALARM),y)
|
||||||
CHIP_CSRCS += stm32l4_exti_alarm.c
|
CHIP_CSRCS += stm32l4_exti_alarm.c
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_RTC_DRIVER),y)
|
ifeq ($(CONFIG_RTC_DRIVER),y)
|
||||||
CHIP_CSRCS += stm32l4_rtc_lowerhalf.c
|
CHIP_CSRCS += stm32l4_rtc_lowerhalf.c
|
||||||
|
CHIP_CSRCS += stm32l4_rtcc.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -1,22 +1,14 @@
|
|||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* arch/arm/src/stm32l4/stm32f3xx_i2c.c
|
* arch/arm/src/stm32l4/stm32l4_i2c.c
|
||||||
* STM32L4 I2C driver - based on STM32F3 I2C Hardware Layer - Device Driver
|
* STM32L4 I2C driver - based on STM32F3 I2C Hardware Layer - Device Driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||||
* Author: Uros Platise <uros.platise@isotel.eu>
|
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||||
*
|
|
||||||
* With extensions and modifications for the F1, F2, and F4 by:
|
|
||||||
*
|
|
||||||
* Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregroy Nutt <gnutt@nuttx.org>
|
* Author: Gregroy Nutt <gnutt@nuttx.org>
|
||||||
*
|
|
||||||
* And this version for the STM32 F3 by
|
|
||||||
*
|
|
||||||
* Author: John Wharington
|
* Author: John Wharington
|
||||||
*
|
|
||||||
* Modified for STM32L4 by
|
|
||||||
*
|
|
||||||
* Author: Sebastien Lorquet
|
* Author: Sebastien Lorquet
|
||||||
|
* Author: dev@ziggurat29.com
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -96,6 +88,7 @@
|
|||||||
|
|
||||||
#include "up_arch.h"
|
#include "up_arch.h"
|
||||||
|
|
||||||
|
#include "stm32l4_gpio.h"
|
||||||
#include "stm32l4_rcc.h"
|
#include "stm32l4_rcc.h"
|
||||||
#include "stm32l4_i2c.h"
|
#include "stm32l4_i2c.h"
|
||||||
#include "stm32l4_waste.h"
|
#include "stm32l4_waste.h"
|
||||||
@ -103,9 +96,6 @@
|
|||||||
/* At least one I2C peripheral must be enabled */
|
/* At least one I2C peripheral must be enabled */
|
||||||
|
|
||||||
#if defined(CONFIG_STM32L4_I2C1) || defined(CONFIG_STM32L4_I2C2) || defined(CONFIG_STM32L4_I2C3)
|
#if defined(CONFIG_STM32L4_I2C1) || defined(CONFIG_STM32L4_I2C2) || defined(CONFIG_STM32L4_I2C3)
|
||||||
/* This implementation is for the STM32 F1, F2, and F4 only */
|
|
||||||
|
|
||||||
#if defined(CONFIG_STM32L4_STM32F30XX)
|
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@ -138,12 +128,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define I2C_OUTPUT \
|
#define I2C_OUTPUT \
|
||||||
(GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_CNF_OUTOD | GPIO_MODE_50MHz)
|
(GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_OPENDRAIN | GPIO_SPEED_50MHz)
|
||||||
#define MKI2C_OUTPUT(p) \
|
#define MKI2C_OUTPUT(p) \
|
||||||
(((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT)
|
(((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT)
|
||||||
|
|
||||||
/* Register setting unique to the STM32F30xx */
|
|
||||||
|
|
||||||
#define I2C_CR1_TXRX \
|
#define I2C_CR1_TXRX \
|
||||||
(I2C_CR1_RXIE | I2C_CR1_TXIE)
|
(I2C_CR1_RXIE | I2C_CR1_TXIE)
|
||||||
#define I2C_CR1_ALLINTS \
|
#define I2C_CR1_ALLINTS \
|
||||||
@ -246,7 +234,7 @@ struct stm32l4_i2c_priv_s
|
|||||||
{
|
{
|
||||||
const struct i2c_ops_s *ops; /* Standard I2C operations */
|
const struct i2c_ops_s *ops; /* Standard I2C operations */
|
||||||
const struct stm32l4_i2c_config_s *config; /* Port configuration */
|
const struct stm32l4_i2c_config_s *config; /* Port configuration */
|
||||||
int refs; /* Referernce count */
|
int refs; /* Reference count */
|
||||||
sem_t sem_excl; /* Mutual exclusion semaphore */
|
sem_t sem_excl; /* Mutual exclusion semaphore */
|
||||||
#ifndef CONFIG_I2C_POLLED
|
#ifndef CONFIG_I2C_POLLED
|
||||||
sem_t sem_isr; /* Interrupt wait semaphore */
|
sem_t sem_isr; /* Interrupt wait semaphore */
|
||||||
@ -279,15 +267,10 @@ struct stm32l4_i2c_priv_s
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
static inline uint16_t stm32l4_i2c_getreg(FAR struct stm32l4_i2c_priv_s *priv,
|
static inline uint32_t stm32l4_i2c_getreg32(FAR struct stm32l4_i2c_priv_s *priv,
|
||||||
uint8_t offset);
|
uint8_t offset);
|
||||||
static inline void stm32l4_i2c_putreg(FAR struct stm32l4_i2c_priv_s *priv, uint8_t offset,
|
|
||||||
uint16_t value);
|
|
||||||
static inline void stm32l4_i2c_putreg32(FAR struct stm32l4_i2c_priv_s *priv, uint8_t offset,
|
static inline void stm32l4_i2c_putreg32(FAR struct stm32l4_i2c_priv_s *priv, uint8_t offset,
|
||||||
uint32_t value);
|
uint32_t value);
|
||||||
static inline void stm32l4_i2c_modifyreg(FAR struct stm32l4_i2c_priv_s *priv,
|
|
||||||
uint8_t offset, uint16_t clearbits,
|
|
||||||
uint16_t setbits);
|
|
||||||
static inline void stm32l4_i2c_modifyreg32(FAR struct stm32l4_i2c_priv_s *priv,
|
static inline void stm32l4_i2c_modifyreg32(FAR struct stm32l4_i2c_priv_s *priv,
|
||||||
uint8_t offset, uint32_t clearbits,
|
uint8_t offset, uint32_t clearbits,
|
||||||
uint32_t setbits);
|
uint32_t setbits);
|
||||||
@ -351,8 +334,8 @@ const struct i2c_ops_s stm32l4_i2c_ops =
|
|||||||
static const struct stm32l4_i2c_config_s stm32l4_i2c1_config =
|
static const struct stm32l4_i2c_config_s stm32l4_i2c1_config =
|
||||||
{
|
{
|
||||||
.base = STM32L4_I2C1_BASE,
|
.base = STM32L4_I2C1_BASE,
|
||||||
.clk_bit = RCC_APB1ENR_I2C1EN,
|
.clk_bit = RCC_APB1ENR1_I2C1EN,
|
||||||
.reset_bit = RCC_APB1RSTR_I2C1RST,
|
.reset_bit = RCC_APB1RSTR1_I2C1RST,
|
||||||
.scl_pin = GPIO_I2C1_SCL,
|
.scl_pin = GPIO_I2C1_SCL,
|
||||||
.sda_pin = GPIO_I2C1_SDA,
|
.sda_pin = GPIO_I2C1_SDA,
|
||||||
#ifndef CONFIG_I2C_POLLED
|
#ifndef CONFIG_I2C_POLLED
|
||||||
@ -441,20 +424,6 @@ struct stm32l4_i2c_priv_s stm32l4_i2c3_priv =
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
/************************************************************************************
|
|
||||||
* Name: stm32l4_i2c_getreg
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Get a 16-bit register value by offset
|
|
||||||
*
|
|
||||||
************************************************************************************/
|
|
||||||
|
|
||||||
static inline uint16_t stm32l4_i2c_getreg(FAR struct stm32l4_i2c_priv_s *priv,
|
|
||||||
uint8_t offset)
|
|
||||||
{
|
|
||||||
return getreg16(priv->config->base + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32l4_i2c_getreg32
|
* Name: stm32l4_i2c_getreg32
|
||||||
*
|
*
|
||||||
@ -469,20 +438,6 @@ static inline uint32_t stm32l4_i2c_getreg32(FAR struct stm32l4_i2c_priv_s *priv,
|
|||||||
return getreg32(priv->config->base + offset);
|
return getreg32(priv->config->base + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
|
||||||
* Name: stm32l4_i2c_putreg
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Put a 16-bit register value by offset
|
|
||||||
*
|
|
||||||
************************************************************************************/
|
|
||||||
|
|
||||||
static inline void stm32l4_i2c_putreg(FAR struct stm32l4_i2c_priv_s *priv, uint8_t offset,
|
|
||||||
uint16_t value)
|
|
||||||
{
|
|
||||||
putreg16(value, priv->config->base + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32l4_i2c_putreg32
|
* Name: stm32l4_i2c_putreg32
|
||||||
*
|
*
|
||||||
@ -497,21 +452,6 @@ static inline void stm32l4_i2c_putreg32(FAR struct stm32l4_i2c_priv_s *priv,
|
|||||||
putreg32(value, priv->config->base + offset);
|
putreg32(value, priv->config->base + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
|
||||||
* Name: stm32l4_i2c_modifyreg
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Modify a 16-bit register value by offset
|
|
||||||
*
|
|
||||||
************************************************************************************/
|
|
||||||
|
|
||||||
static inline void stm32l4_i2c_modifyreg(FAR struct stm32l4_i2c_priv_s *priv,
|
|
||||||
uint8_t offset, uint16_t clearbits,
|
|
||||||
uint16_t setbits)
|
|
||||||
{
|
|
||||||
modifyreg16(priv->config->base + offset, clearbits, setbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32l4_i2c_modifyreg32
|
* Name: stm32l4_i2c_modifyreg32
|
||||||
*
|
*
|
||||||
@ -615,7 +555,6 @@ static inline int stm32l4_i2c_sem_waitdone(FAR struct stm32l4_i2c_priv_s *priv)
|
|||||||
{
|
{
|
||||||
struct timespec abstime;
|
struct timespec abstime;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
uint32_t regval;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
@ -866,7 +805,7 @@ static inline void stm32l4_i2c_sem_waitstop(FAR struct stm32l4_i2c_priv_s *priv)
|
|||||||
|
|
||||||
/* Check for timeout error */
|
/* Check for timeout error */
|
||||||
|
|
||||||
sr = stm32l4_i2c_getreg(priv, STM32L4_I2C_ISR_OFFSET);
|
sr = stm32l4_i2c_getreg32(priv, STM32L4_I2C_ISR_OFFSET);
|
||||||
if ((sr & I2C_INT_TIMEOUT) != 0)
|
if ((sr & I2C_INT_TIMEOUT) != 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -1065,6 +1004,23 @@ static void stm32l4_i2c_setclock(FAR struct stm32l4_i2c_priv_s *priv, uint32_t f
|
|||||||
uint8_t scl_h_period;
|
uint8_t scl_h_period;
|
||||||
uint8_t scl_l_period;
|
uint8_t scl_l_period;
|
||||||
|
|
||||||
|
/* XXX haque; these are the only freqs we support at the moment, until we can compute the values ourself */
|
||||||
|
|
||||||
|
if (frequency == 10000)
|
||||||
|
{}
|
||||||
|
else if (frequency == 100000)
|
||||||
|
{}
|
||||||
|
else if (frequency == 400000)
|
||||||
|
{}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
frequency = 1000000;
|
||||||
|
#else
|
||||||
|
frequency = 500000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Has the I2C bus frequency changed? */
|
/* Has the I2C bus frequency changed? */
|
||||||
|
|
||||||
if (frequency != priv->frequency)
|
if (frequency != priv->frequency)
|
||||||
@ -1079,40 +1035,100 @@ static void stm32l4_i2c_setclock(FAR struct stm32l4_i2c_priv_s *priv, uint32_t f
|
|||||||
|
|
||||||
/* Update timing and control registers */
|
/* Update timing and control registers */
|
||||||
|
|
||||||
/* TODO: speed/timing calcs */
|
/* TODO: speed/timing calcs, taking into consideration
|
||||||
#warning "check set filters before timing, see RM0316"
|
* STM32L4_PCLK1_FREQUENCY, or SYSCLK, or HSI16
|
||||||
|
* clock source, RCC_CCIPR, I2CxSEL, 0 = PCKL, 1 = SCLK, 2 = HSI16, 3 = reserved
|
||||||
/* values from 100khz at 8mhz i2c clock */
|
#warning "check set filters before timing, see RM0351 35.4.4 p 1112"
|
||||||
|
* analog filter; suppress spikes up to 50 ns in fast-mode and fast-mode plus
|
||||||
/* prescaler */
|
* ANFOFF cr1
|
||||||
/* t_presc= (presc+1)*t_i2cclk */
|
* DNF cr1; 1-15 I2CCLK periods
|
||||||
/* RM0316 */
|
*/
|
||||||
|
/* RM0351 35.4.9 p 1140 */
|
||||||
|
|
||||||
if (frequency == 10000)
|
if (frequency == 10000)
|
||||||
{
|
{
|
||||||
presc = 0x01;
|
#if 1
|
||||||
scl_l_period = 0xc7;
|
/* 10 KHz values from I2C timing tool with clock 80mhz */
|
||||||
scl_h_period = 0xc3;
|
|
||||||
h_time = 0x02;
|
presc = 0x0b; /* PRESC - (+1) prescale I2CCLK */
|
||||||
s_time = 0x04;
|
scl_l_period = 0xff; /* SCLL - SCL low period in master mode */
|
||||||
|
scl_h_period = 0xba; /* SCLH - SCL high period in master mode */
|
||||||
|
h_time = 0x00; /* SDADEL - (+1) data hold time after SCL falling edge */
|
||||||
|
s_time = 0x01; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* 10 KHz values from datasheet with clock 8mhz */
|
||||||
|
|
||||||
|
presc = 0x03; /* PRESC - (+1) prescale I2CCLK */
|
||||||
|
scl_l_period = 0xc7; /* SCLL - SCL low period in master mode */
|
||||||
|
scl_h_period = 0xc3; /* SCLH - SCL high period in master mode */
|
||||||
|
h_time = 0x02; /* SDADEL - (+1) data hold time after SCL falling edge */
|
||||||
|
s_time = 0x04; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (frequency == 100000)
|
else if (frequency == 100000)
|
||||||
{
|
{
|
||||||
/* values from datasheet with clock 8mhz */
|
#if 1
|
||||||
|
/* 100 KHz values from I2C timing tool with clock 80mhz */
|
||||||
|
|
||||||
|
presc = 0x01; /* PRESC - (+1) prescale I2CCLK */
|
||||||
|
scl_l_period = 0xe7; /* SCLL - SCL low period in master mode */
|
||||||
|
scl_h_period = 0x9b; /* SCLH - SCL high period in master mode */
|
||||||
|
h_time = 0x00; /* SDADEL - (+1) data hold time after SCL falling edge */
|
||||||
|
s_time = 0x0d; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */
|
||||||
|
#else
|
||||||
|
/* 100 KHz values from datasheet with clock 8mhz */
|
||||||
|
|
||||||
presc = 0x01;
|
presc = 0x01;
|
||||||
scl_l_period = 0x13;
|
scl_l_period = 0x13;
|
||||||
scl_h_period = 0x0f;
|
scl_h_period = 0x0f;
|
||||||
h_time = 0x02;
|
h_time = 0x02;
|
||||||
s_time = 0x04;
|
s_time = 0x04;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else if (frequency == 400000)
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
/* 400 KHz values from I2C timing tool for clock of 80mhz */
|
||||||
|
|
||||||
|
presc = 0x01; /* PRESC - (+1) prescale I2CCLK */
|
||||||
|
scl_l_period = 0x43; /* SCLL - SCL low period in master mode */
|
||||||
|
scl_h_period = 0x13; /* SCLH - SCL high period in master mode */
|
||||||
|
h_time = 0x00; /* SDADEL - (+1) data hold time after SCL falling edge */
|
||||||
|
s_time = 0x07; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */
|
||||||
|
#else
|
||||||
|
/* 400 KHz values from datasheet for clock of 8mhz */
|
||||||
|
|
||||||
presc = 0x00;
|
presc = 0x00;
|
||||||
scl_l_period = 0x09;
|
scl_l_period = 0x09;
|
||||||
scl_h_period = 0x03;
|
scl_h_period = 0x03;
|
||||||
h_time = 0x01;
|
h_time = 0x01;
|
||||||
s_time = 0x03;
|
s_time = 0x03;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
/* 1000 KHhz values from I2C timing tool for clock of 80mhz */
|
||||||
|
|
||||||
|
presc = 0x01; /* PRESC - (+1) prescale I2CCLK */
|
||||||
|
scl_l_period = 0x14; /* SCLL - SCL low period in master mode */
|
||||||
|
scl_h_period = 0x13; /* SCLH - SCL high period in master mode */
|
||||||
|
h_time = 0x00; /* SDADEL - (+1) data hold time after SCL falling edge */
|
||||||
|
s_time = 0x05; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */
|
||||||
|
|
||||||
|
frequency = 1000000;
|
||||||
|
#else
|
||||||
|
/* 500 KHhz values from datasheet for clock of 8mhz */
|
||||||
|
|
||||||
|
presc = 0x00;
|
||||||
|
scl_l_period = 0x06;
|
||||||
|
scl_h_period = 0x03;
|
||||||
|
h_time = 0x00;
|
||||||
|
s_time = 0x01;
|
||||||
|
|
||||||
|
frequency = 500000;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t timingr =
|
uint32_t timingr =
|
||||||
@ -1124,10 +1140,6 @@ static void stm32l4_i2c_setclock(FAR struct stm32l4_i2c_priv_s *priv, uint32_t f
|
|||||||
|
|
||||||
stm32l4_i2c_putreg32(priv, STM32L4_I2C_TIMINGR_OFFSET, timingr);
|
stm32l4_i2c_putreg32(priv, STM32L4_I2C_TIMINGR_OFFSET, timingr);
|
||||||
|
|
||||||
/* Bit 14 of OAR1 must be configured and kept at 1 */
|
|
||||||
|
|
||||||
stm32l4_i2c_putreg(priv, STM32L4_I2C_OAR1_OFFSET, I2C_OAR1_ONE);
|
|
||||||
|
|
||||||
/* Re-enable the peripheral (or not) */
|
/* Re-enable the peripheral (or not) */
|
||||||
|
|
||||||
if (pe)
|
if (pe)
|
||||||
@ -1318,7 +1330,7 @@ static int stm32l4_i2c_isr(struct stm32l4_i2c_priv_s *priv)
|
|||||||
/* Send a byte */
|
/* Send a byte */
|
||||||
|
|
||||||
stm32l4_i2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->dcnt);
|
stm32l4_i2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->dcnt);
|
||||||
stm32l4_i2c_putreg(priv, STM32L4_I2C_TXDR_OFFSET, *priv->ptr++);
|
stm32l4_i2c_putreg32(priv, STM32L4_I2C_TXDR_OFFSET, *priv->ptr++);
|
||||||
priv->dcnt--;
|
priv->dcnt--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1354,7 +1366,7 @@ static int stm32l4_i2c_isr(struct stm32l4_i2c_priv_s *priv)
|
|||||||
#endif
|
#endif
|
||||||
/* Receive a byte */
|
/* Receive a byte */
|
||||||
|
|
||||||
*priv->ptr++ = stm32l4_i2c_getreg(priv, STM32L4_I2C_RXDR_OFFSET);
|
*priv->ptr++ = (uint8_t) stm32l4_i2c_getreg32(priv, STM32L4_I2C_RXDR_OFFSET);
|
||||||
|
|
||||||
/* Disable acknowledge when last byte is to be received */
|
/* Disable acknowledge when last byte is to be received */
|
||||||
|
|
||||||
@ -1554,9 +1566,9 @@ static int stm32l4_i2c_init(FAR struct stm32l4_i2c_priv_s *priv)
|
|||||||
|
|
||||||
/* Enable power and reset the peripheral */
|
/* Enable power and reset the peripheral */
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_APB1ENR, 0, priv->config->clk_bit);
|
modifyreg32(STM32L4_RCC_APB1ENR1, 0, priv->config->clk_bit);
|
||||||
modifyreg32(STM32L4_RCC_APB1RSTR, 0, priv->config->reset_bit);
|
modifyreg32(STM32L4_RCC_APB1RSTR1, 0, priv->config->reset_bit);
|
||||||
modifyreg32(STM32L4_RCC_APB1RSTR, priv->config->reset_bit, 0);
|
modifyreg32(STM32L4_RCC_APB1RSTR1, priv->config->reset_bit, 0);
|
||||||
|
|
||||||
/* Configure pins */
|
/* Configure pins */
|
||||||
|
|
||||||
@ -1588,8 +1600,8 @@ static int stm32l4_i2c_init(FAR struct stm32l4_i2c_priv_s *priv)
|
|||||||
|
|
||||||
priv->frequency = 0;
|
priv->frequency = 0;
|
||||||
|
|
||||||
/* TODO: f303 i2c clock source RCC_CFGR3 */
|
/* TODO: i2c clock source RCC_CCIPR */
|
||||||
/* RCC_CFGR3_I2C1SW (default is HSI clock) */
|
/* RCC_CCIPR I2CxSEL (default is PCLK clock) */
|
||||||
|
|
||||||
stm32l4_i2c_setclock(priv, 100000);
|
stm32l4_i2c_setclock(priv, 100000);
|
||||||
|
|
||||||
@ -1629,7 +1641,7 @@ static int stm32l4_i2c_deinit(FAR struct stm32l4_i2c_priv_s *priv)
|
|||||||
|
|
||||||
/* Disable clocking */
|
/* Disable clocking */
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_APB1ENR, priv->config->clk_bit, 0);
|
modifyreg32(STM32L4_RCC_APB1ENR1, priv->config->clk_bit, 0);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1713,8 +1725,8 @@ static int stm32l4_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg
|
|||||||
status = stm32l4_i2c_getstatus(priv);
|
status = stm32l4_i2c_getstatus(priv);
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
|
|
||||||
i2cdbg("Timed out: CR1: %04x status: %08x\n",
|
i2cdbg("Timed out: CR1: %08x status: %08x\n",
|
||||||
stm32l4_i2c_getreg(priv, STM32L4_I2C_CR1_OFFSET), status);
|
stm32l4_i2c_getreg32(priv, STM32L4_I2C_CR1_OFFSET), status);
|
||||||
|
|
||||||
/* "Note: When the STOP, START or PEC bit is set, the software must
|
/* "Note: When the STOP, START or PEC bit is set, the software must
|
||||||
* not perform any write access to I2C_CR1 before this bit is
|
* not perform any write access to I2C_CR1 before this bit is
|
||||||
@ -1836,6 +1848,7 @@ static int stm32l4_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg
|
|||||||
#ifdef CONFIG_I2C_RESET
|
#ifdef CONFIG_I2C_RESET
|
||||||
static int stm32l4_i2c_reset(FAR struct i2c_master_s * dev)
|
static int stm32l4_i2c_reset(FAR struct i2c_master_s * dev)
|
||||||
{
|
{
|
||||||
|
FAR struct stm32l4_i2c_priv_s *priv = (struct stm32l4_i2c_priv_s *)dev;
|
||||||
unsigned int clock_count;
|
unsigned int clock_count;
|
||||||
unsigned int stretch_count;
|
unsigned int stretch_count;
|
||||||
uint32_t scl_gpio;
|
uint32_t scl_gpio;
|
||||||
@ -1962,7 +1975,7 @@ out:
|
|||||||
FAR struct i2c_master_s *stm32l4_i2cbus_initialize(int port)
|
FAR struct i2c_master_s *stm32l4_i2cbus_initialize(int port)
|
||||||
{
|
{
|
||||||
struct stm32l4_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */
|
struct stm32l4_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */
|
||||||
irqtate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
#if STM32L4_PCLK1_FREQUENCY < 4000000
|
#if STM32L4_PCLK1_FREQUENCY < 4000000
|
||||||
# warning STM32L4_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation.
|
# warning STM32L4_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation.
|
||||||
@ -2054,6 +2067,5 @@ int stm32l4_i2cbus_uninitialize(FAR struct i2c_master_s * dev)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_STM32L4_STM32F30XX */
|
|
||||||
#endif /* CONFIG_STM32L4_I2C1 || CONFIG_STM32L4_I2C2 || CONFIG_STM32L4_I2C3 */
|
#endif /* CONFIG_STM32L4_I2C1 || CONFIG_STM32L4_I2C2 || CONFIG_STM32L4_I2C3 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user