1 /**
2 * \file
3 *
4 * \brief Direct Memory Access Controller Driver for SAMB
5 *
6 * Copyright (C) 2015-2016 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 #ifndef DMA_H_INCLUDED
47 #define DMA_H_INCLUDED
48
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52
53 /**
54 * \defgroup asfdoc_samb_dma_group SAM Direct Memory Access Controller Driver (DMAC)
55 *
56 * This driver for Atmel® | SMART SAM devices provides an interface for the configuration
57 * and management of the Direct Memory Access Controller(DMAC) module within
58 * the device. The DMAC can transfer data between memories and peripherals, and
59 * thus off-load these tasks from the CPU. The module supports peripheral to
60 * peripheral, peripheral to memory, memory to peripheral, and memory to memory
61 * transfers.
62 *
63 * The following peripherals are used by the DMAC Driver:
64 * - DMAC (Direct Memory Access Controller)
65 *
66 * The following devices can use this module:
67 * - Atmel | SMART SAM B11
68 *
69 * The outline of this documentation is as follows:
70 * - \ref asfdoc_samb_dma_prerequisites
71 * - \ref asfdoc_samb_dma_module_overview
72 * - \ref asfdoc_samb_dma_special_considerations
73 * - \ref asfdoc_samb_dma_extra_info
74 * - \ref asfdoc_samb_dma_examples
75 * - \ref asfdoc_samb_dma_api_overview
76 *
77 *
78 * \section asfdoc_samb_dma_prerequisites Prerequisites
79 *
80 * There are no prerequisites for this module.
81 *
82 *
83 * \section asfdoc_samb_dma_module_overview Module Overview
84 *
85 * SAM devices with DMAC enables high data transfer rates with minimum
86 * CPU intervention and frees up CPU time. With access to all peripherals,
87 * the DMAC can handle automatic transfer of data to/from modules.
88 * It supports static and incremental addressing for both source and
89 * destination.
90 *
91 * The DMAC when used with peripheral triggers, provides a
92 * considerable advantage by reducing the power consumption and performing
93 * data transfer in the background.
94 * The CPU can remain in sleep during this time to reduce power consumption.
95 *
96 * <table>
97 * <tr>
98 * <th>Device</th>
99 * <th>Dma channel number</th>
100 * </tr>
101 * <tr>
102 * <td>SAMB11</td>
103 * <td>4</td>
104 * </tr>
105 * </table>
106 * The DMA channel operation can be suspended at any time by software,
107 * or after selectable descriptor execution. The DMAC driver for SAM
108 * supports four types of transfers such as peripheral to peripheral,
109 * peripheral to memory, memory to peripheral, and memory to memory.
110 *
111 * The basic transfer unit is a beat which is defined as a single bus access.
112 * There can be multiple beats in a single block transfer and multiple block
113 * transfers in a DMA transaction.
114 * DMA transfer is based on descriptors, which holds transfer properties
115 * such as the source and destination addresses, transfer counter, and other
116 * additional transfer control information.
117 * The descriptors can be static or linked. When static, a single block transfer
118 * is performed. When linked, a number of transfer descriptors can be used to
119 * enable multiple block transfers within a single DMA transaction.
120 *
121 * The implementation of the DMA driver is based on the idea that DMA channel
122 * is a finite resource of entities with the same abilities. A DMA channel resource
123 * is able to move a defined set of data from a source address to destination
124 * address triggered by a transfer trigger. On the SAM devices there are 12
125 * DMA resources available for allocation. Each of these DMA resources can trigger
126 * interrupt callback routines.
127 * The other main features are:
128 *
129 * - Selectable transfer trigger source
130 * - Software
131 * - Peripheral
132 * - Tree level channel priority
133 * - Normal level
134 * - High level
135 * - Top level
136 * - Optional interrupt generation on transfer complete, channel error
137 * - Supports multi-buffer or circular buffer mode by linking multiple descriptors
138 * - Beat size configurable as 8-bit, 16-bit, or 32-bit
139 *
140 * A simplified block diagram of the DMA Resource can be seen in
141 * \ref asfdoc_samb_dma_module_block_diagram "the figure below".
142 *
143 * \anchor asfdoc_samb_dma_module_block_diagram
144 * \dot
145 * digraph overview {
146 * splines = false;
147 * rankdir=LR;
148 *
149 * mux1 [label="Transfer Trigger", shape=box];
150 *
151 * dma [label="DMA Channel", shape=polygon, sides=6, orientation=60, style=filled, fillcolor=darkolivegreen1, height=1, width=1];
152 * descriptor [label="Transfer Descriptor", shape=box, style=filled, fillcolor=lightblue];
153 *
154 * mux1 -> dma;
155 * descriptor -> dma;
156 *
157 * interrupt [label="Interrupt", shape=box];
158 * events [label="Events", shape=box];
159 *
160 * dma:e -> interrupt:w;
161 * dma:e -> events:w;
162 *
163 * {rank=same; descriptor dma}
164 *
165 * }
166 * \enddot
167 *
168 * \subsection asfdoc_samb_dma_module_overview_dma_channels DMA Channels
169 * The DMAC in each device consists of several DMA channels, which
170 * along with the transfer descriptors defines the data transfer properties.
171 * - The transfer control descriptor defines the source and destination
172 * addresses, source and destination address increment settings, the
173 * block transfer count
174 * - Dedicated channel registers control the peripheral trigger source,
175 * trigger mode settings, and channel priority level settings
176 *
177 * With a successful DMA resource allocation, a dedicated
178 * DMA channel will be assigned. The channel will be occupied until the
179 * DMA resource is freed. A DMA resource handle is used to identify the specific
180 * DMA resource.
181 * When there are multiple channels with active requests, the arbiter prioritizes
182 * the channels requesting access to the bus.
183 *
184 * \subsection asfdoc_samb_dma_module_overview_dma_trigger DMA Triggers
185 * DMA transfer can be started only when a DMA transfer request is acknowledged/granted by the arbiter. A
186 * transfer request can be triggered from software, peripheral. There
187 * are dedicated source trigger selections for each DMA channel usage.
188 *
189 * \subsection asfdoc_samb_dma_module_overview_dma_transfer_descriptor DMA Transfer Descriptor
190 * The transfer descriptor resides in the SRAM and
191 * defines these channel properties.
192 *
193 * <table>
194 * <tr>
195 * <th>Field name</th>
196 * <th>Field width</th>
197 * </tr>
198 * <tr>
199 * <td>Source Address</td>
200 * <td>32 bits</td>
201 * </tr>
202 * <tr>
203 * <td>Destination Address</td>
204 * <td>32 bits</td>
205 * </tr>
206 * <tr>
207 * <td>Block Transfer Counter</td>
208 * <td>32 bits</td>
209 * </tr>
210 * <tr>
211 * <td>Descriptor Next Address</td>
212 * <td>30 bits</td>
213 * </tr>
214 * <tr>
215 * <td>Block Transfer Interrupt</td>
216 * <td>1 bit</td>
217 * </tr>
218 * <tr>
219 * <td>Block Transfer Stop Control</td>
220 * <td>1 bit</td>
221 * </tr>
222 * </table>
223 *
224 * Before starting a transfer, at least one descriptor should be configured.
225 * After a successful allocation of a DMA channel, the transfer descriptor can
226 * be added with a call to \ref dma_add_descriptor(). If there is a transfer
227 * descriptor already allocated to the DMA resource, the descriptor will
228 * be linked to the next descriptor address.
229 *
230 * \subsection asfdoc_samb_dma_module_overview_dma_output DMA Interrupts
231 * Both an interrupt callback and an peripheral can be triggered by the
232 * DMA transfer. Three types of callbacks are supported by the DMA driver:
233 * transfer complete, channel suspend, and transfer error. Each of these callback
234 * types can be registered and enabled for each channel independently through
235 * the DMA driver API.
236 *
237 *
238 * \section asfdoc_samb_dma_special_considerations Special Considerations
239 *
240 * There are no special considerations for this module.
241 *
242 *
243 * \section asfdoc_samb_dma_extra_info Extra Information
244 *
245 * For extra information, see \ref asfdoc_samb_dma_extra. This includes:
246 * - \ref asfdoc_samb_dma_extra_acronyms
247 * - \ref asfdoc_samb_dma_extra_dependencies
248 * - \ref asfdoc_samb_dma_extra_errata
249 * - \ref asfdoc_samb_dma_extra_history
250 *
251 *
252 * \section asfdoc_samb_dma_examples Examples
253 *
254 * For a list of examples related to this driver, see
255 * \ref asfdoc_samb_dma_exqsg.
256 *
257 *
258 * \section asfdoc_samb_dma_api_overview API Overview
259 * @{
260 */
261
262 #include <compiler.h>
263 #include <system_sam_b.h>
264 #include "conf_dma.h"
265
266 /** DMA IRQn number. */
267 #define PROV_DMA_CTRL0_IRQn 15
268
269 /** DMA invalid channel number. */
270 #define DMA_INVALID_CHANNEL 0xff
271
272 /** DMA peripheral index */
273 enum dma_peripheral_index {
274 MEMORY_DMA_PERIPHERAL = 0,
275 UART0RX_DMA_PERIPHERAL,
276 UART0TX_DMA_PERIPHERAL,
277 UART1RX_DMA_PERIPHERAL,
278 UART1TX_DMA_PERIPHERAL,
279 SPI0RX_DMA_PERIPHERAL,
280 SPI0TX_DMA_PERIPHERAL,
281 SPI1RX_DMA_PERIPHERAL,
282 SPI1TX_DMA_PERIPHERAL,
283 I2C0RX_DMA_PERIPHERAL,
284 I2C0TX_DMA_PERIPHERAL,
285 I2C1RX_DMA_PERIPHERAL,
286 I2C1TX_DMA_PERIPHERAL,
287 DUALTIMER0_DMA_PERIPHERAL = 15,
288 TIMER0_DMA_PERIPHERAL,
289 };
290
291 /** DMA channel index */
292 enum dma_ch_index {
293 /** DMA channel 0 */
294 DMA_CHANNEL_0 = 0,
295 /** DMA channel 1 */
296 DMA_CHANNEL_1,
297 /** DMA channel 2 */
298 DMA_CHANNEL_2,
299 /** DMA channel 3 */
300 DMA_CHANNEL_3,
301 };
302
303 enum dma_endian_swap {
304 /** DMA endian no swap */
305 DMA_ENDIAN_NO_SWAP,
306 /** DMA endian 16-bit */
307 DMA_ENDIAN_SIZE_16,
308 /** DMA endian 32-bit */
309 DMA_ENDIAN_SIZE_32,
310 /** DMA endian 64-bit */
311 DMA_ENDIAN_SIZE_64,
312 };
313
314 /**
315 * Callback types for DMA callback driver.
316 */
317 enum dma_callback_type {
318 /** Callback for transfer complete */
319 DMA_CALLBACK_TRANSFER_DONE,
320 /** AHB read slave error */
321 DMA_CALLBACK_READ_ERR,
322 /** AHB write slave error */
323 DMA_CALLBACK_WRITE_ERR,
324 /** FIFO has been overflown */
325 DMA_CALLBACK_FIFO_OVERFLOW,
326 /** FIFO has been underflows */
327 DMA_CALLBACK_FIFO_UNDERFLOW,
328 /** Read timeout on AHB bus (timeout value fixed at 1024 cycles) */
329 DMA_CALLBACK_READ_TIMEOUT,
330 /** Write timeout on AHB bus (timeout value fixed at 1024 cycles) */
331 DMA_CALLBACK_WRITE_TIMEOUT,
332 /** Channel active but did not start a burst for 2048 cycles */
333 DMA_CALLBACK_WDT_TRIGGER,
334 /** Number of available callbacks */
335 DMA_CALLBACK_N,
336 };
337
338 /**
339 * DMA transfer descriptor configuration. When the source or destination address
340 * increment is enabled, the addresses stored into the configuration structure
341 * must correspond to the end of the transfer.
342 */
343 struct dma_descriptor {
344 /** Start address of read buffer */
345 uint32_t read_start_addr;
346 /** Start address of write buffer */
347 uint32_t write_start_addr;
348 /** Size (in bytes) of buffer to transfer */
349 uint32_t buffer_size;
350 union {
351 struct {
352 /** Active high interrupt enable once buffer has been transferred */
353 uint32_t set_interrupt:1;
354 /** If set, channel stops when buffer done, otherwise load from cmd_next_addr */
355 uint32_t last:1;
356 /** Address of next command if cmd_last is not set */
357 uint32_t next_addr:30;
358 } cmd;
359 uint32_t next;
360 };
361 };
362 /** Structure for DMA source/description */
363 struct dma_config {
364 /** Maximum number of bytes of an AHB read/write burst */
365 uint8_t max_burst;
366 /** Number of AHB read/write commands to issue before channel is released */
367 uint8_t tokens;
368 /** If true, the controller will increment the next burst address */
369 bool enable_inc_addr;
370 /** Index of peripheral to read/write from (0 if memory or no peripheral flow control) */
371 enum dma_peripheral_index periph;
372 /**
373 * Number of cycles to wait for read/write request signal to update
374 * after issuing the read/write clear signal
375 */
376 uint8_t periph_delay;
377 /** Top priority enable */
378 bool enable_proi_top;
379 /** Top priority channel index */
380 uint8_t proi_top_index;
381 /** High priority enable */
382 bool enable_proi_high;
383 /** High priority channel index */
384 uint8_t proi_high_index;
385 };
386
387 /** Structure for DMA transfer resource */
388 struct dma_resource_config {
389 struct dma_config src;
390 struct dma_config des;
391 /** If true, channel will work in joint mode */
392 bool enable_joint_mode;
393 /** Endian Byte Swapping */
394 enum dma_endian_swap swap;
395 };
396
397 /** Forward definition of the DMA resource */
398 struct dma_resource;
399 /** Type definition for a DMA resource callback function */
400 typedef void (*dma_callback_t)(struct dma_resource *const resource);
401
402 /** Structure for DMA transfer resource */
403 struct dma_resource {
404 /** Allocated DMA channel ID */
405 uint8_t channel_id;
406 /** Array of callback functions for DMA transfer job */
407 dma_callback_t callback[DMA_CALLBACK_N];
408 /** Bit mask for enabled callbacks */
409 uint8_t callback_enable;
410 /** Status of the last job */
411 volatile enum status_code job_status;
412 /** Transferred data size */
413 uint32_t transfered_size;
414 /** DMA transfer descriptor */
415 struct dma_descriptor* descriptor;
416 };
417
418 /**
419 * \brief Get DMA resource status.
420 *
421 * \param[in] resource Pointer to the DMA resource
422 *
423 * \return Status of the DMA resource.
424 */
dma_get_job_status(struct dma_resource * resource)425 static inline enum status_code dma_get_job_status(struct dma_resource *resource)
426 {
427 return resource->job_status;
428 }
429
430 /**
431 * \brief Enable a callback function for a dedicated DMA resource.
432 *
433 * \param[in] resource Pointer to the DMA resource
434 * \param[in] type Callback function type
435 *
436 */
dma_enable_callback(struct dma_resource * resource,enum dma_callback_type type)437 static inline void dma_enable_callback(struct dma_resource *resource,
438 enum dma_callback_type type)
439 {
440 resource->callback_enable |= 1 << type;
441 }
442
443 /**
444 * \brief Disable a callback function for a dedicated DMA resource.
445 *
446 * \param[in] resource Pointer to the DMA resource
447 * \param[in] type Callback function type
448 *
449 */
dma_disable_callback(struct dma_resource * resource,enum dma_callback_type type)450 static inline void dma_disable_callback(struct dma_resource *resource,
451 enum dma_callback_type type)
452 {
453 resource->callback_enable &= ~(1 << type);
454 }
455
456 /**
457 * \brief Register a callback function for a dedicated DMA resource.
458 *
459 * There are three types of callback functions, which can be registered:
460 * - Callback for transfer complete
461 * - Callback for transfer error
462 * - Callback for channel suspend
463 *
464 * \param[in] resource Pointer to the DMA resource
465 * \param[in] callback Pointer to the callback function
466 * \param[in] type Callback function type
467 *
468 */
dma_register_callback(struct dma_resource * resource,dma_callback_t callback,enum dma_callback_type type)469 static inline void dma_register_callback(struct dma_resource *resource,
470 dma_callback_t callback, enum dma_callback_type type)
471 {
472 resource->callback[type] = callback;
473 }
474
475 /**
476 * \brief Unregister a callback function for a dedicated DMA resource.
477 *
478 * There are three types of callback functions:
479 * - Callback for transfer complete
480 * - Callback for transfer error
481 * - Callback for channel suspend
482 *
483 * The application can unregister any of the callback functions which
484 * are already registered and are no longer needed.
485 *
486 * \param[in] resource Pointer to the DMA resource
487 * \param[in] type Callback function type
488 *
489 */
dma_unregister_callback(struct dma_resource * resource,enum dma_callback_type type)490 static inline void dma_unregister_callback(struct dma_resource *resource,
491 enum dma_callback_type type)
492 {
493 resource->callback[type] = NULL;
494 }
495
496 /**
497 * \brief Initializes DMA transfer configuration with predefined default values.
498 *
499 * This function will initialize a given DMA descriptor configuration structure to
500 * a set of known default values. This function should be called on
501 * any new instance of the configuration structure before being
502 * modified by the user application.
503 *
504 * The default configuration is as follows:
505 * \li Set the read start address as 0
506 * \li Set the write start address as 0
507 * \li Set buffer size as 1
508 * \li Set beat size as byte
509 * \li Enable the interrupt
510 * \li Enable the channel stops when buffer done
511 * \li Set next command address to 0
512 * \param[out] config Pointer to the configuration
513 *
514 */
dma_descriptor_get_config_defaults(struct dma_descriptor * config)515 static inline void dma_descriptor_get_config_defaults(struct dma_descriptor *config)
516 {
517 /* Default read buffer size is set to 0 */
518 config->read_start_addr = 0;
519 /* Default write buffer size is set to 0 */
520 config->write_start_addr = 0;
521 /* Set beat size to one byte */
522 config->buffer_size = 1;
523 /* Enable transferred interrupt */
524 config->cmd.set_interrupt = 1;
525 /* Channel stops when buffer done */
526 config->cmd.last = 1;
527 /* Set next command to 0 */
528 config->cmd.next_addr = 0;
529 }
530
531 /**
532 * \brief Update DMA descriptor.
533 *
534 * This function can update the descriptor of an allocated DMA resource.
535 *
536 */
dma_update_descriptor(struct dma_resource * resource,struct dma_descriptor * descriptor)537 static inline void dma_update_descriptor(struct dma_resource *resource,
538 struct dma_descriptor* descriptor)
539 {
540 resource->descriptor = descriptor;
541 }
542
543 /**
544 * \brief Reset DMA descriptor.
545 *
546 * This function will clear the DESCADDR register of an allocated DMA resource.
547 *
548 */
dma_reset_descriptor(struct dma_resource * resource)549 static inline void dma_reset_descriptor(struct dma_resource *resource)
550 {
551 resource->descriptor = NULL;
552 }
553
554 void dma_get_config_defaults(struct dma_resource_config *config);
555 enum status_code dma_allocate(struct dma_resource *resource,
556 struct dma_resource_config *config);
557 enum status_code dma_add_descriptor(struct dma_resource *resource,
558 struct dma_descriptor* descriptor);
559 enum status_code dma_start_transfer_job(struct dma_resource *resource);
560 enum status_code dma_free(struct dma_resource *resource);
561 uint8_t dma_get_status(uint8_t channel);
562 uint8_t dma_get_interrupt_status(uint8_t channel);
563 void dma_clear_interrupt_status(uint8_t channel, uint8_t flag);
564 /** @} */
565
566 /**
567 * \page asfdoc_samb_dma_extra Extra Information for DMAC Driver
568 *
569 * \section asfdoc_samb_dma_extra_acronyms Acronyms
570 * Below is a table listing the acronyms used in this module, along with their
571 * intended meanings.
572 *
573 * <table>
574 * <tr>
575 * <th>Acronym</th>
576 * <th>Description</th>
577 * </tr>
578 * <tr>
579 * <td>DMA</td>
580 * <td>Direct Memory Access</td>
581 * </tr>
582 * <tr>
583 * <td>DMAC</td>
584 * <td>Direct Memory Access Controller </td>
585 * </tr>
586 * <tr>
587 * <td>CPU</td>
588 * <td>Central Processing Unit</td>
589 * </tr>
590 * </table>
591 *
592 *
593 * \section asfdoc_samb_dma_extra_dependencies Dependencies
594 * There are no dependencies related to this driver.
595 *
596 *
597 * \section asfdoc_samb_dma_extra_errata Errata
598 * There are no errata related to this driver.
599 *
600 *
601 * \section asfdoc_samb_dma_extra_history Module History
602 * An overview of the module history is presented in the table below, with
603 * details on the enhancements and fixes made to the module since its first
604 * release. The current version of this corresponds to the newest version in
605 * the table.
606 *
607 * <table>
608 * <tr>
609 * <th>Changelog</th>
610 * </tr>
611 * <tr>
612 * <td>Initial Release</td>
613 * </tr>
614 * </table>
615 */
616
617 /**
618 * \page asfdoc_samb_dma_exqsg Examples for DMAC Driver
619 *
620 * This is a list of the available Quick Start Guides (QSGs) and example
621 * applications for \ref asfdoc_samb_dma_group. QSGs are simple examples with
622 * step-by-step instructions to configure and use this driver in a selection of
623 * use cases. Note that QSGs can be compiled as a standalone application or be
624 * added to the user application.
625 *
626 * - \subpage asfdoc_samb_dma_basic_use_case
627 *
628 * \note More DMA usage examples are available in peripheral QSGs.
629 *
630 * \page asfdoc_samb_dma_document_revision_history Document Revision History
631 *
632 * <table>
633 * <tr>
634 * <th>Doc. Rev.</td>
635 * <th>Date</td>
636 * <th>Comments</td>
637 * </tr>
638 * <tr>
639 * <td>A</td>
640 * <td>09/2015</td>
641 * <td>Initial release</td>
642 * </tr>
643 * </table>
644 */
645
646 #ifdef __cplusplus
647 }
648 #endif
649
650 #endif /* DMA_H_INCLUDED */
651