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