Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
dma.h
Go to the documentation of this file.
1
7/*
8 * Copyright (c) 2016 Intel Corporation
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12
13#ifndef ZEPHYR_INCLUDE_DRIVERS_DMA_H_
14#define ZEPHYR_INCLUDE_DRIVERS_DMA_H_
15
16#include <kernel.h>
17#include <device.h>
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23
35 PERIPHERAL_TO_PERIPHERAL /*only supported in NXP EDMA*/
36};
37
43};
44
45/* channel attributes */
47 DMA_CHANNEL_NORMAL, /* normal DMA channel */
48 DMA_CHANNEL_PERIODIC, /* can be triggerred by periodic sources */
49};
50
89#ifdef CONFIG_DMA_64BIT
92#else
95#endif
111};
112
125typedef void (*dma_callback_t)(const struct device *dev, void *user_data,
126 uint32_t channel, int status);
127
185};
186
197 bool busy;
200};
201
216};
217
218/* magic code to identify context content */
219#define DMA_MAGIC 0x47494749
220
227typedef int (*dma_api_config)(const struct device *dev, uint32_t channel,
228 struct dma_config *config);
229
230#ifdef CONFIG_DMA_64BIT
231typedef int (*dma_api_reload)(const struct device *dev, uint32_t channel,
232 uint64_t src, uint64_t dst, size_t size);
233#else
234typedef int (*dma_api_reload)(const struct device *dev, uint32_t channel,
235 uint32_t src, uint32_t dst, size_t size);
236#endif
237
238typedef int (*dma_api_start)(const struct device *dev, uint32_t channel);
239
240typedef int (*dma_api_stop)(const struct device *dev, uint32_t channel);
241
242typedef int (*dma_api_get_status)(const struct device *dev, uint32_t channel,
243 struct dma_status *status);
244
258typedef bool (*dma_api_chan_filter)(const struct device *dev,
259 int channel, void *filter_param);
260
261__subsystem struct dma_driver_api {
262 dma_api_config config;
263 dma_api_reload reload;
264 dma_api_start start;
265 dma_api_stop stop;
266 dma_api_get_status get_status;
267 dma_api_chan_filter chan_filter;
268};
284static inline int dma_config(const struct device *dev, uint32_t channel,
285 struct dma_config *config)
286{
287 const struct dma_driver_api *api =
288 (const struct dma_driver_api *)dev->api;
289
290 return api->config(dev, channel, config);
291}
292
306#ifdef CONFIG_DMA_64BIT
307static inline int dma_reload(const struct device *dev, uint32_t channel,
308 uint64_t src, uint64_t dst, size_t size)
309#else
310static inline int dma_reload(const struct device *dev, uint32_t channel,
311 uint32_t src, uint32_t dst, size_t size)
312#endif
313{
314 const struct dma_driver_api *api =
315 (const struct dma_driver_api *)dev->api;
316
317 if (api->reload) {
318 return api->reload(dev, channel, src, dst, size);
319 }
320
321 return -ENOSYS;
322}
323
338__syscall int dma_start(const struct device *dev, uint32_t channel);
339
340static inline int z_impl_dma_start(const struct device *dev, uint32_t channel)
341{
342 const struct dma_driver_api *api =
343 (const struct dma_driver_api *)dev->api;
344
345 return api->start(dev, channel);
346}
347
361__syscall int dma_stop(const struct device *dev, uint32_t channel);
362
363static inline int z_impl_dma_stop(const struct device *dev, uint32_t channel)
364{
365 const struct dma_driver_api *api =
366 (const struct dma_driver_api *)dev->api;
367
368 return api->stop(dev, channel);
369}
370
383__syscall int dma_request_channel(const struct device *dev,
384 void *filter_param);
385
386static inline int z_impl_dma_request_channel(const struct device *dev,
387 void *filter_param)
388{
389 int i = 0;
390 int channel = -EINVAL;
391 const struct dma_driver_api *api =
392 (const struct dma_driver_api *)dev->api;
393 /* dma_context shall be the first one in dev data */
394 struct dma_context *dma_ctx = (struct dma_context *)dev->data;
395
396 if (dma_ctx->magic != DMA_MAGIC) {
397 return channel;
398 }
399
400 for (i = 0; i < dma_ctx->dma_channels; i++) {
401 if (!atomic_test_and_set_bit(dma_ctx->atomic, i)) {
402 channel = i;
403 if (api->chan_filter &&
404 !api->chan_filter(dev, channel, filter_param)) {
405 atomic_clear_bit(dma_ctx->atomic, channel);
406 continue;
407 }
408 break;
409 }
410 }
411
412 return channel;
413}
414
424__syscall void dma_release_channel(const struct device *dev,
425 uint32_t channel);
426
427static inline void z_impl_dma_release_channel(const struct device *dev,
428 uint32_t channel)
429{
430 struct dma_context *dma_ctx = (struct dma_context *)dev->data;
431
432 if (dma_ctx->magic != DMA_MAGIC) {
433 return;
434 }
435
436 if (channel < dma_ctx->dma_channels) {
437 atomic_clear_bit(dma_ctx->atomic, channel);
438 }
439
440}
441
454__syscall int dma_chan_filter(const struct device *dev,
455 int channel, void *filter_param);
456
457static inline int z_impl_dma_chan_filter(const struct device *dev,
458 int channel, void *filter_param)
459{
460 const struct dma_driver_api *api =
461 (const struct dma_driver_api *)dev->api;
462
463 if (api->chan_filter) {
464 return api->chan_filter(dev, channel, filter_param);
465 }
466
467 return -ENOSYS;
468}
469
484static inline int dma_get_status(const struct device *dev, uint32_t channel,
485 struct dma_status *stat)
486{
487 const struct dma_driver_api *api =
488 (const struct dma_driver_api *)dev->api;
489
490 if (api->get_status) {
491 return api->get_status(dev, channel, stat);
492 }
493
494 return -ENOSYS;
495}
496
511{
512 /* Check boundaries (max supported width is 32 Bytes) */
513 if (size < 1 || size > 32) {
514 return 0; /* Zero is the default (8 Bytes) */
515 }
516
517 /* Ensure size is a power of 2 */
518 if (!is_power_of_two(size)) {
519 return 0; /* Zero is the default (8 Bytes) */
520 }
521
522 /* Convert to bit pattern for writing to a register */
523 return find_msb_set(size);
524}
525
540{
541 /* Check boundaries (max supported burst length is 256) */
542 if (burst < 1 || burst > 256) {
543 return 0; /* Zero is the default (1 burst length) */
544 }
545
546 /* Ensure burst is a power of 2 */
547 if (!(burst & (burst - 1))) {
548 return 0; /* Zero is the default (1 burst length) */
549 }
550
551 /* Convert to bit pattern for writing to a register */
552 return find_msb_set(burst);
553}
554
559#ifdef __cplusplus
560}
561#endif
562
563#include <syscalls/dma.h>
564
565#endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_H_ */
int atomic_t
Definition: atomic.h:21
void
Definition: eswifi_shell.c:15
static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op)
find most significant bit set in a 32-bit word
Definition: ffs.h:31
static void atomic_clear_bit(atomic_t *target, int bit)
Atomically clear a bit.
Definition: atomic.h:187
static bool atomic_test_and_set_bit(atomic_t *target, int bit)
Atomically set a bit.
Definition: atomic.h:166
static int dma_get_status(const struct device *dev, uint32_t channel, struct dma_status *stat)
get current runtime status of DMA transfer
Definition: dma.h:484
int dma_stop(const struct device *dev, uint32_t channel)
Stops the DMA transfer and disables the channel.
static int dma_reload(const struct device *dev, uint32_t channel, uint32_t src, uint32_t dst, size_t size)
Reload buffer(s) for a DMA channel.
Definition: dma.h:310
static int dma_config(const struct device *dev, uint32_t channel, struct dma_config *config)
Configure individual channel for DMA transfer.
Definition: dma.h:284
int dma_chan_filter(const struct device *dev, int channel, void *filter_param)
DMA channel filter.
int dma_request_channel(const struct device *dev, void *filter_param)
request DMA channel.
static uint32_t dma_burst_index(uint32_t burst)
Look-up generic burst index to be used in registers.
Definition: dma.h:539
void dma_release_channel(const struct device *dev, uint32_t channel)
release DMA channel.
int dma_start(const struct device *dev, uint32_t channel)
Enables DMA channel and starts the transfer, the channel must be configured beforehand.
void(* dma_callback_t)(const struct device *dev, void *user_data, uint32_t channel, int status)
Callback function for DMA transfer completion.
Definition: dma.h:125
static uint32_t dma_width_index(uint32_t size)
Look-up generic width index to be used in registers.
Definition: dma.h:510
dma_channel_filter
Definition: dma.h:46
#define DMA_MAGIC
Definition: dma.h:219
dma_channel_direction
Definition: dma.h:31
dma_addr_adj
Definition: dma.h:39
@ DMA_CHANNEL_NORMAL
Definition: dma.h:47
@ DMA_CHANNEL_PERIODIC
Definition: dma.h:48
@ MEMORY_TO_PERIPHERAL
Definition: dma.h:33
@ MEMORY_TO_MEMORY
Definition: dma.h:32
@ PERIPHERAL_TO_MEMORY
Definition: dma.h:34
@ PERIPHERAL_TO_PERIPHERAL
Definition: dma.h:35
@ DMA_ADDR_ADJ_DECREMENT
Definition: dma.h:41
@ DMA_ADDR_ADJ_INCREMENT
Definition: dma.h:40
@ DMA_ADDR_ADJ_NO_CHANGE
Definition: dma.h:42
static bool is_power_of_two(unsigned int x)
Is x a power of two?
Definition: util.h:196
#define EINVAL
Definition: errno.h:61
#define ENOSYS
Definition: errno.h:83
#define bool
Definition: stdbool.h:13
__UINT32_TYPE__ uint32_t
Definition: stdint.h:60
__INT32_TYPE__ int32_t
Definition: stdint.h:44
__UINT64_TYPE__ uint64_t
Definition: stdint.h:61
__UINT16_TYPE__ uint16_t
Definition: stdint.h:59
Runtime device structure (in ROM) per driver instance.
Definition: device.h:367
const void * api
Definition: device.h:373
void *const data
Definition: device.h:377
DMA block configuration structure.
Definition: dma.h:88
uint32_t dest_scatter_interval
Definition: dma.h:97
uint16_t reserved
Definition: dma.h:110
uint32_t source_gather_interval
Definition: dma.h:96
uint32_t block_size
Definition: dma.h:100
uint16_t source_reload_en
Definition: dma.h:106
uint16_t dest_scatter_en
Definition: dma.h:103
uint16_t dest_reload_en
Definition: dma.h:107
uint16_t fifo_mode_control
Definition: dma.h:108
uint16_t source_gather_count
Definition: dma.h:99
uint16_t source_addr_adj
Definition: dma.h:104
struct dma_block_config * next_block
Definition: dma.h:101
uint32_t dest_address
Definition: dma.h:94
uint32_t source_address
Definition: dma.h:93
uint16_t source_gather_en
Definition: dma.h:102
uint16_t dest_addr_adj
Definition: dma.h:105
uint16_t dest_scatter_count
Definition: dma.h:98
uint16_t flow_control_mode
Definition: dma.h:109
DMA configuration structure.
Definition: dma.h:165
uint32_t channel_priority
Definition: dma.h:172
uint32_t source_handshake
Definition: dma.h:170
uint32_t complete_callback_en
Definition: dma.h:168
void * user_data
Definition: dma.h:183
uint32_t error_callback_en
Definition: dma.h:169
dma_callback_t dma_callback
Definition: dma.h:184
uint32_t source_chaining_en
Definition: dma.h:173
uint32_t dest_chaining_en
Definition: dma.h:174
uint32_t dma_slot
Definition: dma.h:166
uint32_t channel_direction
Definition: dma.h:167
uint32_t source_data_size
Definition: dma.h:177
uint32_t dest_burst_length
Definition: dma.h:180
struct dma_block_config * head_block
Definition: dma.h:182
uint32_t linked_channel
Definition: dma.h:175
uint32_t source_burst_length
Definition: dma.h:179
uint32_t block_count
Definition: dma.h:181
uint32_t dest_data_size
Definition: dma.h:178
uint32_t reserved
Definition: dma.h:176
uint32_t dest_handshake
Definition: dma.h:171
Definition: dma.h:212
int32_t magic
Definition: dma.h:213
atomic_t * atomic
Definition: dma.h:215
int dma_channels
Definition: dma.h:214
Definition: dma.h:196
uint32_t pending_length
Definition: dma.h:199
bool busy
Definition: dma.h:197
enum dma_channel_direction dir
Definition: dma.h:198
Definition: stat.h:39
static const intptr_t user_data[5]
Definition: main.c:590