mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
cpu/stm32: use HSI with I2C
This commit is contained in:
parent
20ffa92ba3
commit
cb5fef4486
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_stm32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Shared CPU specific configuration for STM32 family
|
||||
*
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef CPU_CONF_STM32_COMMON_H
|
||||
#define CPU_CONF_STM32_COMMON_H
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#include "periph/i2c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3) || \
|
||||
defined(CPU_FAM_STM32F7) || defined(CPU_FAM_STM32L0) || \
|
||||
defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32L4) || \
|
||||
defined(CPU_FAM_STM32WB) || defined(CPU_FAM_STM32G4) || \
|
||||
defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32L5) || \
|
||||
defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL)
|
||||
|
||||
/**
|
||||
* @brief Timing register settings
|
||||
*
|
||||
* @ref i2c_timing_param_t
|
||||
*/
|
||||
static const i2c_timing_param_t timing_params[] = {
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F7) || \
|
||||
defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) || \
|
||||
defined(CPU_FAM_STM32WL)
|
||||
[ I2C_SPEED_NORMAL ] = {
|
||||
.presc = 0xB,
|
||||
.scll = 0x13, /* t_SCLL = 5.0us */
|
||||
.sclh = 0xF, /* t_SCLH = 4.0us */
|
||||
.sdadel = 0x2, /* t_SDADEL = 500ns */
|
||||
.scldel = 0x4, /* t_SCLDEL = 1250ns */
|
||||
},
|
||||
[ I2C_SPEED_FAST ] = {
|
||||
.presc = 5,
|
||||
.scll = 0x9, /* t_SCLL = 1250ns */
|
||||
.sclh = 0x3, /* t_SCLH = 500ns */
|
||||
.sdadel = 0x3, /* t_SDADEL = 375ns */
|
||||
.scldel = 0x3, /* t_SCLDEL = 500ns */
|
||||
},
|
||||
[ I2C_SPEED_FAST_PLUS ] = {
|
||||
.presc = 5,
|
||||
.scll = 0x3, /* t_SCLL = 500ns */
|
||||
.sclh = 0x1, /* t_SCLH = 250ns */
|
||||
.sdadel = 0x0, /* t_SDADEL = 0ns */
|
||||
.scldel = 0x1, /* t_SCLDEL = 250ns */
|
||||
}
|
||||
#elif defined(CPU_FAM_STM32F3)
|
||||
[ I2C_SPEED_NORMAL ] = {
|
||||
.presc = 1,
|
||||
.scll = 0x13, /* t_SCLL = 5.0us */
|
||||
.sclh = 0xF, /* t_SCLH = 4.0us */
|
||||
.sdadel = 0x2, /* t_SDADEL = 500ns */
|
||||
.scldel = 0x4, /* t_SCLDEL = 1250ns */
|
||||
},
|
||||
[ I2C_SPEED_FAST ] = {
|
||||
.presc = 0,
|
||||
.scll = 0x9, /* t_SCLL = 1250ns */
|
||||
.sclh = 0x3, /* t_SCLH = 500ns */
|
||||
.sdadel = 0x1, /* t_SDADEL = 125ns */
|
||||
.scldel = 0x3, /* t_SCLDEL = 500ns */
|
||||
},
|
||||
[ I2C_SPEED_FAST_PLUS ] = {
|
||||
.presc = 0,
|
||||
.scll = 0x6, /* t_SCLL = 875ns */
|
||||
.sclh = 0x3, /* t_SCLH = 500ns */
|
||||
.sdadel = 0x0, /* t_SDADEL = 0ns */
|
||||
.scldel = 0x1, /* t_SCLDEL = 250ns */
|
||||
}
|
||||
#elif defined(CPU_FAM_STM32L0)
|
||||
[ I2C_SPEED_NORMAL ] = {
|
||||
.presc = 1,
|
||||
.scll = 0x56, /* t_SCLL = 5.0us */
|
||||
.sclh = 0x3E, /* t_SCLH = 4.0us */
|
||||
.sdadel = 0x1, /* t_SDADEL = 500ns */
|
||||
.scldel = 0xA, /* t_SCLDEL = 1250ns */
|
||||
},
|
||||
[ I2C_SPEED_FAST ] = {
|
||||
.presc = 0,
|
||||
.scll = 0x2E, /* t_SCLL = 1250ns */
|
||||
.sclh = 0x11, /* t_SCLH = 500ns */
|
||||
.sdadel = 0x1, /* t_SDADEL = 125ns */
|
||||
.scldel = 0xB, /* t_SCLDEL = 500ns */
|
||||
},
|
||||
[ I2C_SPEED_FAST_PLUS ] = {
|
||||
.presc = 0,
|
||||
.scll = 0x6, /* t_SCLL = 875ns */
|
||||
.sclh = 0x3, /* t_SCLH = 500ns */
|
||||
.sdadel = 0x0, /* t_SDADEL = 0ns */
|
||||
.scldel = 0x1, /* t_SCLDEL = 250ns */
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* CPU_FAM_STM32F0 || CPU_FAM_STM32F3 || CPU_FAM_STM32F7 ||
|
||||
CPU_FAM_STM32L0 || CPU_FAM_STM32L4 || CPU_FAM_STM32WB ||
|
||||
CPU_FAM_STM32G4 || CPU_FAM_STM32G0 || CPU_FAM_STM32L5 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CPU_CONF_STM32_COMMON_H */
|
||||
/** @} */
|
@ -88,7 +88,11 @@ typedef struct {
|
||||
#endif
|
||||
uint8_t bus; /**< APB bus */
|
||||
uint32_t rcc_mask; /**< bit in clock enable register */
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3) || \
|
||||
defined(CPU_FAM_STM32F7) || defined(CPU_FAM_STM32G0) || \
|
||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32L4) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL)
|
||||
uint32_t rcc_sw_mask; /**< bit to switch I2C clock */
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || \
|
||||
@ -101,20 +105,12 @@ typedef struct {
|
||||
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3) || \
|
||||
defined(CPU_FAM_STM32F7) || defined(CPU_FAM_STM32L0) || \
|
||||
defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) || \
|
||||
defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32L5) || \
|
||||
defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32G4) || \
|
||||
defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32WL)
|
||||
/**
|
||||
* @brief Structure for I2C timing register settings
|
||||
*
|
||||
* These parameters are valid for 48MHz (16MHz for L0) input clock.
|
||||
* See reference manual of supported CPU for example of timing settings:
|
||||
* - STM32F030/F070: see RM0360, section 22.4.10, p.560, table 76
|
||||
* - STM32F303: see RM0316, section 28.4.9, p.849, table 148
|
||||
* - STM32F72X: see RM0431, section 26.4.9, p.851, table 149
|
||||
* - STM32L0x2: see RM0376, section 27.4.10, p.686, table 117
|
||||
* - STM32L4X5/6: see RM0351, section 39.4.9, p.1297, table 234
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t presc; /**< Timing prescaler value */
|
||||
@ -123,7 +119,47 @@ typedef struct {
|
||||
uint8_t sdadel; /**< Data hold time */
|
||||
uint8_t scldel; /**< Data setup time */
|
||||
} i2c_timing_param_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Timing register settings
|
||||
*
|
||||
* These parameters are valid for HSI16 input clock.
|
||||
* See reference manual of supported CPU for example of timing settings:
|
||||
* - STM32F030/F070: see RM0360, section 22.4.10, p.560, table 76
|
||||
* - STM32F303: see RM0316, section 28.4.9, p.849, table 148
|
||||
* - STM32F72X: see RM0431, section 26.4.9, p.851, table 149
|
||||
* - STM32L0x2: see RM0376, section 27.4.10, p.686, table 117
|
||||
* - STM32L4X5/6: see RM0351, section 39.4.9, p.1297, table 234
|
||||
*
|
||||
* @ref i2c_timing_param_t
|
||||
*/
|
||||
static const i2c_timing_param_t timing_params[] = {
|
||||
[ I2C_SPEED_NORMAL ] = {
|
||||
.presc = 3,
|
||||
.scll = 0x13, /* t_SCLL = 5.0us */
|
||||
.sclh = 0xF, /* t_SCLH = 4.0us */
|
||||
.sdadel = 0x2, /* t_SDADEL = 500ns */
|
||||
.scldel = 0x4, /* t_SCLDEL = 1250ns */
|
||||
},
|
||||
[ I2C_SPEED_FAST ] = {
|
||||
.presc = 1,
|
||||
.scll = 0x9, /* t_SCLL = 1250ns */
|
||||
.sclh = 0x3, /* t_SCLH = 500ns */
|
||||
.sdadel = 0x2, /* t_SDADEL = 250ns */
|
||||
.scldel = 0x3, /* t_SCLDEL = 500ns */
|
||||
},
|
||||
[ I2C_SPEED_FAST_PLUS ] = {
|
||||
.presc = 0,
|
||||
.scll = 0x4, /* t_SCLL = 312.5ns */
|
||||
.sclh = 0x2, /* t_SCLH = 187.5ns */
|
||||
.sdadel = 0x0, /* t_SDADEL = 0ns */
|
||||
.scldel = 0x2, /* t_SCLDEL = 187.5ns */
|
||||
}
|
||||
};
|
||||
#endif /* CPU_FAM_STM32F0 || CPU_FAM_STM32F3 || CPU_FAM_STM32F7 ||
|
||||
CPU_FAM_STM32L0 || CPU_FAM_STM32L4 || CPU_FAM_STM32L5 ||
|
||||
CPU_FAM_STM32G0 || CPU_FAM_STM32G4 || CPU_FAM_STM32U5 ||
|
||||
CPU_FAM_STM32WB || CPU_FAM_STM32WL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -41,7 +41,7 @@
|
||||
#include "byteorder.h"
|
||||
#include "panic.h"
|
||||
|
||||
#include "cpu_conf_stm32_common.h"
|
||||
#include "stmclk.h"
|
||||
|
||||
#include "periph/i2c.h"
|
||||
#include "periph/gpio.h"
|
||||
@ -59,6 +59,18 @@
|
||||
|
||||
#define CLEAR_FLAG (I2C_ICR_NACKCF | I2C_ICR_ARLOCF | I2C_ICR_BERRCF | I2C_ICR_ADDRCF)
|
||||
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
#define I2C_CLOCK_SRC_REG (RCC->CFGR3)
|
||||
#elif defined(RCC_CCIPR_I2C1SEL)
|
||||
#define I2C_CLOCK_SRC_REG (RCC->CCIPR)
|
||||
#elif defined(RCC_CCIPR1_I2C1SEL)
|
||||
#define I2C_CLOCK_SRC_REG (RCC->CCIPR1)
|
||||
#elif defined(RCC_DCKCFGR2_I2C1SEL)
|
||||
#define I2C_CLOCK_SRC_REG (RCC->DCKCFGR2)
|
||||
#endif
|
||||
|
||||
static uint32_t hsi_state;
|
||||
|
||||
/* static function definitions */
|
||||
static inline void _i2c_init(I2C_TypeDef *i2c, uint32_t timing);
|
||||
static int _write(I2C_TypeDef *i2c, uint16_t addr, const void *data,
|
||||
@ -87,9 +99,11 @@ void i2c_init(i2c_t dev)
|
||||
NVIC_SetPriority(i2c_config[dev].irqn, I2C_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(i2c_config[dev].irqn);
|
||||
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
/* Set I2CSW bits to enable I2C clock source */
|
||||
RCC->CFGR3 |= i2c_config[dev].rcc_sw_mask;
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3) || \
|
||||
defined(CPU_FAM_STM32F7) || defined(CPU_FAM_STM32L4) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WB)
|
||||
/* select I2C clock source */
|
||||
I2C_CLOCK_SRC_REG |= i2c_config[dev].rcc_sw_mask;
|
||||
#endif
|
||||
|
||||
DEBUG("[i2c] init: configuring pins\n");
|
||||
@ -141,6 +155,11 @@ void i2c_acquire(i2c_t dev)
|
||||
assert(dev < I2C_NUMOF);
|
||||
|
||||
mutex_lock(&locks[dev]);
|
||||
hsi_state = (RCC->CR & RCC_CR_HSION);
|
||||
if (!hsi_state) {
|
||||
/* the internal RC oscillator (HSI) must be enabled */
|
||||
stmclk_enable_hsi();
|
||||
}
|
||||
|
||||
periph_clk_en(i2c_config[dev].bus, i2c_config[dev].rcc_mask);
|
||||
|
||||
@ -158,6 +177,9 @@ void i2c_release(i2c_t dev)
|
||||
_wait_for_bus(i2c_config[dev].dev);
|
||||
|
||||
periph_clk_dis(i2c_config[dev].bus, i2c_config[dev].rcc_mask);
|
||||
if (!hsi_state) {
|
||||
stmclk_disable_hsi();
|
||||
}
|
||||
|
||||
mutex_unlock(&locks[dev]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user