blob: adfec0a697432e5badb551fe71643f8fbe15316e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
/*
* Copyright (c) 2006-2026, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-02-17 Dyyt587 first version
* 2024-06-23 wdfk-prog Add mode selection scaffolding
* 2024-06-23 wdfk-prog Distinguish STM32 I2C timing semantics by IP generation
*/
#ifndef __DRV_HARD_I2C_H__
#define __DRV_HARD_I2C_H__
#include <drv_common.h>
#include "drv_dma.h"
#include "drv_config.h"
#include <ipc/completion.h>
/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
/* hardware bus */
#if defined(BSP_USING_HARD_I2C1) \
|| defined(BSP_USING_HARD_I2C2) \
|| defined(BSP_USING_HARD_I2C3) \
|| defined(BSP_USING_HARD_I2C4)
#define BSP_HARDWARE_I2C
#endif
/* poll */
#if defined(BSP_I2C1_TX_USING_POLL) \
|| defined(BSP_I2C2_TX_USING_POLL) \
|| defined(BSP_I2C3_TX_USING_POLL) \
|| defined(BSP_I2C4_TX_USING_POLL)
#define BSP_I2C_TX_USING_POLL
#endif
#if defined(BSP_I2C1_RX_USING_POLL) \
|| defined(BSP_I2C2_RX_USING_POLL) \
|| defined(BSP_I2C3_RX_USING_POLL) \
|| defined(BSP_I2C4_RX_USING_POLL)
#define BSP_I2C_RX_USING_POLL
#endif
#if defined (BSP_I2C_TX_USING_POLL) \
|| defined (BSP_I2C_RX_USING_POLL)
#define BSP_I2C_USING_POLL
#endif
/* DMA */
#if defined(BSP_I2C1_TX_USING_DMA) \
|| defined(BSP_I2C2_TX_USING_DMA) \
|| defined(BSP_I2C3_TX_USING_DMA) \
|| defined(BSP_I2C4_TX_USING_DMA)
#define BSP_I2C_TX_USING_DMA
#endif
#if defined(BSP_I2C1_RX_USING_DMA) \
|| defined(BSP_I2C2_RX_USING_DMA) \
|| defined(BSP_I2C3_RX_USING_DMA) \
|| defined(BSP_I2C4_RX_USING_DMA)
#define BSP_I2C_RX_USING_DMA
#endif
#if defined (BSP_I2C_TX_USING_DMA) \
|| defined (BSP_I2C_RX_USING_DMA)
#define BSP_I2C_USING_DMA
#endif
/* INT */
#if defined(BSP_I2C1_TX_USING_INT) \
|| defined(BSP_I2C2_TX_USING_INT) \
|| defined(BSP_I2C3_TX_USING_INT) \
|| defined(BSP_I2C4_TX_USING_INT)
#define BSP_I2C_TX_USING_INT
#endif
#if defined(BSP_I2C1_RX_USING_INT) \
|| defined(BSP_I2C2_RX_USING_INT) \
|| defined(BSP_I2C3_RX_USING_INT) \
|| defined(BSP_I2C4_RX_USING_INT)
#define BSP_I2C_RX_USING_INT
#endif
#if defined (BSP_I2C_TX_USING_INT) \
|| defined (BSP_I2C_RX_USING_INT)
#define BSP_I2C_USING_INT
#endif
/* IRQ */
#if defined (BSP_I2C_USING_DMA) \
|| defined (BSP_I2C_USING_INT)
#define BSP_I2C_USING_IRQ
#endif
/*
* timing semantics are intentionally split by I2C IP generation:
*
* - legacy I2C IP:
* use bus frequency in Hz (for example 100000/400000), because HAL
* configures the peripheral through ClockSpeed/DutyCycle.
*
* - TIMINGR-based I2C IP:
* keep using the raw TIMINGR register value for now. Exact timing
* generation depends on board-level inputs such as kernel clock,
* rise/fall time, digital/analog filter settings, and target bus mode,
* so this change does not convert TIMINGR platforms to a unified Hz API.
*/
#if defined(SOC_SERIES_STM32F1) \
|| defined(SOC_SERIES_STM32F2) \
|| defined(SOC_SERIES_STM32F4) \
|| defined(SOC_SERIES_STM32L1)
#define STM32_I2C_LEGACY_IP
#else
#define STM32_I2C_TIMINGR_IP
#endif
#define BSP_I2C_CTRL_SET_TIMING 0x40
struct stm32_i2c_config
{
const char *name;
I2C_TypeDef *Instance;
/*
* timing semantics depend on the I2C IP generation:
* - legacy IP (F1/F4): bus speed in Hz
* - TIMINGR IP (F7/H7): raw TIMINGR register value
*/
rt_uint32_t timing;
rt_uint32_t timeout;
IRQn_Type evirq_type;
IRQn_Type erirq_type;
#ifdef BSP_I2C_RX_USING_DMA
const struct stm32_dma_config *dma_rx;
#endif /* BSP_I2C_RX_USING_DMA */
#ifdef BSP_I2C_TX_USING_DMA
const struct stm32_dma_config *dma_tx;
#endif /* BSP_I2C_TX_USING_DMA */
};
struct stm32_i2c
{
I2C_HandleTypeDef handle;
struct stm32_i2c_config *config;
struct rt_i2c_bus_device i2c_bus;
rt_uint16_t i2c_dma_flag;
#ifdef BSP_I2C_USING_IRQ
struct rt_completion completion;
#endif /* BSP_I2C_USING_IRQ */
#ifdef BSP_I2C_USING_DMA
struct
{
#ifdef BSP_I2C_RX_USING_DMA
DMA_HandleTypeDef handle_rx;
#endif /* BSP_I2C_RX_USING_DMA */
#ifdef BSP_I2C_TX_USING_DMA
DMA_HandleTypeDef handle_tx;
#endif /* BSP_I2C_TX_USING_DMA */
} dma;
#endif /* BSP_I2C_USING_DMA */
};
#ifdef __cplusplus
}
#endif
#endif /* __DRV_HARD_I2C_H__ */
|