You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
6.4 KiB
215 lines
6.4 KiB
/* |
|
* Copyright (c) 2016 BayLibre, SAS |
|
* Copyright (c) 2017 Linaro Ltd |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
* |
|
*/ |
|
|
|
#ifndef ZEPHYR_DRIVERS_I2C_I2C_LL_STM32_H_ |
|
#define ZEPHYR_DRIVERS_I2C_I2C_LL_STM32_H_ |
|
|
|
#include <zephyr/drivers/i2c/stm32.h> |
|
#include <zephyr/kernel.h> |
|
#include <zephyr/devicetree.h> |
|
#include <zephyr/pm/device.h> |
|
#include <zephyr/pm/device_runtime.h> |
|
#include <zephyr/logging/log.h> |
|
|
|
#ifdef CONFIG_I2C_STM32_BUS_RECOVERY |
|
#include <zephyr/drivers/gpio.h> |
|
#endif /* CONFIG_I2C_STM32_BUS_RECOVERY */ |
|
|
|
#include <zephyr/drivers/dma.h> |
|
|
|
typedef void (*irq_config_func_t)(const struct device *port); |
|
|
|
#ifdef CONFIG_I2C_STM32_V2 |
|
/* Private I2C_MSG_* flags for STM32 I2C */ |
|
#define I2C_MSG_STM32_USE_RELOAD_MODE BIT(7) |
|
#endif |
|
|
|
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_i2c_v2) |
|
/** |
|
* @brief structure to convey optional i2c timings settings |
|
*/ |
|
struct i2c_config_timing { |
|
/* i2c peripheral clock in Hz */ |
|
uint32_t periph_clock; |
|
/* i2c bus speed in Hz */ |
|
uint32_t i2c_speed; |
|
/* I2C_TIMINGR register value of i2c v2 peripheral */ |
|
uint32_t timing_setting; |
|
}; |
|
#endif |
|
|
|
#ifdef CONFIG_I2C_STM32_V2_DMA |
|
struct stream { |
|
const struct device *dev_dma; |
|
int32_t dma_channel; |
|
}; |
|
#endif /* CONFIG_I2C_STM32_V2_DMA */ |
|
|
|
struct i2c_stm32_config { |
|
#ifdef CONFIG_I2C_STM32_INTERRUPT |
|
irq_config_func_t irq_config_func; |
|
#endif |
|
#ifdef CONFIG_I2C_STM32_BUS_RECOVERY |
|
struct gpio_dt_spec scl; |
|
struct gpio_dt_spec sda; |
|
#endif /* CONFIG_I2C_STM32_BUS_RECOVERY */ |
|
const struct stm32_pclken *pclken; |
|
size_t pclk_len; |
|
I2C_TypeDef *i2c; |
|
uint32_t bitrate; |
|
const struct pinctrl_dev_config *pcfg; |
|
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_i2c_v2) |
|
const struct i2c_config_timing *timings; |
|
size_t n_timings; |
|
#endif |
|
#ifdef CONFIG_I2C_STM32_V2_DMA |
|
struct stream tx_dma; |
|
struct stream rx_dma; |
|
#endif /* CONFIG_I2C_STM32_V2_DMA */ |
|
}; |
|
|
|
struct i2c_stm32_data { |
|
#ifdef CONFIG_I2C_RTIO |
|
struct i2c_rtio *ctx; |
|
uint32_t dev_config; |
|
uint8_t *xfer_buf; |
|
size_t xfer_len; |
|
uint8_t xfer_flags; |
|
#ifdef CONFIG_I2C_STM32_V1 |
|
size_t msg_len; |
|
uint8_t is_restart; |
|
uint16_t slave_address; |
|
#else |
|
uint8_t burst_flags; |
|
uint8_t burst_len; |
|
#endif /* CONFIG_I2C_STM32_V1 */ |
|
#else /* CONFIG_I2C_RTIO */ |
|
#ifdef CONFIG_I2C_STM32_INTERRUPT |
|
struct k_sem device_sync_sem; |
|
#endif /* CONFIG_I2C_STM32_INTERRUPT */ |
|
struct k_sem bus_mutex; |
|
uint32_t dev_config; |
|
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_i2c_v2) |
|
/* Store the current timing structure set by runtime config */ |
|
struct i2c_config_timing current_timing; |
|
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_i2c_v2) */ |
|
#ifdef CONFIG_I2C_STM32_V1 |
|
uint16_t slave_address; |
|
#endif /* CONFIG_I2C_STM32_V1 */ |
|
struct { |
|
#ifdef CONFIG_I2C_STM32_V1 |
|
unsigned int is_restart; |
|
unsigned int flags; |
|
#endif /* CONFIG_I2C_STM32_V1 */ |
|
unsigned int is_write; |
|
unsigned int is_arlo; |
|
unsigned int is_nack; |
|
unsigned int is_err; |
|
struct i2c_msg *msg; |
|
unsigned int len; |
|
uint8_t *buf; |
|
} current; |
|
bool is_configured; |
|
bool smbalert_active; |
|
enum i2c_stm32_mode mode; |
|
#ifdef CONFIG_SMBUS_STM32_SMBALERT |
|
i2c_stm32_smbalert_cb_func_t smbalert_cb_func; |
|
const struct device *smbalert_cb_dev; |
|
#endif /* CONFIG_SMBUS_STM32_SMBALERT */ |
|
#ifdef CONFIG_I2C_STM32_V2_DMA |
|
struct dma_config dma_tx_cfg; |
|
struct dma_config dma_rx_cfg; |
|
struct dma_block_config dma_blk_cfg; |
|
#endif /* CONFIG_I2C_STM32_V2_DMA */ |
|
#endif /* CONFIG_I2C_RTIO */ |
|
|
|
#ifdef CONFIG_I2C_TARGET |
|
bool master_active; |
|
bool slave_attached; |
|
struct i2c_target_config *slave_cfg; |
|
#ifdef CONFIG_I2C_STM32_V2 |
|
struct i2c_target_config *slave2_cfg; |
|
#endif /* CONFIG_I2C_STM32_V2 */ |
|
#endif /* CONFIG_I2C_TARGET */ |
|
}; |
|
|
|
#ifdef CONFIG_I2C_RTIO |
|
bool i2c_stm32_start(const struct device *dev); |
|
int i2c_stm32_msg_start(const struct device *dev, uint8_t flags, |
|
uint8_t *buf, size_t buf_len, uint16_t i2c_addr); |
|
#else /* CONFIG_I2C_RTIO */ |
|
int i2c_stm32_transaction(const struct device *dev, |
|
struct i2c_msg msg, uint8_t *next_msg_flags, |
|
uint16_t periph); |
|
#endif /* CONFIG_I2C_RTIO */ |
|
|
|
int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config); |
|
|
|
#ifdef CONFIG_I2C_TARGET |
|
int i2c_stm32_target_register(const struct device *dev, struct i2c_target_config *config); |
|
int i2c_stm32_target_unregister(const struct device *dev, struct i2c_target_config *config); |
|
#endif /* CONFIG_I2C_TARGET */ |
|
|
|
int i2c_stm32_activate(const struct device *dev); |
|
int i2c_stm32_configure_timing(const struct device *dev, uint32_t clk); |
|
|
|
#ifdef CONFIG_PM_DEVICE |
|
int i2c_stm32_pm_action(const struct device *dev, enum pm_device_action action); |
|
int i2c_stm32_suspend(const struct device *dev); |
|
#endif /* CONFIG_PM_DEVICE */ |
|
|
|
int i2c_stm32_error(const struct device *dev); |
|
void i2c_stm32_event(const struct device *dev); |
|
|
|
#ifdef CONFIG_I2C_STM32_INTERRUPT |
|
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT |
|
void i2c_stm32_combined_isr(void *arg); |
|
#define I2C_STM32_IRQ_CONNECT_AND_ENABLE(index) \ |
|
do { \ |
|
IRQ_CONNECT(DT_INST_IRQN(index), \ |
|
DT_INST_IRQ(index, priority), \ |
|
i2c_stm32_combined_isr, \ |
|
DEVICE_DT_INST_GET(index), 0); \ |
|
irq_enable(DT_INST_IRQN(index)); \ |
|
} while (false) |
|
#else /* CONFIG_I2C_STM32_COMBINED_INTERRUPT */ |
|
void i2c_stm32_event_isr(void *arg); |
|
void i2c_stm32_error_isr(void *arg); |
|
#define I2C_STM32_IRQ_CONNECT_AND_ENABLE(index) \ |
|
do { \ |
|
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, event, irq), \ |
|
DT_INST_IRQ_BY_NAME(index, event, priority), \ |
|
i2c_stm32_event_isr, \ |
|
DEVICE_DT_INST_GET(index), 0); \ |
|
irq_enable(DT_INST_IRQ_BY_NAME(index, event, irq)); \ |
|
\ |
|
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, error, irq), \ |
|
DT_INST_IRQ_BY_NAME(index, error, priority), \ |
|
i2c_stm32_error_isr, \ |
|
DEVICE_DT_INST_GET(index), 0); \ |
|
irq_enable(DT_INST_IRQ_BY_NAME(index, error, irq)); \ |
|
} while (false) |
|
#endif /* CONFIG_I2C_STM32_COMBINED_INTERRUPT */ |
|
|
|
#define I2C_STM32_IRQ_HANDLER_DECL(index) \ |
|
static void i2c_stm32_irq_config_func_##index(const struct device *dev) |
|
#define I2C_STM32_IRQ_HANDLER_FUNCTION(index) \ |
|
.irq_config_func = i2c_stm32_irq_config_func_##index, |
|
#define I2C_STM32_IRQ_HANDLER(index) \ |
|
static void i2c_stm32_irq_config_func_##index(const struct device *dev) \ |
|
{ \ |
|
I2C_STM32_IRQ_CONNECT_AND_ENABLE(index); \ |
|
} |
|
|
|
#else /* CONFIG_I2C_STM32_INTERRUPT */ |
|
#define I2C_STM32_IRQ_HANDLER_DECL(index) |
|
#define I2C_STM32_IRQ_HANDLER_FUNCTION(index) |
|
#define I2C_STM32_IRQ_HANDLER(index) |
|
#endif /* CONFIG_I2C_STM32_INTERRUPT */ |
|
|
|
#endif /* ZEPHYR_DRIVERS_I2C_I2C_LL_STM32_H_ */
|
|
|