1 /*
2 * Copyright (c) 2019 Song Qiang <songqiang1304521@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @brief DMA low level driver implementation for F0/F1/F3/L0/L4 series SoCs.
9 */
10
11 #include "dma_stm32.h"
12
13 #define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
14 #include <logging/log.h>
15 LOG_MODULE_REGISTER(dma_stm32_v2);
16
17
dma_stm32_id_to_stream(uint32_t id)18 uint32_t dma_stm32_id_to_stream(uint32_t id)
19 {
20 static const uint32_t stream_nr[] = {
21 LL_DMA_CHANNEL_1,
22 LL_DMA_CHANNEL_2,
23 LL_DMA_CHANNEL_3,
24 LL_DMA_CHANNEL_4,
25 LL_DMA_CHANNEL_5,
26 #if defined(LL_DMA_CHANNEL_6)
27 LL_DMA_CHANNEL_6,
28 #if defined(LL_DMA_CHANNEL_7)
29 LL_DMA_CHANNEL_7,
30 #if defined(LL_DMA_CHANNEL_8)
31 LL_DMA_CHANNEL_8,
32 #endif /* LL_DMA_CHANNEL_8 */
33 #endif /* LL_DMA_CHANNEL_7 */
34 #endif /* LL_DMA_CHANNEL_6 */
35 };
36
37 __ASSERT_NO_MSG(id < ARRAY_SIZE(stream_nr));
38
39 return stream_nr[id];
40 }
41
dma_stm32_clear_ht(DMA_TypeDef * DMAx,uint32_t id)42 void dma_stm32_clear_ht(DMA_TypeDef *DMAx, uint32_t id)
43 {
44 static const dma_stm32_clear_flag_func func[] = {
45 LL_DMA_ClearFlag_HT1,
46 LL_DMA_ClearFlag_HT2,
47 LL_DMA_ClearFlag_HT3,
48 LL_DMA_ClearFlag_HT4,
49 LL_DMA_ClearFlag_HT5,
50 #if defined(LL_DMA_IFCR_CHTIF6)
51 LL_DMA_ClearFlag_HT6,
52 #if defined(LL_DMA_IFCR_CHTIF7)
53 LL_DMA_ClearFlag_HT7,
54 #if defined(LL_DMA_IFCR_CHTIF8)
55 LL_DMA_ClearFlag_HT8,
56 #endif /* LL_DMA_IFCR_CHTIF8 */
57 #endif /* LL_DMA_IFCR_CHTIF7 */
58 #endif /* LL_DMA_IFCR_CHTIF6 */
59 };
60
61 __ASSERT_NO_MSG(id < ARRAY_SIZE(func));
62
63 func[id](DMAx);
64 }
65
dma_stm32_clear_tc(DMA_TypeDef * DMAx,uint32_t id)66 void dma_stm32_clear_tc(DMA_TypeDef *DMAx, uint32_t id)
67 {
68 static const dma_stm32_clear_flag_func func[] = {
69 LL_DMA_ClearFlag_TC1,
70 LL_DMA_ClearFlag_TC2,
71 LL_DMA_ClearFlag_TC3,
72 LL_DMA_ClearFlag_TC4,
73 LL_DMA_ClearFlag_TC5,
74 #if defined(LL_DMA_IFCR_CTCIF6)
75 LL_DMA_ClearFlag_TC6,
76 #if defined(LL_DMA_IFCR_CTCIF7)
77 LL_DMA_ClearFlag_TC7,
78 #if defined(LL_DMA_IFCR_CTCIF8)
79 LL_DMA_ClearFlag_TC8,
80 #endif /* LL_DMA_IFCR_CTCIF8 */
81 #endif /* LL_DMA_IFCR_CTCIF7 */
82 #endif /* LL_DMA_IFCR_CTCIF6 */
83 };
84
85 __ASSERT_NO_MSG(id < ARRAY_SIZE(func));
86
87 func[id](DMAx);
88 }
89
dma_stm32_is_ht_active(DMA_TypeDef * DMAx,uint32_t id)90 bool dma_stm32_is_ht_active(DMA_TypeDef *DMAx, uint32_t id)
91 {
92 static const dma_stm32_check_flag_func func[] = {
93 LL_DMA_IsActiveFlag_HT1,
94 LL_DMA_IsActiveFlag_HT2,
95 LL_DMA_IsActiveFlag_HT3,
96 LL_DMA_IsActiveFlag_HT4,
97 LL_DMA_IsActiveFlag_HT5,
98 #if defined(LL_DMA_IFCR_CHTIF6)
99 LL_DMA_IsActiveFlag_HT6,
100 #if defined(LL_DMA_IFCR_CHTIF7)
101 LL_DMA_IsActiveFlag_HT7,
102 #if defined(LL_DMA_IFCR_CHTIF8)
103 LL_DMA_IsActiveFlag_HT8,
104 #endif /* LL_DMA_IFCR_CHTIF8 */
105 #endif /* LL_DMA_IFCR_CHTIF7 */
106 #endif /* LL_DMA_IFCR_CHTIF6 */
107 };
108
109 __ASSERT_NO_MSG(id < ARRAY_SIZE(func));
110
111 return func[id](DMAx);
112 }
113
dma_stm32_is_tc_active(DMA_TypeDef * DMAx,uint32_t id)114 bool dma_stm32_is_tc_active(DMA_TypeDef *DMAx, uint32_t id)
115 {
116 static const dma_stm32_check_flag_func func[] = {
117 LL_DMA_IsActiveFlag_TC1,
118 LL_DMA_IsActiveFlag_TC2,
119 LL_DMA_IsActiveFlag_TC3,
120 LL_DMA_IsActiveFlag_TC4,
121 LL_DMA_IsActiveFlag_TC5,
122 #if defined(LL_DMA_IFCR_CTCIF6)
123 LL_DMA_IsActiveFlag_TC6,
124 #if defined(LL_DMA_IFCR_CTCIF7)
125 LL_DMA_IsActiveFlag_TC7,
126 #if defined(LL_DMA_IFCR_CTCIF8)
127 LL_DMA_IsActiveFlag_TC8,
128 #endif /* LL_DMA_IFCR_CTCIF8 */
129 #endif /* LL_DMA_IFCR_CTCIF7 */
130 #endif /* LL_DMA_IFCR_CTCIF6 */
131 };
132
133 __ASSERT_NO_MSG(id < ARRAY_SIZE(func));
134
135 return func[id](DMAx);
136 }
137
138
dma_stm32_clear_te(DMA_TypeDef * DMAx,uint32_t id)139 void dma_stm32_clear_te(DMA_TypeDef *DMAx, uint32_t id)
140 {
141 static const dma_stm32_clear_flag_func func[] = {
142 LL_DMA_ClearFlag_TE1,
143 LL_DMA_ClearFlag_TE2,
144 LL_DMA_ClearFlag_TE3,
145 LL_DMA_ClearFlag_TE4,
146 LL_DMA_ClearFlag_TE5,
147 #if defined(LL_DMA_IFCR_CTEIF6)
148 LL_DMA_ClearFlag_TE6,
149 #if defined(LL_DMA_IFCR_CTEIF7)
150 LL_DMA_ClearFlag_TE7,
151 #if defined(LL_DMA_IFCR_CTEIF8)
152 LL_DMA_ClearFlag_TE8,
153 #endif /* LL_DMA_IFCR_CTEIF6 */
154 #endif /* LL_DMA_IFCR_CTEIF7 */
155 #endif /* LL_DMA_IFCR_CTEIF8 */
156 };
157
158 __ASSERT_NO_MSG(id < ARRAY_SIZE(func));
159
160 func[id](DMAx);
161 }
162
dma_stm32_clear_gi(DMA_TypeDef * DMAx,uint32_t id)163 void dma_stm32_clear_gi(DMA_TypeDef *DMAx, uint32_t id)
164 {
165 static const dma_stm32_clear_flag_func func[] = {
166 LL_DMA_ClearFlag_GI1,
167 LL_DMA_ClearFlag_GI2,
168 LL_DMA_ClearFlag_GI3,
169 LL_DMA_ClearFlag_GI4,
170 LL_DMA_ClearFlag_GI5,
171 #if defined(LL_DMA_IFCR_CGIF6)
172 LL_DMA_ClearFlag_GI6,
173 #if defined(LL_DMA_IFCR_CGIF7)
174 LL_DMA_ClearFlag_GI7,
175 #if defined(LL_DMA_IFCR_CGIF8)
176 LL_DMA_ClearFlag_GI8,
177 #endif /* LL_DMA_IFCR_CGIF6 */
178 #endif /* LL_DMA_IFCR_CGIF7 */
179 #endif /* LL_DMA_IFCR_CGIF8 */
180 };
181
182 __ASSERT_NO_MSG(id < ARRAY_SIZE(func));
183
184 func[id](DMAx);
185 }
186
dma_stm32_is_te_active(DMA_TypeDef * DMAx,uint32_t id)187 bool dma_stm32_is_te_active(DMA_TypeDef *DMAx, uint32_t id)
188 {
189 static const dma_stm32_check_flag_func func[] = {
190 LL_DMA_IsActiveFlag_TE1,
191 LL_DMA_IsActiveFlag_TE2,
192 LL_DMA_IsActiveFlag_TE3,
193 LL_DMA_IsActiveFlag_TE4,
194 LL_DMA_IsActiveFlag_TE5,
195 #if defined(LL_DMA_IFCR_CTEIF6)
196 LL_DMA_IsActiveFlag_TE6,
197 #if defined(LL_DMA_IFCR_CTEIF7)
198 LL_DMA_IsActiveFlag_TE7,
199 #if defined(LL_DMA_IFCR_CTEIF8)
200 LL_DMA_IsActiveFlag_TE8,
201 #endif /* LL_DMA_IFCR_CTEIF6 */
202 #endif /* LL_DMA_IFCR_CTEIF7 */
203 #endif /* LL_DMA_IFCR_CTEIF8 */
204 };
205
206 __ASSERT_NO_MSG(id < ARRAY_SIZE(func));
207
208 return func[id](DMAx);
209 }
210
dma_stm32_is_gi_active(DMA_TypeDef * DMAx,uint32_t id)211 bool dma_stm32_is_gi_active(DMA_TypeDef *DMAx, uint32_t id)
212 {
213 static const dma_stm32_check_flag_func func[] = {
214 LL_DMA_IsActiveFlag_GI1,
215 LL_DMA_IsActiveFlag_GI2,
216 LL_DMA_IsActiveFlag_GI3,
217 LL_DMA_IsActiveFlag_GI4,
218 LL_DMA_IsActiveFlag_GI5,
219 #if defined(LL_DMA_IFCR_CGIF6)
220 LL_DMA_IsActiveFlag_GI6,
221 #if defined(LL_DMA_IFCR_CGIF7)
222 LL_DMA_IsActiveFlag_GI7,
223 #if defined(LL_DMA_IFCR_CGIF8)
224 LL_DMA_IsActiveFlag_GI8,
225 #endif /* LL_DMA_IFCR_CGIF6 */
226 #endif /* LL_DMA_IFCR_CGIF7 */
227 #endif /* LL_DMA_IFCR_CGIF8 */
228 };
229
230 __ASSERT_NO_MSG(id < ARRAY_SIZE(func));
231
232 return func[id](DMAx);
233 }
234
stm32_dma_dump_stream_irq(DMA_TypeDef * dma,uint32_t id)235 void stm32_dma_dump_stream_irq(DMA_TypeDef *dma, uint32_t id)
236 {
237 LOG_INF("tc: %d, ht: %d, te: %d, gi: %d",
238 dma_stm32_is_tc_active(dma, id),
239 dma_stm32_is_ht_active(dma, id),
240 dma_stm32_is_te_active(dma, id),
241 dma_stm32_is_gi_active(dma, id));
242 }
243
stm32_dma_is_tc_irq_active(DMA_TypeDef * dma,uint32_t id)244 bool stm32_dma_is_tc_irq_active(DMA_TypeDef *dma, uint32_t id)
245 {
246 return LL_DMA_IsEnabledIT_TC(dma, dma_stm32_id_to_stream(id)) &&
247 dma_stm32_is_tc_active(dma, id);
248 }
249
stm32_dma_is_ht_irq_active(DMA_TypeDef * dma,uint32_t id)250 bool stm32_dma_is_ht_irq_active(DMA_TypeDef *dma, uint32_t id)
251 {
252 return LL_DMA_IsEnabledIT_HT(dma, dma_stm32_id_to_stream(id)) &&
253 dma_stm32_is_ht_active(dma, id);
254 }
255
stm32_dma_is_te_irq_active(DMA_TypeDef * dma,uint32_t id)256 static inline bool stm32_dma_is_te_irq_active(DMA_TypeDef *dma, uint32_t id)
257 {
258 return LL_DMA_IsEnabledIT_TE(dma, dma_stm32_id_to_stream(id)) &&
259 dma_stm32_is_te_active(dma, id);
260 }
261
stm32_dma_is_irq_active(DMA_TypeDef * dma,uint32_t id)262 bool stm32_dma_is_irq_active(DMA_TypeDef *dma, uint32_t id)
263 {
264 return stm32_dma_is_tc_irq_active(dma, id) ||
265 stm32_dma_is_ht_irq_active(dma, id) ||
266 stm32_dma_is_te_irq_active(dma, id);
267 }
268
stm32_dma_clear_stream_irq(DMA_TypeDef * dma,uint32_t id)269 void stm32_dma_clear_stream_irq(DMA_TypeDef *dma, uint32_t id)
270 {
271 dma_stm32_clear_te(dma, id);
272 }
273
stm32_dma_is_irq_happened(DMA_TypeDef * dma,uint32_t id)274 bool stm32_dma_is_irq_happened(DMA_TypeDef *dma, uint32_t id)
275 {
276 if (dma_stm32_is_te_active(dma, id)) {
277 return true;
278 }
279
280 return false;
281 }
282
stm32_dma_is_unexpected_irq_happened(DMA_TypeDef * dma,uint32_t id)283 bool stm32_dma_is_unexpected_irq_happened(DMA_TypeDef *dma, uint32_t id)
284 {
285 /* Preserve for future amending. */
286 return false;
287 }
288
stm32_dma_enable_stream(DMA_TypeDef * dma,uint32_t id)289 void stm32_dma_enable_stream(DMA_TypeDef *dma, uint32_t id)
290 {
291 LL_DMA_EnableChannel(dma, dma_stm32_id_to_stream(id));
292 }
293
stm32_dma_disable_stream(DMA_TypeDef * dma,uint32_t id)294 int stm32_dma_disable_stream(DMA_TypeDef *dma, uint32_t id)
295 {
296 LL_DMA_DisableChannel(dma, dma_stm32_id_to_stream(id));
297
298 if (!LL_DMA_IsEnabledChannel(dma, dma_stm32_id_to_stream(id))) {
299 return 0;
300 }
301
302 return -EAGAIN;
303 }
304