diff --git a/arch/arm/src/stm32l4/hardware/stm32l4x3xx_rcc.h b/arch/arm/src/stm32l4/hardware/stm32l4x3xx_rcc.h index fb6570e116c..ab5b4d181b1 100644 --- a/arch/arm/src/stm32l4/hardware/stm32l4x3xx_rcc.h +++ b/arch/arm/src/stm32l4/hardware/stm32l4x3xx_rcc.h @@ -84,6 +84,7 @@ #define STM32L4_RCC_BDCR_OFFSET 0x0090 /* Backup domain control register */ #define STM32L4_RCC_CSR_OFFSET 0x0094 /* Control/status register */ #define STM32L4_RCC_CRRCR_OFFSET 0x0098 /* Clock recovery RC register */ +#define STM32L4_RCC_CCIPR2_OFFSET 0x009c /* Peripherals independent clock configuration register 2 */ /* Register Addresses *******************************************************************************/ @@ -118,6 +119,7 @@ #define STM32L4_RCC_BDCR (STM32L4_RCC_BASE+STM32L4_RCC_BDCR_OFFSET) #define STM32L4_RCC_CSR (STM32L4_RCC_BASE+STM32L4_RCC_CSR_OFFSET) #define STM32L4_RCC_CRRCR (STM32L4_RCC_BASE+STM32L4_RCC_CRRCR_OFFSET) +#define STM32L4_RCC_CCIPR2 (STM32L4_RCC_BASE+STM32L4_RCC_CCIPR2_OFFSET) /* Register Bitfield Definitions ********************************************************************/ @@ -217,24 +219,24 @@ # define RCC_CFGR_STOPWUCK_MSI (0 << 15) /* 0: MSI */ # define RCC_CFGR_STOPWUCK_HSI (1 << 15) /* 0: HSI */ -#define RCC_CFGR_MCO_SHIFT (24) /* Bits 24-26: Microcontroller Clock Output */ -#define RCC_CFGR_MCO_MASK (7 << RCC_CFGR_MCO_SHIFT) -# define RCC_CFGR_MCO_NONE (0 << RCC_CFGR_MCO_SHIFT) /* 000: Disabled */ -# define RCC_CFGR_MCO_SYSCLK (1 << RCC_CFGR_MCO_SHIFT) /* 001: SYSCLK system clock selected */ -# define RCC_CFGR_MCO_MSI (2 << RCC_CFGR_MCO_SHIFT) /* 010: MSI clock selected */ -# define RCC_CFGR_MCO_HSI (3 << RCC_CFGR_MCO_SHIFT) /* 011: HSI clock selected */ -# define RCC_CFGR_MCO_HSE (4 << RCC_CFGR_MCO_SHIFT) /* 100: HSE clock selected */ -# define RCC_CFGR_MCO_PLL (5 << RCC_CFGR_MCO_SHIFT) /* 101: Main PLL selected */ -# define RCC_CFGR_MCO_LSI (6 << RCC_CFGR_MCO_SHIFT) /* 110: LSI clock selected */ -# define RCC_CFGR_MCO_LSE (7 << RCC_CFGR_MCO_SHIFT) /* 111: LSE clock selected */ +#define RCC_CFGR_MCO_SHIFT (24) /* Bits 24-26: Microcontroller Clock Output */ +#define RCC_CFGR_MCO_MASK (7 << RCC_CFGR_MCO_SHIFT) +# define RCC_CFGR_MCO_NONE (0 << RCC_CFGR_MCO_SHIFT) /* 000: Disabled */ +# define RCC_CFGR_MCO_SYSCLK (1 << RCC_CFGR_MCO_SHIFT) /* 001: SYSCLK system clock selected */ +# define RCC_CFGR_MCO_MSI (2 << RCC_CFGR_MCO_SHIFT) /* 010: MSI clock selected */ +# define RCC_CFGR_MCO_HSI (3 << RCC_CFGR_MCO_SHIFT) /* 011: HSI clock selected */ +# define RCC_CFGR_MCO_HSE (4 << RCC_CFGR_MCO_SHIFT) /* 100: HSE clock selected */ +# define RCC_CFGR_MCO_PLL (5 << RCC_CFGR_MCO_SHIFT) /* 101: Main PLL selected */ +# define RCC_CFGR_MCO_LSI (6 << RCC_CFGR_MCO_SHIFT) /* 110: LSI clock selected */ +# define RCC_CFGR_MCO_LSE (7 << RCC_CFGR_MCO_SHIFT) /* 111: LSE clock selected */ -#define RCC_CFGR_MCOPRE_SHIFT (28) /* Bits 28-30: MCO prescaler */ -#define RCC_CFGR_MCOPRE_MASK (7 << RCC_CFGR_MCOPRE_SHIFT) -# define RCC_CFGR_MCOPRE_NONE (0 << RCC_CFGR_MCOPRE_SHIFT) /* 000: no division */ -# define RCC_CFGR_MCOPRE_DIV2 (1 << RCC_CFGR_MCOPRE_SHIFT) /* 001: division by 2 */ -# define RCC_CFGR_MCOPRE_DIV4 (2 << RCC_CFGR_MCOPRE_SHIFT) /* 010: division by 4 */ -# define RCC_CFGR_MCOPRE_DIV8 (3 << RCC_CFGR_MCOPRE_SHIFT) /* 011: division by 8 */ -# define RCC_CFGR_MCOPRE_DIV16 (4 << RCC_CFGR_MCOPRE_SHIFT) /* 100: division by 16 */ +#define RCC_CFGR_MCOPRE_SHIFT (28) /* Bits 28-30: MCO prescaler */ +#define RCC_CFGR_MCOPRE_MASK (7 << RCC_CFGR_MCOPRE_SHIFT) +# define RCC_CFGR_MCOPRE_NONE (0 << RCC_CFGR_MCOPRE_SHIFT) /* 000: no division */ +# define RCC_CFGR_MCOPRE_DIV2 (1 << RCC_CFGR_MCOPRE_SHIFT) /* 001: division by 2 */ +# define RCC_CFGR_MCOPRE_DIV4 (2 << RCC_CFGR_MCOPRE_SHIFT) /* 010: division by 4 */ +# define RCC_CFGR_MCOPRE_DIV8 (3 << RCC_CFGR_MCOPRE_SHIFT) /* 011: division by 8 */ +# define RCC_CFGR_MCOPRE_DIV16 (4 << RCC_CFGR_MCOPRE_SHIFT) /* 100: division by 16 */ /* PLL configuration register */ @@ -785,5 +787,14 @@ #define RCC_CRRCR_HSI48ON (1 << 0) /* Bit 0: HSI48 clock enable */ #define RCC_CRRCR_HSI48RDY (1 << 1) /* Bit 1: HSI48 clock ready flag */ +/* Peripheral Independent Clock Configuration 2 register (only on STM32L45x and STM32L46x) */ + +#define RCC_CCIPR2_I2C4SEL_SHIFT (0) /* Bits 0-1: I2C4 clock source selection */ +#define RCC_CCIPR2_I2C4SEL_MASK (3 << RCC_CCIPR2_I2C4SEL_SHIFT) +# define RCC_CCIPR2_I2C4SEL_PCLK (0 << RCC_CCIPR2_I2C4SEL_SHIFT) +# define RCC_CCIPR2_I2C4SEL_SYSCLK (1 << RCC_CCIPR2_I2C4SEL_SHIFT) +# define RCC_CCIPR2_I2C4SEL_HSI (2 << RCC_CCIPR2_I2C4SEL_SHIFT) + #endif /* CONFIG_STM32L4_STM32L4X3 */ #endif /* __ARCH_ARM_SRC_STM32L4_HARDWARE_STM32L4X3XX_RCC_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_i2c.c b/arch/arm/src/stm32l4/stm32l4_i2c.c index 06d4dcf0853..d6956eda903 100644 --- a/arch/arm/src/stm32l4/stm32l4_i2c.c +++ b/arch/arm/src/stm32l4/stm32l4_i2c.c @@ -1330,133 +1330,125 @@ static void stm32l4_i2c_setclock(FAR struct stm32l4_i2c_priv_s *priv, stm32l4_i2c_modifyreg32(priv, STM32L4_I2C_CR1_OFFSET, I2C_CR1_PE, 0); } - /* The Speed and timing calculation are based on the following - * fI2CCLK = PCLK and is 80Mhz - * Analog filter is on, - * Digital filter off - * Rise Time is 120 ns and fall is 10ns - * Mode is FastMode - */ - - i2cclk_mhz = 80; +#if defined(STM32L4_I2C_USE_HSI16) || (STM32L4_PCLK1_FREQUENCY == 16000000) + i2cclk_mhz = 16; +#elif STM32L4_PCLK1_FREQUENCY == 80000000 + i2cclk_mhz = 80 +#elif STM32L4_PCLK1_FREQUENCY == 120000000 + i2cclk_mhz = 120; +#else +# warning STM32_I2C_INIT: Peripheral clock is PCLK and the speed/timing calculations need to be redone. +#endif if (i2cclk_mhz == 80) { - uint8_t h_time; - uint8_t s_time; + /* Default timing calculations from original STM32L4 driver: */ - /* Default timing calculations from original STM32L4 driver, - * fI2CCLK = PCLK, 80 Mhz */ + /* The Speed and timing calculation are based on the following + * fI2CCLK = PCLK and is 80 Mhz + * Analog filter is on, + * Digital filter off + * Rise Time is 120 ns and fall is 10 ns + * Mode is FastMode + */ if (frequency == 100000) { - /* 100 KHz values from I2C timing tool with clock 80mhz */ + /* 100 KHz values from I2C timing tool with clock 80 MHz */ 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 */ + sda_delay = 0x00; /* SDADEL - (+1) data hold time after SCL falling edge */ + scl_delay = 0x0d; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */ } else if (frequency == 400000) { - /* 400 KHz values from I2C timing tool for clock of 80mhz */ + /* 400 KHz values from I2C timing tool for clock of 80 MHz */ 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 */ + sda_delay = 0x00; /* SDADEL - (+1) data hold time after SCL falling edge */ + scl_delay = 0x07; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */ } else if (frequency == 1000000) { - /* 1000 KHhz values from I2C timing tool for clock of 80mhz */ + /* 1000 KHz values from I2C timing tool for clock of 80 MHz */ 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; + sda_delay = 0x00; /* SDADEL - (+1) data hold time after SCL falling edge */ + scl_delay = 0x05; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */ } else { - /* 10 KHz values from I2C timing tool with clock 80mhz */ + /* 10 KHz values from I2C timing tool with clock 80 MHz */ presc = 0x0b; /* PRESC - (+1) prescale I2CCLK */ 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 */ + sda_delay = 0x00; /* SDADEL - (+1) data hold time after SCL falling edge */ + scl_delay = 0x01; /* SCLDEL - (+1) data setup time from SDA edge to SCL rising edge */ } - - scl_delay = s_time; - sda_delay = h_time; } - -#if 0 - /* TODO: Alternative clock configurations. Through Kconfig? - * Or auto-detect? */ - - else if (i2cclk_mhz == 8) + else if (i2cclk_mhz == 120) { - uint8_t h_time; - uint8_t s_time; - - /* Alternative timing calculations from original STM32L4 driver, - * fI2CCLK = PCLK, 8 Mhz */ + /* The Speed and timing calculation are based on the following + * fI2CCLK = PCLK and is 120 Mhz + * Analog filter is on, + * Digital filter off + * Rise Time is 120 ns and fall is 25 ns + * Mode is FastMode + */ if (frequency == 100000) { - /* 100 KHz values from datasheet with clock 8mhz */ + /* 100 KHz values from I2C timing tool with clock 120 MHz */ - presc = 0x01; - scl_l_period = 0x13; - scl_h_period = 0x0f; - h_time = 0x02; - s_time = 0x04; + presc = 2; + scl_delay = 14; + sda_delay = 0; + scl_h_period = 157; + scl_l_period = 230; } else if (frequency == 400000) { - /* 400 KHz values from datasheet for clock of 8mhz */ + /* 400 KHz values from I2C timing tool for clock of 120 MHz */ - presc = 0x00; - scl_l_period = 0x09; - scl_h_period = 0x03; - h_time = 0x01; - s_time = 0x03; + presc = 2; + scl_delay = 8; + sda_delay = 0; + scl_h_period = 21; + scl_l_period = 66; } else if (frequency == 1000000) { - /* 500 KHhz values from datasheet for clock of 8mhz */ + /* 1000 KHz values from I2C timing tool for clock of 120 MHz */ - presc = 0x00; - scl_l_period = 0x06; - scl_h_period = 0x03; - h_time = 0x00; - s_time = 0x01; - - frequency = 500000; + presc = 2; + scl_delay = 6; + sda_delay = 0; + scl_h_period = 7; + scl_l_period = 20; } else { - /* 10 KHz values from I2C timing tool with clock 8mhz */ + /* 10 KHz values not supported */ - 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 */ + DEBUGPANIC(); } - - scl_delay = s_time; - sda_delay = h_time; } - else if (i2cclk_mhz == 16) { - /* Timing calculations from STM32F7 driver, fI2CCLK = HSI 16 MHz */ + /* The Speed and timing calculation are based on the following + * fI2CCLK = HSI and is 16Mhz + * Analog filter is on, + * Digital filter off + * Rise Time is 120 ns and fall is 10ns + * Mode is FastMode + */ if (frequency == 100000) { @@ -1465,24 +1457,23 @@ static void stm32l4_i2c_setclock(FAR struct stm32l4_i2c_priv_s *priv, sda_delay = 0; scl_h_period = 61; scl_l_period = 89; - } else if (frequency == 400000) - { - presc = 0; - scl_delay = 3; - sda_delay = 0; - scl_h_period = 6; - scl_l_period = 24; - } + { + presc = 0; + scl_delay = 3; + sda_delay = 0; + scl_h_period = 6; + scl_l_period = 24; + } else if (frequency == 1000000) - { - presc = 0; - scl_delay = 2; - sda_delay = 0; - scl_h_period = 1; - scl_l_period = 5; - } + { + presc = 0; + scl_delay = 2; + sda_delay = 0; + scl_h_period = 1; + scl_l_period = 5; + } else { presc = 7; @@ -1492,7 +1483,6 @@ static void stm32l4_i2c_setclock(FAR struct stm32l4_i2c_priv_s *priv, scl_l_period = 162; } } -#endif else { DEBUGPANIC(); @@ -2917,11 +2907,6 @@ FAR struct i2c_master_s *stm32l4_i2cbus_initialize(int port) int ret; #endif -#if STM32L4_PCLK1_FREQUENCY != 80000000 -# warning STM32_I2C_INIT: Peripheral clock is PCLK and it must be 80mHz or the speed/timing calculations need to be redone. - return NULL; -#endif - /* Get I2C private structure */ switch (port) diff --git a/arch/arm/src/stm32l4/stm32l4_lptim.c b/arch/arm/src/stm32l4/stm32l4_lptim.c index 951e0ab9259..dc73a52f0bd 100644 --- a/arch/arm/src/stm32l4/stm32l4_lptim.c +++ b/arch/arm/src/stm32l4/stm32l4_lptim.c @@ -136,7 +136,7 @@ static struct stm32l4_lptim_priv_s stm32l4_lptim1_priv = .ops = &stm32l4_lptim_ops, .mode = STM32L4_LPTIM_MODE_UNUSED, .base = STM32L4_LPTIM1_BASE, - .freq = STM32L4_LPTIM1_FREQUENCY, /* Must be efined in board.h */ + .freq = STM32L4_LPTIM1_FREQUENCY, /* Must be defined in board.h */ }; #endif @@ -146,7 +146,7 @@ static struct stm32l4_lptim_priv_s stm32l4_lptim2_priv = .ops = &stm32l4_lptim_ops, .mode = STM32L4_LPTIM_MODE_UNUSED, .base = STM32L4_LPTIM2_BASE, - .freq = STM32L4_LPTIM2_FREQUENCY, /* Must be efined in board.h */ + .freq = STM32L4_LPTIM2_FREQUENCY, /* Must be defined in board.h */ }; #endif diff --git a/arch/arm/src/stm32l4/stm32l4x3xx_rcc.c b/arch/arm/src/stm32l4/stm32l4x3xx_rcc.c index cd080bd521e..e84253cdf2c 100644 --- a/arch/arm/src/stm32l4/stm32l4x3xx_rcc.c +++ b/arch/arm/src/stm32l4/stm32l4x3xx_rcc.c @@ -537,6 +537,24 @@ static inline void rcc_enableccip(void) regval = getreg32(STM32L4_RCC_CCIPR); +#if defined(STM32L4_I2C_USE_HSI16) +#ifdef CONFIG_STM32L4_I2C1 + /* Select HSI16 as I2C1 clock source. */ + + regval |= RCC_CCIPR_I2C1SEL_HSI; +#endif +#ifdef CONFIG_STM32L4_I2C2 + /* Select HSI16 as I2C2 clock source. */ + + regval |= RCC_CCIPR_I2C2SEL_HSI; +#endif +#ifdef CONFIG_STM32L4_I2C3 + /* Select HSI16 as I2C3 clock source. */ + + regval |= RCC_CCIPR_I2C3SEL_HSI; +#endif +#endif /* STM32L4_I2C_USE_HSI16 */ + #if defined(STM32L4_USE_CLK48) /* XXX sanity if sdmmc1 or usb or rng, then we need to set the clk48 source * and then we can also do away with STM32L4_USE_CLK48, and give better @@ -565,6 +583,20 @@ static inline void rcc_enableccip(void) #endif putreg32(regval, STM32L4_RCC_CCIPR); + + /* I2C4 alone has their clock selection in CCIPR2 register. */ + +#if defined(STM32L4_I2C_USE_HSI16) +#ifdef CONFIG_STM32L4_I2C4 + regval = getreg32(STM32L4_RCC_CCIPR2); + + /* Select HSI16 as I2C4 clock source. */ + + regval |= RCC_CCIPR_I2C4SEL_HSI; + + putreg32(regval, STM32L4_RCC_CCIPR2); +#endif +#endif } /**************************************************************************** @@ -583,7 +615,7 @@ static void stm32l4_stdclockconfig(void) uint32_t regval; volatile int32_t timeout; -#ifdef STM32L4_BOARD_USEHSI +#if defined(STM32L4_BOARD_USEHSI) || defined(STM32L4_I2C_USE_HSI16) /* Enable Internal High-Speed Clock (HSI) */ regval = getreg32(STM32L4_RCC_CR); @@ -603,6 +635,10 @@ static void stm32l4_stdclockconfig(void) break; } } +#endif + +#if defined(STM32L4_BOARD_USEHSI) + /* Already set above */ #elif defined(STM32L4_BOARD_USEMSI) /* Enable Internal Multi-Speed Clock (MSI) */ diff --git a/arch/arm/src/stm32l4/stm32l4x5xx_rcc.c b/arch/arm/src/stm32l4/stm32l4x5xx_rcc.c index 32d39e25bc2..5bbaf153a49 100644 --- a/arch/arm/src/stm32l4/stm32l4x5xx_rcc.c +++ b/arch/arm/src/stm32l4/stm32l4x5xx_rcc.c @@ -548,6 +548,24 @@ static inline void rcc_enableccip(void) regval = getreg32(STM32L4_RCC_CCIPR); +#if defined(STM32L4_I2C_USE_HSI16) +#ifdef CONFIG_STM32L4_I2C1 + /* Select HSI16 as I2C1 clock source. */ + + regval |= RCC_CCIPR_I2C1SEL_HSI; +#endif +#ifdef CONFIG_STM32L4_I2C2 + /* Select HSI16 as I2C2 clock source. */ + + regval |= RCC_CCIPR_I2C2SEL_HSI; +#endif +#ifdef CONFIG_STM32L4_I2C3 + /* Select HSI16 as I2C3 clock source. */ + + regval |= RCC_CCIPR_I2C3SEL_HSI; +#endif +#endif /* STM32L4_I2C_USE_HSI16 */ + #if defined(STM32L4_USE_CLK48) /* XXX sanity if sdmmc1 or usb or rng, then we need to set the clk48 source * and then we can also do away with STM32L4_USE_CLK48, and give better @@ -588,7 +606,7 @@ static void stm32l4_stdclockconfig(void) uint32_t regval; volatile int32_t timeout; -#ifdef STM32L4_BOARD_USEHSI +#if defined(STM32L4_BOARD_USEHSI) || defined(STM32L4_I2C_USE_HSI16) /* Enable Internal High-Speed Clock (HSI) */ regval = getreg32(STM32L4_RCC_CR); @@ -608,6 +626,10 @@ static void stm32l4_stdclockconfig(void) break; } } +#endif + +#if defined(STM32L4_BOARD_USEHSI) + /* Already set above */ #elif defined(STM32L4_BOARD_USEMSI) /* Enable Internal Multi-Speed Clock (MSI) */ @@ -900,7 +922,7 @@ static void stm32l4_stdclockconfig(void) regval |= RCC_CR_MSIPLLEN; putreg32(regval, STM32L4_RCC_CR); # endif -#endif +#endif /* STM32L4_USE_LSE */ } } #endif diff --git a/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c index ad32568963e..60098e47bd2 100644 --- a/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c +++ b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c @@ -611,6 +611,24 @@ static inline void rcc_enableccip(void) regval = getreg32(STM32L4_RCC_CCIPR); +#if defined(STM32L4_I2C_USE_HSI16) +#ifdef CONFIG_STM32L4_I2C1 + /* Select HSI16 as I2C1 clock source. */ + + regval |= RCC_CCIPR_I2C1SEL_HSI; +#endif +#ifdef CONFIG_STM32L4_I2C2 + /* Select HSI16 as I2C2 clock source. */ + + regval |= RCC_CCIPR_I2C2SEL_HSI; +#endif +#ifdef CONFIG_STM32L4_I2C3 + /* Select HSI16 as I2C3 clock source. */ + + regval |= RCC_CCIPR_I2C3SEL_HSI; +#endif +#endif /* STM32L4_I2C_USE_HSI16 */ + #if defined(STM32L4_USE_CLK48) /* XXX sanity if sdmmc1 or usb or rng, then we need to set the clk48 source * and then we can also do away with STM32L4_USE_CLK48, and give better @@ -633,6 +651,20 @@ static inline void rcc_enableccip(void) #endif putreg32(regval, STM32L4_RCC_CCIPR); + + /* I2C4 alone has their clock selection in CCIPR2 register. */ + +#if defined(STM32L4_I2C_USE_HSI16) +#ifdef CONFIG_STM32L4_I2C4 + regval = getreg32(STM32L4_RCC_CCIPR2); + + /* Select HSI16 as I2C4 clock source. */ + + regval |= RCC_CCIPR_I2C4SEL_HSI; + + putreg32(regval, STM32L4_RCC_CCIPR2); +#endif +#endif } /**************************************************************************** @@ -651,7 +683,7 @@ static void stm32l4_stdclockconfig(void) uint32_t regval; volatile int32_t timeout; -#ifdef STM32L4_BOARD_USEHSI +#if defined(STM32L4_BOARD_USEHSI) || defined(STM32L4_I2C_USE_HSI16) /* Enable Internal High-Speed Clock (HSI) */ regval = getreg32(STM32L4_RCC_CR); @@ -671,6 +703,10 @@ static void stm32l4_stdclockconfig(void) break; } } +#endif + +#if defined(STM32L4_BOARD_USEHSI) + /* Already set above */ #elif defined(STM32L4_BOARD_USEMSI) /* Enable Internal Multi-Speed Clock (MSI) */ diff --git a/arch/arm/src/stm32l4/stm32l4xrxx_rcc.c b/arch/arm/src/stm32l4/stm32l4xrxx_rcc.c index 01b9d213342..6c2c12d9a18 100644 --- a/arch/arm/src/stm32l4/stm32l4xrxx_rcc.c +++ b/arch/arm/src/stm32l4/stm32l4xrxx_rcc.c @@ -586,6 +586,24 @@ static inline void rcc_enableccip(void) regval = getreg32(STM32L4_RCC_CCIPR); +#if defined(STM32L4_I2C_USE_HSI16) +#ifdef CONFIG_STM32L4_I2C1 + /* Select HSI16 as I2C1 clock source. */ + + regval |= RCC_CCIPR_I2C1SEL_HSI; +#endif +#ifdef CONFIG_STM32L4_I2C2 + /* Select HSI16 as I2C2 clock source. */ + + regval |= RCC_CCIPR_I2C2SEL_HSI; +#endif +#ifdef CONFIG_STM32L4_I2C3 + /* Select HSI16 as I2C3 clock source. */ + + regval |= RCC_CCIPR_I2C3SEL_HSI; +#endif +#endif /* STM32L4_I2C_USE_HSI16 */ + #if defined(STM32L4_USE_CLK48) /* XXX sanity if sdmmc1 or usb or rng, then we need to set the clk48 source * and then we can also do away with STM32L4_USE_CLK48, and give better @@ -607,6 +625,14 @@ static inline void rcc_enableccip(void) regval = getreg32(STM32L4_RCC_CCIPR2); +#if defined(STM32L4_I2C_USE_HSI16) +#ifdef CONFIG_STM32L4_I2C4 + /* Select HSI16 as I2C4 clock source. */ + + regval |= RCC_CCIPR2_I2C4SEL_HSI; +#endif +#endif + #ifdef CONFIG_STM32L4_DFSDM1 /* Select SAI1 as DFSDM audio clock source. */ @@ -636,7 +662,7 @@ static void stm32l4_stdclockconfig(void) uint32_t regval; volatile int32_t timeout; -#ifdef STM32L4_BOARD_USEHSI +#if defined(STM32L4_BOARD_USEHSI) || defined(STM32L4_I2C_USE_HSI16) /* Enable Internal High-Speed Clock (HSI) */ regval = getreg32(STM32L4_RCC_CR); @@ -656,6 +682,10 @@ static void stm32l4_stdclockconfig(void) break; } } +#endif + +#if defined(STM32L4_BOARD_USEHSI) + /* Already set above */ #elif defined(STM32L4_BOARD_USEMSI) /* Enable Internal Multi-Speed Clock (MSI) */