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