1 /**
2 * \file
3 *
4 * \brief SAM XDMA Controller (DMAC) driver.
5 *
6 * Copyright (c) 2015 Atmel Corporation. All rights reserved.
7 *
8 * \asf_license_start
9 *
10 * \page License
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 *
22 * 3. The name of Atmel may not be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * 4. This software may only be redistributed and used in connection with an
26 * Atmel microcontroller product.
27 *
28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 *
40 * \asf_license_stop
41 *
42 */
43 /*
44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45 */
46
47 #ifndef XDMAC_H_INCLUDED
48 #define XDMAC_H_INCLUDED
49
50 /**
51 * \defgroup asfdoc_sam_drivers_xdmac_group SAMV71/V70/E70/S70 XDMA Controller (XDMAC) Driver
52 *
53 * This driver for Atmel® | SMART SAM XDMA Controller (XDMAC) is a AHB-protocol central
54 * direct memory access controller. It performs peripheral data transfer and memory move operations
55 * over one or two bus ports through the unidirectional communication channel.
56 * This is a driver for the configuration, enabling, disabling, and use of the XDMAC peripheral.
57 *
58 * Devices from the following series can use this module:
59 * - Atmel | SMART SAMV71
60 * - Atmel | SMART SAMV70
61 * - Atmel | SMART SAMS70
62 * - Atmel | SMART SAME70
63 *
64 * The outline of this documentation is as follows:
65 * - \ref asfdoc_sam_drivers_xdmac_prerequisites
66 * - \ref asfdoc_sam_drivers_xdmac_module_overview
67 * - \ref asfdoc_sam_drivers_xdmac_special_considerations
68 * - \ref asfdoc_sam_drivers_xdmac_extra_info
69 * - \ref asfdoc_sam_drivers_xdmac_examples
70 * - \ref asfdoc_sam_drivers_xdmac_api_overview
71 *
72 *
73 * \section asfdoc_sam_drivers_xdmac_prerequisites Prerequisites
74 *
75 * There are no prerequisites for this module.
76 *
77 *
78 * \section asfdoc_sam_drivers_xdmac_module_overview Module Overview
79 * The DMA Controller (XDMAC) is a AHB-protocol central direct memory access controller.
80 * It performs peripheral data transfer and memory move operations over one or two bus ports
81 * through the unidirectional communication channel. Each channel is fully programmable and
82 * provides both peripheral or memory to memory transfer. The channel features are configurable
83 * at implementation time.
84 *
85 *
86 * \section asfdoc_sam_drivers_xdmac_special_considerations Special Considerations
87 * There are no special considerations for this module.
88 *
89 *
90 * \section asfdoc_sam_drivers_xdmac_extra_info Extra Information
91 *
92 * For extra information, see \ref asfdoc_sam_drivers_xdmac_extra. This includes:
93 * - \ref asfdoc_sam_drivers_xdmac_extra_acronyms
94 * - \ref asfdoc_sam_drivers_xdmac_extra_dependencies
95 * - \ref asfdoc_sam_drivers_xdmac_extra_errata
96 * - \ref asfdoc_sam_drivers_xdmac_extra_history
97 *
98 * \section asfdoc_sam_drivers_xdmac_examples Examples
99 *
100 * For a list of examples related to this driver, see
101 * \ref asfdoc_sam_drivers_xdmac_exqsg.
102 *
103 *
104 * \section asfdoc_sam_drivers_xdmac_api_overview API Overview
105 * @{
106 */
107
108 #include <compiler.h>
109 #include <status_codes.h>
110
111 /** @cond */
112 /**INDENT-OFF**/
113 #ifdef __cplusplus
114 extern "C" {
115 #endif
116 /**INDENT-ON**/
117 /** @endcond */
118
119 /** DMA channel hardware interface number */
120 #define XDAMC_CHANNEL_HWID_HSMCI 0
121 #define XDAMC_CHANNEL_HWID_SPI0_TX 1
122 #define XDAMC_CHANNEL_HWID_SPI0_RX 2
123 #define XDAMC_CHANNEL_HWID_SPI1_TX 3
124 #define XDAMC_CHANNEL_HWID_SPI1_RX 4
125 #define XDAMC_CHANNEL_HWID_QSPI_TX 5
126 #define XDAMC_CHANNEL_HWID_QSPI_RX 6
127 #define XDAMC_CHANNEL_HWID_USART0_TX 7
128 #define XDAMC_CHANNEL_HWID_USART0_RX 8
129 #define XDAMC_CHANNEL_HWID_USART1_TX 9
130 #define XDAMC_CHANNEL_HWID_USART1_RX 10
131 #define XDAMC_CHANNEL_HWID_USART2_TX 11
132 #define XDAMC_CHANNEL_HWID_USART2_RX 12
133 #define XDAMC_CHANNEL_HWID_PWM0 13
134 #define XDAMC_CHANNEL_HWID_TWIHS0_TX 14
135 #define XDAMC_CHANNEL_HWID_TWIHS0_RX 15
136 #define XDAMC_CHANNEL_HWID_TWIHS1_TX 16
137 #define XDAMC_CHANNEL_HWID_TWIHS1_RX 17
138 #define XDAMC_CHANNEL_HWID_TWIHS2_TX 18
139 #define XDAMC_CHANNEL_HWID_TWIHS2_RX 19
140 #define XDAMC_CHANNEL_HWID_UART0_TX 20
141 #define XDAMC_CHANNEL_HWID_UART0_RX 21
142 #define XDAMC_CHANNEL_HWID_UART1_TX 22
143 #define XDAMC_CHANNEL_HWID_UART1_RX 23
144 #define XDAMC_CHANNEL_HWID_UART2_TX 24
145 #define XDAMC_CHANNEL_HWID_UART2_RX 25
146 #define XDAMC_CHANNEL_HWID_UART3_TX 26
147 #define XDAMC_CHANNEL_HWID_UART3_RX 27
148 #define XDAMC_CHANNEL_HWID_UART4_TX 28
149 #define XDAMC_CHANNEL_HWID_UART4_RX 29
150 #define XDAMC_CHANNEL_HWID_DAC 30
151 #define XDAMC_CHANNEL_HWID_SSC_TX 32
152 #define XDAMC_CHANNEL_HWID_SSC_RX 33
153 #define XDAMC_CHANNEL_HWID_PIOA 34
154 #define XDAMC_CHANNEL_HWID_AFEC0 35
155 #define XDAMC_CHANNEL_HWID_AFEC1 36
156 #define XDAMC_CHANNEL_HWID_AES_TX 37
157 #define XDAMC_CHANNEL_HWID_AES_RX 38
158 #define XDAMC_CHANNEL_HWID_PWM1 39
159 #define XDAMC_CHANNEL_HWID_TC0 40
160 #define XDAMC_CHANNEL_HWID_TC1 41
161 #define XDAMC_CHANNEL_HWID_TC2 42
162 #define XDAMC_CHANNEL_HWID_TC3 43
163
164 /* XDMA_MBR_UBC */
165 #define XDMAC_UBC_NDE (0x1u << 24)
166 #define XDMAC_UBC_NDE_FETCH_DIS (0x0u << 24)
167 #define XDMAC_UBC_NDE_FETCH_EN (0x1u << 24)
168 #define XDMAC_UBC_NSEN (0x1u << 25)
169 #define XDMAC_UBC_NSEN_UNCHANGED (0x0u << 25)
170 #define XDMAC_UBC_NSEN_UPDATED (0x1u << 25)
171 #define XDMAC_UBC_NDEN (0x1u << 26)
172 #define XDMAC_UBC_NDEN_UNCHANGED (0x0u << 26)
173 #define XDMAC_UBC_NDEN_UPDATED (0x1u << 26)
174 #define XDMAC_UBC_NVIEW_Pos 27
175 #define XDMAC_UBC_NVIEW_Msk (0x3u << XDMAC_UBC_NVIEW_Pos)
176 #define XDMAC_UBC_NVIEW_NDV0 (0x0u << XDMAC_UBC_NVIEW_Pos)
177 #define XDMAC_UBC_NVIEW_NDV1 (0x1u << XDMAC_UBC_NVIEW_Pos)
178 #define XDMAC_UBC_NVIEW_NDV2 (0x2u << XDMAC_UBC_NVIEW_Pos)
179 #define XDMAC_UBC_NVIEW_NDV3 (0x3u << XDMAC_UBC_NVIEW_Pos)
180 #define XDMAC_UBC_UBLEN_Pos 0
181 #define XDMAC_UBC_UBLEN_Msk (0xffffffu << XDMAC_UBC_UBLEN_Pos)
182 #define XDMAC_UBC_UBLEN(value) ((XDMAC_UBC_UBLEN_Msk & ((value) << XDMAC_UBC_UBLEN_Pos)))
183
184 /** XDMA config register for channel */
185 typedef struct {
186 /** Microblock Control Member. */
187 uint32_t mbr_ubc;
188 /** Source Address Member. */
189 uint32_t mbr_sa;
190 /** Destination Address Member. */
191 uint32_t mbr_da;
192 /** Configuration Register. */
193 uint32_t mbr_cfg;
194 /** Block Control Member. */
195 uint32_t mbr_bc;
196 /** Data Stride Member. */
197 uint32_t mbr_ds;
198 /** Source Microblock Stride Member. */
199 uint32_t mbr_sus;
200 /** Destination Microblock Stride Member. */
201 uint32_t mbr_dus;
202 } xdmac_channel_config_t;
203
204 /**
205 * \brief Structure for storing parameters for DMA view0 that can be
206 * performed by the DMA Master transfer.
207 */
208 typedef struct {
209 /** Next Descriptor Address number. */
210 uint32_t mbr_nda;
211 /** Microblock Control Member. */
212 uint32_t mbr_ubc;
213 /** Destination Address Member. */
214 uint32_t mbr_da;
215 } lld_view0;
216
217 /**
218 * \brief Structure for storing parameters for DMA view1 that can be
219 * performed by the DMA Master transfer.
220 */
221 typedef struct {
222 /** Next Descriptor Address number. */
223 uint32_t mbr_nda;
224 /** Microblock Control Member. */
225 uint32_t mbr_ubc;
226 /** Source Address Member. */
227 uint32_t mbr_sa;
228 /** Destination Address Member. */
229 uint32_t mbr_da;
230 } lld_view1;
231
232 /**
233 * \brief Structure for storing parameters for DMA view2 that can be
234 * performed by the DMA Master transfer.
235 */
236 typedef struct {
237 /** Next Descriptor Address number. */
238 uint32_t mbr_nda;
239 /** Microblock Control Member. */
240 uint32_t mbr_ubc;
241 /** Source Address Member. */
242 uint32_t mbr_sa;
243 /** Destination Address Member. */
244 uint32_t mbr_da;
245 /** Configuration Register. */
246 uint32_t mbr_cfg;
247 } lld_view2;
248
249 /**
250 * \brief Structure for storing parameters for DMA view3 that can be
251 * performed by the DMA Master transfer.
252 */
253 typedef struct {
254 /** Next Descriptor Address number. */
255 uint32_t mbr_nda;
256 /** Microblock Control Member. */
257 uint32_t mbr_ubc;
258 /** Source Address Member. */
259 uint32_t mbr_sa;
260 /** Destination Address Member. */
261 uint32_t mbr_da;
262 /** Configuration Register. */
263 uint32_t mbr_cfg;
264 /** Block Control Member. */
265 uint32_t mbr_bc;
266 /** Data Stride Member. */
267 uint32_t mbr_ds;
268 /** Source Microblock Stride Member. */
269 uint32_t mbr_sus;
270 /** Destination Microblock Stride Member. */
271 uint32_t mbr_dus;
272 } lld_view3;
273
274 /**
275 * \brief Get XDMAC global type.
276 *
277 * \param[out] xdmac Module hardware register base address pointer.
278 */
xdmac_get_type(Xdmac * xdmac)279 static inline uint32_t xdmac_get_type( Xdmac *xdmac)
280 {
281 Assert(xdmac);
282 return xdmac->XDMAC_GTYPE;
283 }
284
285 /**
286 * \brief Get XDMAC global configuration.
287 *
288 * \param[out] xdmac Module hardware register base address pointer.
289 */
xdmac_get_config(Xdmac * xdmac)290 static inline uint32_t xdmac_get_config(Xdmac *xdmac)
291 {
292 Assert(xdmac);
293 return xdmac->XDMAC_GCFG;
294 }
295
296 /**
297 * \brief Get XDMAC global weighted arbiter configuration.
298 *
299 * \param[out] xdmac Module hardware register base address pointer.
300 */
xdmac_get_arbiter(Xdmac * xdmac)301 static inline uint32_t xdmac_get_arbiter(Xdmac *xdmac)
302 {
303 Assert(xdmac);
304 return xdmac->XDMAC_GWAC;
305 }
306
307 /**
308 * \brief Enables XDMAC global interrupt.
309 *
310 * \param[out] xdmac Module hardware register base address pointer.
311 * \param[in] mask A bitmask of channels to be enabled interrupt.
312 */
xdmac_enable_interrupt(Xdmac * xdmac,uint32_t mask)313 static inline void xdmac_enable_interrupt(Xdmac *xdmac, uint32_t mask)
314 {
315 Assert(xdmac);
316 xdmac->XDMAC_GIE = ( XDMAC_GIE_IE0 << mask) ;
317 }
318
319 /**
320 * \brief Disables XDMAC global interrupt
321 *
322 * \param[out] xdmac Module hardware register base address pointer.
323 * \param[in] mask A bitmask of channels to be disabled interrupt.
324 */
xdmac_disable_interrupt(Xdmac * xdmac,uint32_t mask)325 static inline void xdmac_disable_interrupt(Xdmac *xdmac, uint32_t mask)
326 {
327 Assert(xdmac);
328 xdmac->XDMAC_GID = (XDMAC_GID_ID0 << mask);
329 }
330
331 /**
332 * \brief Get XDMAC global interrupt mask.
333 *
334 * \param[out] xdmac Module hardware register base address pointer.
335 */
xdmac_get_interrupt_mask(Xdmac * xdmac)336 static inline uint32_t xdmac_get_interrupt_mask(Xdmac *xdmac)
337 {
338 Assert(xdmac);
339 return (xdmac->XDMAC_GIM);
340 }
341
342 /**
343 * \brief Get XDMAC global interrupt status.
344 *
345 * \param[out] xdmac Module hardware register base address pointer.
346 */
xdmac_get_interrupt_status(Xdmac * xdmac)347 static inline uint32_t xdmac_get_interrupt_status(Xdmac *xdmac)
348 {
349 Assert(xdmac);
350 return (xdmac->XDMAC_GIS);
351 }
352
353 /**
354 * \brief enables the relevant channel of given XDMAC.
355 *
356 * \param[out] xdmac Module hardware register base address pointer.
357 * \param[in] channel_num XDMA Channel number (range 0 to 23)
358 */
xdmac_channel_enable(Xdmac * xdmac,uint32_t channel_num)359 static inline void xdmac_channel_enable(Xdmac *xdmac, uint32_t channel_num)
360 {
361 Assert(xdmac);
362 Assert(channel_num < XDMACCHID_NUMBER);
363 xdmac->XDMAC_GE = (XDMAC_GE_EN0 << channel_num);
364 }
365
366 /**
367 * \brief Disables the relevant channel of given XDMAC.
368 *
369 * \param[out] xdmac Module hardware register base address pointer.
370 * \param[in] channel_num XDMA Channel number (range 0 to 23)
371 */
xdmac_channel_disable(Xdmac * xdmac,uint32_t channel_num)372 static inline void xdmac_channel_disable(Xdmac *xdmac, uint32_t channel_num)
373 {
374 Assert(xdmac);
375 Assert(channel_num < XDMACCHID_NUMBER);
376 xdmac->XDMAC_GD =(XDMAC_GD_DI0 << channel_num);
377 }
378
379 /**
380 * \brief Get Global channel status of given XDMAC.
381 * \note: When set to 1, this bit indicates that the channel x is enabled.
382 If a channel disable request is issued, this bit remains asserted
383 until pending transaction is completed.
384 * \param[out] xdmac Module hardware register base address pointer.
385 */
xdmac_channel_get_status(Xdmac * xdmac)386 static inline uint32_t xdmac_channel_get_status(Xdmac *xdmac)
387 {
388 Assert(xdmac);
389 return xdmac->XDMAC_GS;
390 }
391
392 /**
393 * \brief Suspend the relevant channel's read.
394 *
395 * \param[out] xdmac Module hardware register base address pointer.
396 * \param[in] channel_num XDMA Channel number (range 0 to 23).
397 */
xdmac_channel_read_suspend(Xdmac * xdmac,uint32_t channel_num)398 static inline void xdmac_channel_read_suspend(Xdmac *xdmac, uint32_t channel_num)
399 {
400 Assert(xdmac);
401 Assert(channel_num < XDMACCHID_NUMBER);
402 xdmac->XDMAC_GRS |= XDMAC_GRS_RS0 << channel_num;
403 }
404
405 /**
406 * \brief Suspend the relevant channel's write.
407 *
408 * \param[out] xdmac Module hardware register base address pointer.
409 * \param[in] channel_num XDMA Channel number (range 0 to 23).
410 */
xdmac_channel_write_suspend(Xdmac * xdmac,uint32_t channel_num)411 static inline void xdmac_channel_write_suspend(Xdmac *xdmac, uint32_t channel_num)
412 {
413 Assert(xdmac);
414 Assert(channel_num < XDMACCHID_NUMBER);
415 xdmac->XDMAC_GWS |= XDMAC_GWS_WS0 << channel_num;
416 }
417
418 /**
419 * \brief Suspend the relevant channel's read & write.
420 *
421 * \param[out] xdmac Module hardware register base address pointer.
422 * \param[in] channel_num XDMA Channel number (range 0 to 23).
423 */
xdmac_channel_readwrite_suspend(Xdmac * xdmac,uint32_t channel_num)424 static inline void xdmac_channel_readwrite_suspend(Xdmac *xdmac, uint32_t channel_num)
425 {
426 Assert(xdmac);
427 Assert(channel_num < XDMACCHID_NUMBER);
428 xdmac->XDMAC_GRWS = (XDMAC_GRWS_RWS0 << channel_num);
429 }
430
431 /**
432 * \brief Resume the relevant channel's read & write.
433 *
434 * \param[out] xdmac Module hardware register base address pointer.
435 * \param[in] channel_num XDMA Channel number (range 0 to 23).
436 */
xdmac_channel_readwrite_resume(Xdmac * xdmac,uint32_t channel_num)437 static inline void xdmac_channel_readwrite_resume(Xdmac *xdmac, uint32_t channel_num)
438 {
439 Assert(xdmac);
440 Assert(channel_num < XDMACCHID_NUMBER);
441 xdmac->XDMAC_GRWR = (XDMAC_GRWR_RWR0 << channel_num);
442 }
443
444 /**
445 * \brief Set software transfer request on the relevant channel.
446 *
447 * \param[out] xdmac Module hardware register base address pointer.
448 * \param[in] channel_num XDMA Channel number (range 0 to 23).
449 */
xdmac_channel_software_request(Xdmac * xdmac,uint32_t channel_num)450 static inline void xdmac_channel_software_request(Xdmac *xdmac, uint32_t channel_num)
451 {
452 Assert(xdmac);
453 Assert(channel_num < XDMACCHID_NUMBER);
454 xdmac->XDMAC_GSWR = (XDMAC_GSWR_SWREQ0 << channel_num);
455 }
456
457 /**
458 * \brief Get software transfer status of the relevant channel.
459 *
460 * \param[out] xdmac Module hardware register base address pointer.
461 */
xdmac_get_software_request_status(Xdmac * xdmac)462 static inline uint32_t xdmac_get_software_request_status(Xdmac *xdmac)
463 {
464 Assert(xdmac);
465 return xdmac->XDMAC_GSWS;
466 }
467
468 /**
469 * \brief Enable interrupt with mask on the relevant channel of given XDMA.
470 *
471 * \param[out] xdmac Module hardware register base address pointer.
472 * \param[in] channel_num XDMA Channel number (range 0 to 23).
473 * \param[in] mask Interrupt mask.
474 */
xdmac_channel_enable_interrupt(Xdmac * xdmac,uint32_t channel_num,uint32_t mask)475 static inline void xdmac_channel_enable_interrupt(Xdmac *xdmac, uint32_t channel_num, uint32_t mask)
476 {
477 Assert(xdmac);
478 Assert(channel_num < XDMACCHID_NUMBER);
479 xdmac->XDMAC_CHID[channel_num].XDMAC_CIE = mask;
480 }
481
482 /**
483 * \brief Disable interrupt with mask on the relevant channel of given XDMA.
484 *
485 * \param[out] xdmac Module hardware register base address pointer.
486 * \param[in] channel_num XDMA Channel number (range 0 to 23).
487 * \param[in] mask Interrupt mask.
488 */
xdmac_channel_disable_interrupt(Xdmac * xdmac,uint32_t channel_num,uint32_t mask)489 static inline void xdmac_channel_disable_interrupt(Xdmac *xdmac, uint32_t channel_num, uint32_t mask)
490 {
491 Assert(xdmac);
492 Assert(channel_num < XDMACCHID_NUMBER);
493 xdmac->XDMAC_CHID[channel_num].XDMAC_CID = mask;
494 }
495
496 /**
497 * \brief Get interrupt mask for the relevant channel of given XDMA.
498 *
499 * \param[out] xdmac Module hardware register base address pointer.
500 * \param[in] channel_num XDMA Channel number (range 0 to 23).
501 */
xdmac_channel_get_interrupt_mask(Xdmac * xdmac,uint32_t channel_num)502 static inline uint32_t xdmac_channel_get_interrupt_mask(Xdmac *xdmac, uint32_t channel_num)
503 {
504 Assert(xdmac);
505 Assert(channel_num < XDMACCHID_NUMBER);
506 return xdmac->XDMAC_CHID[channel_num].XDMAC_CIM;
507 }
508
509 /**
510 * \brief Get interrupt status for the relevant channel of given XDMA.
511 *
512 * \param[out] xdmac Module hardware register base address pointer.
513 * \param[in] channel_num XDMA Channel number (range 0 to 23).
514 */
xdmac_channel_get_interrupt_status(Xdmac * xdmac,uint32_t channel_num)515 static inline uint32_t xdmac_channel_get_interrupt_status(Xdmac *xdmac, uint32_t channel_num)
516 {
517 Assert(xdmac);
518 Assert(channel_num < XDMACCHID_NUMBER);
519 return xdmac->XDMAC_CHID[channel_num].XDMAC_CIS;
520 }
521
522 /**
523 * \brief Set software flush request on the relevant channel.
524 *
525 * \param[out] xdmac Module hardware register base address pointer.
526 * \param[in] channel_num XDMA Channel number (range 0 to 23).
527 */
xdmac_channel_software_flush_request(Xdmac * xdmac,uint32_t channel_num)528 static inline void xdmac_channel_software_flush_request(Xdmac *xdmac, uint32_t channel_num)
529 {
530 Assert(xdmac);
531 Assert(channel_num < XDMACCHID_NUMBER);
532 xdmac->XDMAC_GSWF = (XDMAC_GSWF_SWF0 << channel_num);
533 while( !(xdmac_channel_get_interrupt_status(xdmac, channel_num) & XDMAC_CIS_FIS) );
534 }
535
536 /**
537 * \brief Set source address for the relevant channel of given XDMA.
538 *
539 * \param[out] xdmac Module hardware register base address pointer
540 * \param[in] channel_num DMA Channel number (range 0 to 23)
541 * \param[in] src_addr Source address
542 */
xdmac_channel_set_source_addr(Xdmac * xdmac,uint32_t channel_num,uint32_t src_addr)543 static inline void xdmac_channel_set_source_addr(Xdmac *xdmac, uint32_t channel_num, uint32_t src_addr)
544 {
545 Assert(xdmac);
546 Assert(channel_num < XDMACCHID_NUMBER);
547 xdmac->XDMAC_CHID[channel_num].XDMAC_CSA = src_addr;
548 }
549
550 /**
551 * \brief Set destination address for the relevant channel of given XDMA.
552 *
553 * \param[out] xdmac Module hardware register base address pointer
554 * \param[in] channel_num DMA Channel number (range 0 to 23)
555 * \param[in] dst_addr Destination address
556 */
xdmac_channel_set_destination_addr(Xdmac * xdmac,uint32_t channel_num,uint32_t dst_addr)557 static inline void xdmac_channel_set_destination_addr(Xdmac *xdmac, uint32_t channel_num, uint32_t dst_addr)
558 {
559 Assert(xdmac);
560 Assert(channel_num < XDMACCHID_NUMBER);
561 xdmac->XDMAC_CHID[channel_num].XDMAC_CDA = dst_addr;
562 }
563
564 /**
565 * \brief Set next descriptor's address & interface for the relevant channel of given XDMA.
566 *
567 * \param[out] xdmac Module hardware register base address pointer
568 * \param[in] channel_num DMA Channel number (range 0 to 23)
569 * \param[in] desc_addr Address of next descriptor.
570 * \param[in] ndaif Interface of next descriptor.
571 */
xdmac_channel_set_descriptor_addr(Xdmac * xdmac,uint32_t channel_num,uint32_t desc_addr,uint8_t ndaif)572 static inline void xdmac_channel_set_descriptor_addr(Xdmac *xdmac, uint32_t channel_num,
573 uint32_t desc_addr, uint8_t ndaif)
574 {
575 Assert(xdmac);
576 Assert(channel_num < XDMACCHID_NUMBER);
577 Assert(ndaif<2);
578 xdmac->XDMAC_CHID[channel_num].XDMAC_CNDA = (desc_addr & 0xFFFFFFFC) | ndaif;
579 }
580
581 /**
582 * \brief Set next descriptor's configuration for the relevant channel of given XDMA.
583 *
584 * \param[out] xdmac Module hardware register base address pointer
585 * \param[in] channel_num DMA Channel number (range 0 to 23)
586 * \param[in] config Configuration of next descriptor.
587 */
xdmac_channel_set_descriptor_control(Xdmac * xdmac,uint32_t channel_num,uint32_t config)588 static inline void xdmac_channel_set_descriptor_control(Xdmac *xdmac, uint32_t channel_num, uint32_t config)
589 {
590 Assert(xdmac);
591 Assert(channel_num < XDMACCHID_NUMBER);
592 xdmac->XDMAC_CHID[channel_num].XDMAC_CNDC = config;
593 }
594
595 /**
596 * \brief Set microblock length for the relevant channel of given XDMA.
597 *
598 * \param[out] xdmac Module hardware register base address pointer
599 * \param[in] channel_num DMA Channel number (range 0 to 23)
600 * \param[in] ublen Microblock length.
601 */
xdmac_channel_set_microblock_control(Xdmac * xdmac,uint32_t channel_num,uint32_t ublen)602 static inline void xdmac_channel_set_microblock_control(Xdmac *xdmac, uint32_t channel_num, uint32_t ublen)
603 {
604 Assert(xdmac);
605 Assert(channel_num < XDMACCHID_NUMBER);
606 xdmac->XDMAC_CHID[channel_num].XDMAC_CUBC = XDMAC_CUBC_UBLEN(ublen);
607 }
608
609 /**
610 * \brief Set block length for the relevant channel of given XDMA.
611 *
612 * \param[out] xdmac Module hardware register base address pointer
613 * \param[in] channel_num XDMA Channel number (range 0 to 23)
614 * \param[in] blen Block length.
615 */
xdmac_channel_set_block_control(Xdmac * xdmac,uint32_t channel_num,uint32_t blen)616 static inline void xdmac_channel_set_block_control(Xdmac *xdmac, uint32_t channel_num, uint32_t blen)
617 {
618 Assert(xdmac);
619 Assert(channel_num < XDMACCHID_NUMBER);
620 xdmac->XDMAC_CHID[channel_num].XDMAC_CBC = XDMAC_CBC_BLEN(blen);
621 }
622
623 /**
624 * \brief Set configuration for the relevant channel of given XDMA.
625 *
626 * \param[out] xdmac Module hardware register base address pointer
627 * \param[in] channel_num XDMA Channel number (range 0 to 23)
628 * \param[in] config Channel configuration.
629 */
xdmac_channel_set_config(Xdmac * xdmac,uint32_t channel_num,uint32_t config)630 static inline void xdmac_channel_set_config(Xdmac *xdmac, uint32_t channel_num, uint32_t config)
631 {
632 Assert(xdmac);
633 Assert(channel_num < XDMACCHID_NUMBER);
634 xdmac->XDMAC_CHID[channel_num].XDMAC_CC = config;
635 }
636
637 /**
638 * \brief Set the relevant channel's data stride memory pattern of given XDMA.
639 *
640 * \param[out] xdmac Module hardware register base address pointer
641 * \param[in] channel_num XDMA Channel number (range 0 to 23)
642 * \param[in] dds_msp Data stride memory pattern.
643 */
xdmac_channel_set_datastride_mempattern(Xdmac * xdmac,uint32_t channel_num,uint32_t dds_msp)644 static inline void xdmac_channel_set_datastride_mempattern(Xdmac *xdmac, uint32_t channel_num, uint32_t dds_msp)
645 {
646 Assert(xdmac);
647 Assert(channel_num < XDMACCHID_NUMBER);
648 xdmac->XDMAC_CHID[channel_num].XDMAC_CDS_MSP = dds_msp;
649 }
650
651 /**
652 * \brief Set the relevant channel's source microblock stride of given XDMA.
653 *
654 * \param[out] xdmac Module hardware register base address pointer
655 * \param[in] channel_num XDMA Channel number (range 0 to 23)
656 * \param[in] subs Source microblock stride.
657 */
xdmac_channel_set_source_microblock_stride(Xdmac * xdmac,uint32_t channel_num,uint32_t subs)658 static inline void xdmac_channel_set_source_microblock_stride(Xdmac *xdmac,
659 uint32_t channel_num, uint32_t subs)
660 {
661 Assert(xdmac);
662 Assert(channel_num < XDMACCHID_NUMBER);
663 xdmac->XDMAC_CHID[channel_num].XDMAC_CSUS = XDMAC_CSUS_SUBS(subs);
664 }
665
666 /**
667 * \brief Set the relevant channel's destination microblock stride of given XDMA.
668 *
669 * \param[out] xdmac Module hardware register base address pointer
670 * \param[in] channel_num XDMA Channel number (range 0 to 23)
671 * \param[in] dubs Destination microblock stride.
672 */
xdmac_channel_set_destination_microblock_stride(Xdmac * xdmac,uint32_t channel_num,uint32_t dubs)673 static inline void xdmac_channel_set_destination_microblock_stride(Xdmac *xdmac,
674 uint32_t channel_num, uint32_t dubs)
675 {
676 Assert(xdmac);
677 Assert(channel_num < XDMACCHID_NUMBER);
678 xdmac->XDMAC_CHID[channel_num].XDMAC_CDUS = XDMAC_CDUS_DUBS(dubs);
679 }
680
681 void xdmac_configure_transfer(Xdmac *xdmac, uint32_t channel_num,
682 xdmac_channel_config_t *p_cfg);
683
684 /** @cond */
685 /**INDENT-OFF**/
686 #ifdef __cplusplus
687 }
688 #endif
689 /**INDENT-ON**/
690 /** @endcond */
691
692 /** @} */
693
694 /**
695 * \page asfdoc_sam_drivers_xdmac_extra Extra Information for Extensible Direct Memory Access Controller Driver
696 *
697 * \section asfdoc_sam_drivers_xdmac_extra_acronyms Acronyms
698 * Below is a table listing the acronyms used in this module, along with their
699 * intended meanings.
700 *
701 * <table>
702 * <tr>
703 * <th>Acronym</th>
704 * <th>Definition</th>
705 * </tr>
706 * <tr>
707 * <td>AHB</td>
708 * <td>AMBA High-performance Bus</td>
709 * </tr>
710 * <tr>
711 * <td>AMBA</td>
712 * <td>Advanced Microcontroller Bus Architecture</td>
713 * </tr>
714 * <tr>
715 * <td>FIFO</td>
716 * <td>First In First Out</td>
717 * </tr>
718 * <tr>
719 * <td>LLD</td>
720 * <td>Linked List Descriptor</td>
721 * </tr>
722 * <tr>
723 * <td>QSG</td>
724 * <td>Quick Start Guide</td>
725 * </tr>
726 * </table>
727 *
728 *
729 * \section asfdoc_sam_drivers_xdmac_extra_dependencies Dependencies
730 * This driver has the following dependencies:
731 *
732 * - None
733 *
734 *
735 * \section asfdoc_sam_drivers_xdmac_extra_errata Errata
736 * There are no errata related to this driver.
737 *
738 *
739 * \section asfdoc_sam_drivers_xdmac_extra_history Module History
740 * An overview of the module history is presented in the table below, with
741 * details on the enhancements and fixes made to the module since its first
742 * release. The current version of this corresponds to the newest version in
743 * the table.
744 *
745 * <table>
746 * <tr>
747 * <th>Changelog</th>
748 * </tr>
749 * <tr>
750 * <td>Initial document release</td>
751 * </tr>
752 * </table>
753 */
754
755 /**
756 * \page asfdoc_sam_drivers_xdmac_exqsg Examples for Direct Memory Access Controller Driver
757 *
758 * This is a list of the available Quick Start Guides (QSGs) and example
759 * applications for \ref asfdoc_sam_drivers_xdmac_group. QSGs are simple examples with
760 * step-by-step instructions to configure and use this driver in a selection of
761 * use cases. Note that QSGs can be compiled as a standalone application or be
762 * added to the user application.
763 *
764 * - \subpage asfdoc_sam_drivers_xdmac_qsg
765 * - \subpage asfdoc_sam_drivers_xdmac_example
766 *
767 * \page asfdoc_sam_drivers_xdmac_document_revision_history Document Revision History
768 *
769 * <table>
770 * <tr>
771 * <th>Doc. Rev.</td>
772 * <th>Date</td>
773 * <th>Comments</td>
774 * </tr>
775 * <tr>
776 * <td>XXXXXA</td>
777 * <td>08/2015</td>
778 * <td>Initial document release</td>
779 * </tr>
780 * </table>
781 *
782 */
783
784 /**
785 * \page asfdoc_sam_drivers_xdmac_qsg Quick Start Guide for the XDMAC driver
786 *
787 * This is the quick start guide for the \ref asfdoc_sam_drivers_xdmac_group, with
788 * step-by-step instructions on how to configure and use the driver for
789 * a specific use case.The code examples can be copied into e.g the main
790 * application loop or any other function that will need to control the
791 * XDMAC module.
792 *
793 * \section asfdoc_sam_drivers_xdmac_qsg_use_cases Use Cases
794 * - \ref asfdoc_sam_drivers_xdmac_qsg_basic
795 *
796 * \section asfdoc_sam_drivers_xdmac_qsg_basic XDMAC Basic Usage
797 *
798 * This use case will demonstrate how to config the XDMAC module to
799 * perform a single memory to memory transfer.
800 *
801 *
802 * \section asfdoc_sam_drivers_xdmac_qsg_basic_setup Setup Steps
803 *
804 * \subsection asfdoc_sam_drivers_xdmac_qsg_basic_prereq Prerequisites
805 *
806 * This module requires the following service
807 * - \ref clk_group "System Clock Management (sysclock)"
808 *
809 * \subsection asfdoc_sam_drivers_xdmac_qsg_basic_setup_code Setup Code
810 *
811 * Add these macros and global variable to the top of your application's C-file:
812 * \snippet xdmac_example.c xdmac_define_channel
813 * \snippet xdmac_example.c xdmac_define_buffer
814 *
815 * Add this to the main loop or a setup function:
816 * \snippet xdmac_example.c xdmac_configure_transfer
817 *
818 * \subsection asfdoc_sam_drivers_xdmac_qsg_basic_setup_workflow Workflow
819 *
820 * -# Configure XDMAC transfer:
821 * \snippet xdmac_example.c xdmac_configure_transfer
822 * -# Enable the XDMAC interrupt:
823 * \snippet xdmac_example.c xdmac_enable_interrupt
824 * \snippet xdmac_example.c xdmac_channel_enable_interrupt
825 * -# Eanble the channel:
826 * \snippet xdmac_example.c xdmac_channel_enable
827 *
828 */
829
830 #endif /* XDMAC_H_INCLUDED */
831