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