1 | /** |
---|
2 | * @file |
---|
3 | * |
---|
4 | * @ingroup mpc55xx |
---|
5 | * |
---|
6 | * @brief Enhanced Direct Memory Access (eDMA). |
---|
7 | */ |
---|
8 | |
---|
9 | /* |
---|
10 | * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved. |
---|
11 | * |
---|
12 | * embedded brains GmbH |
---|
13 | * Dornierstr. 4 |
---|
14 | * 82178 Puchheim |
---|
15 | * Germany |
---|
16 | * <rtems@embedded-brains.de> |
---|
17 | * |
---|
18 | * The license and distribution terms for this file may be |
---|
19 | * found in the file LICENSE in this distribution or at |
---|
20 | * http://www.rtems.com/license/LICENSE. |
---|
21 | */ |
---|
22 | |
---|
23 | #ifndef LIBCPU_POWERPC_MPC55XX_EDMA_H |
---|
24 | #define LIBCPU_POWERPC_MPC55XX_EDMA_H |
---|
25 | |
---|
26 | #include <mpc55xx/regs.h> |
---|
27 | |
---|
28 | #include <rtems.h> |
---|
29 | #include <rtems/chain.h> |
---|
30 | |
---|
31 | #ifdef __cplusplus |
---|
32 | extern "C" { |
---|
33 | #endif /* __cplusplus */ |
---|
34 | |
---|
35 | #if MPC55XX_CHIP_FAMILY == 551 |
---|
36 | #define EDMA_CHANNEL_COUNT 16U |
---|
37 | #elif MPC55XX_CHIP_FAMILY == 564 |
---|
38 | #define EDMA_CHANNEL_COUNT 16U |
---|
39 | #elif MPC55XX_CHIP_FAMILY == 567 |
---|
40 | #define EDMA_CHANNEL_COUNT 96U |
---|
41 | #else |
---|
42 | #define EDMA_CHANNEL_COUNT 64U |
---|
43 | #endif |
---|
44 | |
---|
45 | #define EDMA_MODULE_COUNT ((EDMA_CHANNEL_COUNT + 63U) / 64U) |
---|
46 | |
---|
47 | #define EDMA_CHANNELS_PER_MODULE 64U |
---|
48 | |
---|
49 | #if EDMA_MODULE_COUNT == 1 |
---|
50 | #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \ |
---|
51 | (&EDMA.TCD[(channel_index)]) |
---|
52 | #elif EDMA_MODULE_COUNT == 2 |
---|
53 | #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \ |
---|
54 | ((channel_index) < EDMA_CHANNELS_PER_MODULE ? \ |
---|
55 | &EDMA_A.TCD[(channel_index)] \ |
---|
56 | : &EDMA_B.TCD[(channel_index) - EDMA_CHANNELS_PER_MODULE]) |
---|
57 | #else |
---|
58 | #error "unsupported module count" |
---|
59 | #endif |
---|
60 | |
---|
61 | /* FIXME: These values are only valid for the MPC5566 and MPC5674F */ |
---|
62 | typedef enum { |
---|
63 | EDMA_EQADC_A_FISR0_CFFF0 = 0, |
---|
64 | EDMA_EQADC_A_FISR0_RFDF0 = 1, |
---|
65 | EDMA_EQADC_A_FISR1_CFFF1 = 2, |
---|
66 | EDMA_EQADC_A_FISR1_RFDF1 = 3, |
---|
67 | EDMA_EQADC_A_FISR2_CFFF2 = 4, |
---|
68 | EDMA_EQADC_A_FISR2_RFDF2 = 5, |
---|
69 | EDMA_EQADC_A_FISR3_CFFF3 = 6, |
---|
70 | EDMA_EQADC_A_FISR3_RFDF3 = 7, |
---|
71 | EDMA_EQADC_A_FISR4_CFFF4 = 8, |
---|
72 | EDMA_EQADC_A_FISR4_RFDF4 = 9, |
---|
73 | EDMA_EQADC_A_FISR5_CFFF5 = 10, |
---|
74 | EDMA_EQADC_A_FISR5_RFDF5 = 11, |
---|
75 | EDMA_DSPI_B_SR_TFFF = 12, |
---|
76 | EDMA_DSPI_B_SR_RFDF = 13, |
---|
77 | EDMA_DSPI_C_SR_TFFF = 14, |
---|
78 | EDMA_DSPI_C_SR_RFDF = 15, |
---|
79 | EDMA_DSPI_D_SR_TFFF = 16, |
---|
80 | EDMA_DSPI_D_SR_RFDF = 17, |
---|
81 | EDMA_ESCI_A_COMBTX = 18, |
---|
82 | EDMA_ESCI_A_COMBRX = 19, |
---|
83 | EDMA_EMIOS_GFR_F0 = 20, |
---|
84 | EDMA_EMIOS_GFR_F1 = 21, |
---|
85 | EDMA_EMIOS_GFR_F2 = 22, |
---|
86 | EDMA_EMIOS_GFR_F3 = 23, |
---|
87 | EDMA_EMIOS_GFR_F4 = 24, |
---|
88 | EDMA_EMIOS_GFR_F8 = 25, |
---|
89 | EDMA_EMIOS_GFR_F9 = 26, |
---|
90 | EDMA_ETPU_CDTRSR_A_DTRS0 = 27, |
---|
91 | EDMA_ETPU_CDTRSR_A_DTRS1 = 28, |
---|
92 | EDMA_ETPU_CDTRSR_A_DTRS2 = 29, |
---|
93 | EDMA_ETPU_CDTRSR_A_DTRS14 = 30, |
---|
94 | EDMA_ETPU_CDTRSR_A_DTRS15 = 31, |
---|
95 | EDMA_DSPI_A_SR_TFFF = 32, |
---|
96 | EDMA_DSPI_A_SR_RFDF = 33, |
---|
97 | EDMA_ESCI_B_COMBTX = 34, |
---|
98 | EDMA_ESCI_B_COMBRX = 35, |
---|
99 | EDMA_EMIOS_GFR_F6 = 36, |
---|
100 | EDMA_EMIOS_GFR_F7 = 37, |
---|
101 | EDMA_EMIOS_GFR_F10 = 38, |
---|
102 | EDMA_EMIOS_GFR_F11 = 39, |
---|
103 | EDMA_EMIOS_GFR_F16 = 40, |
---|
104 | EDMA_EMIOS_GFR_F17 = 41, |
---|
105 | EDMA_EMIOS_GFR_F18 = 42, |
---|
106 | EDMA_EMIOS_GFR_F19 = 43, |
---|
107 | EDMA_ETPU_CDTRSR_A_DTRS12 = 44, |
---|
108 | EDMA_ETPU_CDTRSR_A_DTRS13 = 45, |
---|
109 | EDMA_ETPU_CDTRSR_A_DTRS28 = 46, |
---|
110 | EDMA_ETPU_CDTRSR_A_DTRS29 = 47, |
---|
111 | EDMA_SIU_EISR_EIF0 = 48, |
---|
112 | EDMA_SIU_EISR_EIF1 = 49, |
---|
113 | EDMA_SIU_EISR_EIF2 = 50, |
---|
114 | EDMA_SIU_EISR_EIF3 = 51, |
---|
115 | EDMA_ETPU_CDTRSR_B_DTRS0 = 52, |
---|
116 | EDMA_ETPU_CDTRSR_B_DTRS1 = 53, |
---|
117 | EDMA_ETPU_CDTRSR_B_DTRS2 = 54, |
---|
118 | EDMA_ETPU_CDTRSR_B_DTRS3 = 55, |
---|
119 | EDMA_ETPU_CDTRSR_B_DTRS12 = 56, |
---|
120 | EDMA_ETPU_CDTRSR_B_DTRS13 = 57, |
---|
121 | EDMA_ETPU_CDTRSR_B_DTRS14 = 58, |
---|
122 | EDMA_ETPU_CDTRSR_B_DTRS15 = 59, |
---|
123 | EDMA_ETPU_CDTRSR_B_DTRS28 = 60, |
---|
124 | EDMA_ETPU_CDTRSR_B_DTRS29 = 61, |
---|
125 | EDMA_ETPU_CDTRSR_B_DTRS30 = 62, |
---|
126 | EDMA_ETPU_CDTRSR_B_DTRS31 = 63 |
---|
127 | #if MPC55XX_CHIP_FAMILY == 567 |
---|
128 | , |
---|
129 | EDMA_EQADC_B_FISR0_CFFF0 = 64 + 0, |
---|
130 | EDMA_EQADC_B_FISR0_RFDF0 = 64 + 1, |
---|
131 | EDMA_EQADC_B_FISR1_CFFF1 = 64 + 2, |
---|
132 | EDMA_EQADC_B_FISR1_RFDF1 = 64 + 3, |
---|
133 | EDMA_EQADC_B_FISR2_CFFF2 = 64 + 4, |
---|
134 | EDMA_EQADC_B_FISR2_RFDF2 = 64 + 5, |
---|
135 | EDMA_EQADC_B_FISR3_CFFF3 = 64 + 6, |
---|
136 | EDMA_EQADC_B_FISR3_RFDF3 = 64 + 7, |
---|
137 | EDMA_EQADC_B_FISR4_CFFF4 = 64 + 8, |
---|
138 | EDMA_EQADC_B_FISR4_RFDF4 = 64 + 9, |
---|
139 | EDMA_EQADC_B_FISR5_CFFF5 = 64 + 10, |
---|
140 | EDMA_EQADC_B_FISR5_RFDF5 = 64 + 11, |
---|
141 | EDMA_DECFILTER_A_IB = 64 + 12, |
---|
142 | EDMA_DECFILTER_A_OB = 64 + 13, |
---|
143 | EDMA_DECFILTER_B_IB = 64 + 14, |
---|
144 | EDMA_DECFILTER_B_OB = 64 + 15, |
---|
145 | EDMA_DECFILTER_C_IB = 64 + 16, |
---|
146 | EDMA_DECFILTER_C_OB = 64 + 17, |
---|
147 | EDMA_DECFILTER_D_IB = 64 + 18, |
---|
148 | EDMA_DECFILTER_D_OB = 64 + 19, |
---|
149 | EDMA_DECFILTER_E_IB = 64 + 20, |
---|
150 | EDMA_DECFILTER_E_OB = 64 + 21, |
---|
151 | EDMA_DECFILTER_F_IB = 64 + 22, |
---|
152 | EDMA_DECFILTER_F_OB = 64 + 23, |
---|
153 | EDMA_DECFILTER_G_IB = 64 + 24, |
---|
154 | EDMA_DECFILTER_G_OB = 64 + 25, |
---|
155 | EDMA_DECFILTER_H_IB = 64 + 26, |
---|
156 | EDMA_DECFILTER_H_OB = 64 + 27 |
---|
157 | #endif |
---|
158 | } edma_channel; |
---|
159 | |
---|
160 | typedef struct edma_channel_context { |
---|
161 | rtems_chain_node node; |
---|
162 | volatile struct tcd_t *edma_tcd; |
---|
163 | void (*done)(struct edma_channel_context *, uint32_t); |
---|
164 | } edma_channel_context; |
---|
165 | |
---|
166 | void mpc55xx_edma_init(void); |
---|
167 | |
---|
168 | /** |
---|
169 | * @brief Obtains an eDMA channel. |
---|
170 | * |
---|
171 | * @retval RTEMS_SUCCESSFUL Successful operation. |
---|
172 | * @retval RTEMS_RESOURCE_IN_USE The channel is already in use. |
---|
173 | */ |
---|
174 | rtems_status_code mpc55xx_edma_obtain_channel_by_tcd( |
---|
175 | volatile struct tcd_t *edma_tcd |
---|
176 | ); |
---|
177 | |
---|
178 | void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd); |
---|
179 | |
---|
180 | /** |
---|
181 | * @brief Obtains an eDMA channel and registers the channel context. |
---|
182 | * |
---|
183 | * The done handler of the channel context will be called |
---|
184 | * - during minor or major loop completions if interrupts are enabled in the |
---|
185 | * corresponding TCD, or |
---|
186 | * - in case a channel error occurs. |
---|
187 | * |
---|
188 | * An error status value not equal to zero indicates an error. |
---|
189 | * |
---|
190 | * @retval RTEMS_SUCCESSFUL Successful operation. |
---|
191 | * @retval RTEMS_RESOURCE_IN_USE The channel is already in use. |
---|
192 | * @retval RTEMS_IO_ERROR Unable to install interrupt handler for this channel. |
---|
193 | */ |
---|
194 | rtems_status_code mpc55xx_edma_obtain_channel( |
---|
195 | edma_channel_context *ctx, |
---|
196 | unsigned irq_priority |
---|
197 | ); |
---|
198 | |
---|
199 | void mpc55xx_edma_release_channel(edma_channel_context *ctx); |
---|
200 | |
---|
201 | /** |
---|
202 | * @brief Copies a source TCD to an eDMA TCD. |
---|
203 | * |
---|
204 | * The DONE flag of the eDMA TCD is cleared before the actual copy operation. |
---|
205 | * This enables the setting of channel link or scatter/gather options. |
---|
206 | * |
---|
207 | * This function can be used to start the channel if the START flags is |
---|
208 | * set in the source TCD. |
---|
209 | */ |
---|
210 | void mpc55xx_edma_copy( |
---|
211 | volatile struct tcd_t *edma_tcd, |
---|
212 | const struct tcd_t *source_tcd |
---|
213 | ); |
---|
214 | |
---|
215 | /** |
---|
216 | * @brief Copies a source TCD to an eDMA TCD and enables hardware requests. |
---|
217 | * |
---|
218 | * The DONE flag of the eDMA TCD is cleared before the actual copy operation. |
---|
219 | * This enables the setting of channel link or scatter/gather options. |
---|
220 | */ |
---|
221 | void mpc55xx_edma_copy_and_enable_hardware_requests( |
---|
222 | volatile struct tcd_t *edma_tcd, |
---|
223 | const struct tcd_t *source_tcd |
---|
224 | ); |
---|
225 | |
---|
226 | void mpc55xx_edma_sg_link( |
---|
227 | volatile struct tcd_t *edma_tcd, |
---|
228 | const struct tcd_t *source_tcd |
---|
229 | ); |
---|
230 | |
---|
231 | static inline volatile struct EDMA_tag *mpc55xx_edma_by_tcd( |
---|
232 | volatile struct tcd_t *edma_tcd |
---|
233 | ) |
---|
234 | { |
---|
235 | return (volatile struct EDMA_tag *) |
---|
236 | ((uintptr_t) edma_tcd & ~(uintptr_t) 0x1fff); |
---|
237 | } |
---|
238 | |
---|
239 | static inline unsigned mpc55xx_edma_channel_by_tcd( |
---|
240 | volatile struct tcd_t *edma_tcd |
---|
241 | ) |
---|
242 | { |
---|
243 | volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); |
---|
244 | |
---|
245 | return edma_tcd - &edma->TCD[0]; |
---|
246 | } |
---|
247 | |
---|
248 | static inline void mpc55xx_edma_enable_hardware_requests( |
---|
249 | volatile struct tcd_t *edma_tcd |
---|
250 | ) |
---|
251 | { |
---|
252 | volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); |
---|
253 | unsigned channel = edma_tcd - &edma->TCD[0]; |
---|
254 | |
---|
255 | edma->SERQR.R = (uint8_t) channel; |
---|
256 | } |
---|
257 | |
---|
258 | static inline void mpc55xx_edma_disable_hardware_requests( |
---|
259 | volatile struct tcd_t *edma_tcd |
---|
260 | ) |
---|
261 | { |
---|
262 | volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); |
---|
263 | unsigned channel = edma_tcd - &edma->TCD[0]; |
---|
264 | |
---|
265 | edma->CERQR.R = (uint8_t) channel; |
---|
266 | } |
---|
267 | |
---|
268 | static inline void mpc55xx_edma_enable_error_interrupts( |
---|
269 | volatile struct tcd_t *edma_tcd |
---|
270 | ) |
---|
271 | { |
---|
272 | volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); |
---|
273 | unsigned channel = edma_tcd - &edma->TCD[0]; |
---|
274 | |
---|
275 | edma->SEEIR.R = (uint8_t) channel; |
---|
276 | } |
---|
277 | |
---|
278 | static inline void mpc55xx_edma_disable_error_interrupts( |
---|
279 | volatile struct tcd_t *edma_tcd |
---|
280 | ) |
---|
281 | { |
---|
282 | volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); |
---|
283 | unsigned channel = edma_tcd - &edma->TCD[0]; |
---|
284 | |
---|
285 | edma->CEEIR.R = (uint8_t) channel; |
---|
286 | } |
---|
287 | |
---|
288 | static inline void mpc55xx_edma_set_start( |
---|
289 | volatile struct tcd_t *edma_tcd |
---|
290 | ) |
---|
291 | { |
---|
292 | volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); |
---|
293 | unsigned channel = edma_tcd - &edma->TCD[0]; |
---|
294 | |
---|
295 | edma->SSBR.R = (uint8_t) channel; |
---|
296 | } |
---|
297 | |
---|
298 | static inline void mpc55xx_edma_clear_done( |
---|
299 | volatile struct tcd_t *edma_tcd |
---|
300 | ) |
---|
301 | { |
---|
302 | volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); |
---|
303 | unsigned channel = edma_tcd - &edma->TCD[0]; |
---|
304 | |
---|
305 | edma->CDSBR.R = (uint8_t) channel; |
---|
306 | } |
---|
307 | |
---|
308 | static inline void mpc55xx_edma_clear_interrupts( |
---|
309 | volatile struct tcd_t *edma_tcd |
---|
310 | ) |
---|
311 | { |
---|
312 | volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); |
---|
313 | unsigned channel = edma_tcd - &edma->TCD[0]; |
---|
314 | |
---|
315 | edma->CIRQR.R = (uint8_t) channel; |
---|
316 | } |
---|
317 | |
---|
318 | static inline bool mpc55xx_edma_is_done( |
---|
319 | volatile struct tcd_t *edma_tcd |
---|
320 | ) |
---|
321 | { |
---|
322 | return edma_tcd->BMF.B.DONE; |
---|
323 | } |
---|
324 | |
---|
325 | #ifdef __cplusplus |
---|
326 | } |
---|
327 | #endif /* __cplusplus */ |
---|
328 | |
---|
329 | #endif /* LIBCPU_POWERPC_MPC55XX_EDMA_H */ |
---|