v2.0.0
dma.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_DMA_H
8#define _HARDWARE_DMA_H
9
10#include "pico.h"
11#include "hardware/structs/dma.h"
12#include "hardware/regs/dreq.h"
13#include "pico/assert.h"
14#include "hardware/regs/intctrl.h"
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
38// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_DMA, Enable/disable hardware_dma assertions, type=bool, default=0, group=hardware_dma
39#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_DMA
40#ifdef PARAM_ASSERTIONS_ENABLED_DMA // backwards compatibility with SDK < 2.0.0
41#define PARAM_ASSERTIONS_ENABLED_HARDWARE_DMA PARAM_ASSERTIONS_ENABLED_DMA
42#else
43#define PARAM_ASSERTIONS_ENABLED_HARDWARE_DMA 0
44#endif
45#endif
46
55#ifndef DMA_IRQ_NUM
56#define DMA_IRQ_NUM(irq_index) (DMA_IRQ_0 + (irq_index))
57#endif
58
59static inline void check_dma_channel_param(__unused uint channel) {
60#if PARAM_ASSERTIONS_ENABLED(HARDWARE_DMA)
61 // this method is used a lot by inline functions so avoid code bloat by deferring to function
62 extern void check_dma_channel_param_impl(uint channel);
63 check_dma_channel_param_impl(channel);
64#endif
65}
66
67static inline void check_dma_timer_param(__unused uint timer_num) {
68 valid_params_if(HARDWARE_DMA, timer_num < NUM_DMA_TIMERS);
69}
70
71inline static dma_channel_hw_t *dma_channel_hw_addr(uint channel) {
72 check_dma_channel_param(channel);
73 return &dma_hw->ch[channel];
74}
75
85void dma_channel_claim(uint channel);
86
96void dma_claim_mask(uint32_t channel_mask);
97
103void dma_channel_unclaim(uint channel);
104
110void dma_unclaim_mask(uint32_t channel_mask);
111
118int dma_claim_unused_channel(bool required);
119
128bool dma_channel_is_claimed(uint channel);
129
143 enum dma_channel_transfer_size {
144 DMA_SIZE_8 = 0,
145 DMA_SIZE_16 = 1,
146 DMA_SIZE_32 = 2
147};
148
149 typedef struct {
150 uint32_t ctrl;
151} dma_channel_config;
152
160 static inline void channel_config_set_read_increment(dma_channel_config *c, bool incr) {
161 c->ctrl = incr ? (c->ctrl | DMA_CH0_CTRL_TRIG_INCR_READ_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_INCR_READ_BITS);
162}
163
171 static inline void channel_config_set_write_increment(dma_channel_config *c, bool incr) {
172 c->ctrl = incr ? (c->ctrl | DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS);
173}
174
190 static inline void channel_config_set_dreq(dma_channel_config *c, uint dreq) {
191 assert(dreq <= DREQ_FORCE);
192 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_TREQ_SEL_BITS) | (dreq << DMA_CH0_CTRL_TRIG_TREQ_SEL_LSB);
193}
194
204 static inline void channel_config_set_chain_to(dma_channel_config *c, uint chain_to) {
205 assert(chain_to <= NUM_DMA_CHANNELS);
206 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (chain_to << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB);
207}
208
218 static inline void channel_config_set_transfer_data_size(dma_channel_config *c, enum dma_channel_transfer_size size) {
219 assert(size == DMA_SIZE_8 || size == DMA_SIZE_16 || size == DMA_SIZE_32);
220 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_DATA_SIZE_BITS) | (((uint)size) << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB);
221}
222
238 static inline void channel_config_set_ring(dma_channel_config *c, bool write, uint size_bits) {
239 assert(size_bits < 32);
240 c->ctrl = (c->ctrl & ~(DMA_CH0_CTRL_TRIG_RING_SIZE_BITS | DMA_CH0_CTRL_TRIG_RING_SEL_BITS)) |
241 (size_bits << DMA_CH0_CTRL_TRIG_RING_SIZE_LSB) |
242 (write ? DMA_CH0_CTRL_TRIG_RING_SEL_BITS : 0);
243}
244
254 static inline void channel_config_set_bswap(dma_channel_config *c, bool bswap) {
255 c->ctrl = bswap ? (c->ctrl | DMA_CH0_CTRL_TRIG_BSWAP_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_BSWAP_BITS);
256}
257
268 static inline void channel_config_set_irq_quiet(dma_channel_config *c, bool irq_quiet) {
269 c->ctrl = irq_quiet ? (c->ctrl | DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS);
270}
271
286 static inline void channel_config_set_high_priority(dma_channel_config *c, bool high_priority) {
287 c->ctrl = high_priority ? (c->ctrl | DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS);
288}
289
301 static inline void channel_config_set_enable(dma_channel_config *c, bool enable) {
302 c->ctrl = enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_EN_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_EN_BITS);
303}
304
313 static inline void channel_config_set_sniff_enable(dma_channel_config *c, bool sniff_enable) {
314 c->ctrl = sniff_enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS) : (c->ctrl &
315 ~DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
316}
317
338 static inline dma_channel_config dma_channel_get_default_config(uint channel) {
339 dma_channel_config c = {0};
340 channel_config_set_read_increment(&c, true);
341 channel_config_set_write_increment(&c, false);
342 channel_config_set_dreq(&c, DREQ_FORCE);
343 channel_config_set_chain_to(&c, channel);
344 channel_config_set_transfer_data_size(&c, DMA_SIZE_32);
345 channel_config_set_ring(&c, false, 0);
346 channel_config_set_bswap(&c, false);
347 channel_config_set_irq_quiet(&c, false);
348 channel_config_set_enable(&c, true);
349 channel_config_set_sniff_enable(&c, false);
350 channel_config_set_high_priority( &c, false);
351 return c;
352}
353
360 static inline dma_channel_config dma_get_channel_config(uint channel) {
361 dma_channel_config c;
362 c.ctrl = dma_channel_hw_addr(channel)->ctrl_trig;
363 return c;
364}
365
372 static inline uint32_t channel_config_get_ctrl_value(const dma_channel_config *config) {
373 return config->ctrl;
374}
375
383 static inline void dma_channel_set_config(uint channel, const dma_channel_config *config, bool trigger) {
384 // Don't use CTRL_TRIG since we don't want to start a transfer
385 if (!trigger) {
386 dma_channel_hw_addr(channel)->al1_ctrl = channel_config_get_ctrl_value(config);
387 } else {
388 dma_channel_hw_addr(channel)->ctrl_trig = channel_config_get_ctrl_value(config);
389 }
390}
391
399 static inline void dma_channel_set_read_addr(uint channel, const volatile void *read_addr, bool trigger) {
400 if (!trigger) {
401 dma_channel_hw_addr(channel)->read_addr = (uintptr_t) read_addr;
402 } else {
403 dma_channel_hw_addr(channel)->al3_read_addr_trig = (uintptr_t) read_addr;
404 }
405}
406
414 static inline void dma_channel_set_write_addr(uint channel, volatile void *write_addr, bool trigger) {
415 if (!trigger) {
416 dma_channel_hw_addr(channel)->write_addr = (uintptr_t) write_addr;
417 } else {
418 dma_channel_hw_addr(channel)->al2_write_addr_trig = (uintptr_t) write_addr;
419 }
420}
421
429 static inline void dma_channel_set_trans_count(uint channel, uint32_t trans_count, bool trigger) {
430 if (!trigger) {
431 dma_channel_hw_addr(channel)->transfer_count = trans_count;
432 } else {
433 dma_channel_hw_addr(channel)->al1_transfer_count_trig = trans_count;
434 }
435}
436
447 static inline void dma_channel_configure(uint channel, const dma_channel_config *config, volatile void *write_addr,
448 const volatile void *read_addr,
449 uint transfer_count, bool trigger) {
450 dma_channel_set_read_addr(channel, read_addr, false);
451 dma_channel_set_write_addr(channel, write_addr, false);
452 dma_channel_set_trans_count(channel, transfer_count, false);
453 dma_channel_set_config(channel, config, trigger);
454}
455
463 inline static void __attribute__((always_inline)) dma_channel_transfer_from_buffer_now(uint channel,
464 const volatile void *read_addr,
465 uint32_t transfer_count) {
466// check_dma_channel_param(channel);
467 dma_channel_hw_t *hw = dma_channel_hw_addr(channel);
468 hw->read_addr = (uintptr_t) read_addr;
469 hw->al1_transfer_count_trig = transfer_count;
470}
471
479 inline static void dma_channel_transfer_to_buffer_now(uint channel, volatile void *write_addr, uint32_t transfer_count) {
480 dma_channel_hw_t *hw = dma_channel_hw_addr(channel);
481 hw->write_addr = (uintptr_t) write_addr;
482 hw->al1_transfer_count_trig = transfer_count;
483}
484
490 static inline void dma_start_channel_mask(uint32_t chan_mask) {
491 valid_params_if(HARDWARE_DMA, chan_mask && chan_mask < (1u << NUM_DMA_CHANNELS));
492 dma_hw->multi_channel_trigger = chan_mask;
493}
494
500 static inline void dma_channel_start(uint channel) {
501 dma_start_channel_mask(1u << channel);
502}
503
544 static inline void dma_channel_abort(uint channel) {
545 check_dma_channel_param(channel);
546 dma_hw->abort = 1u << channel;
547 // Bit will go 0 once channel has reached safe state
548 // (i.e. any in-flight transfers have retired)
549 while (dma_hw->ch[channel].ctrl_trig & DMA_CH0_CTRL_TRIG_BUSY_BITS) tight_loop_contents();
550}
551
558 static inline void dma_channel_set_irq0_enabled(uint channel, bool enabled) {
559 check_dma_channel_param(channel);
560 check_hw_layout(dma_hw_t, inte0, DMA_INTE0_OFFSET);
561 if (enabled)
562 hw_set_bits(&dma_hw->inte0, 1u << channel);
563 else
564 hw_clear_bits(&dma_hw->inte0, 1u << channel);
565}
566
573 static inline void dma_set_irq0_channel_mask_enabled(uint32_t channel_mask, bool enabled) {
574 if (enabled) {
575 hw_set_bits(&dma_hw->inte0, channel_mask);
576 } else {
577 hw_clear_bits(&dma_hw->inte0, channel_mask);
578 }
579}
580
587 static inline void dma_channel_set_irq1_enabled(uint channel, bool enabled) {
588 check_dma_channel_param(channel);
589 check_hw_layout(dma_hw_t, inte1, DMA_INTE1_OFFSET);
590 if (enabled)
591 hw_set_bits(&dma_hw->inte1, 1u << channel);
592 else
593 hw_clear_bits(&dma_hw->inte1, 1u << channel);
594}
595
602 static inline void dma_set_irq1_channel_mask_enabled(uint32_t channel_mask, bool enabled) {
603 if (enabled) {
604 hw_set_bits(&dma_hw->inte1, channel_mask);
605 } else {
606 hw_clear_bits(&dma_hw->inte1, channel_mask);
607 }
608}
609
617 static inline void dma_irqn_set_channel_enabled(uint irq_index, uint channel, bool enabled) {
618 invalid_params_if(HARDWARE_DMA, irq_index >= NUM_DMA_IRQS);
619
620 if (enabled)
621 hw_set_bits(&dma_hw->irq_ctrl[irq_index].inte, 1u << channel);
622 else
623 hw_clear_bits(&dma_hw->irq_ctrl[irq_index].inte, 1u << channel);
624}
625
633 static inline void dma_irqn_set_channel_mask_enabled(uint irq_index, uint32_t channel_mask, bool enabled) {
634 invalid_params_if(HARDWARE_DMA, irq_index >= NUM_DMA_IRQS);
635 if (enabled) {
636 hw_set_bits(&dma_hw->irq_ctrl[irq_index].inte, channel_mask);
637 } else {
638 hw_clear_bits(&dma_hw->irq_ctrl[irq_index].inte, channel_mask);
639 }
640}
641
648 static inline bool dma_channel_get_irq0_status(uint channel) {
649 check_dma_channel_param(channel);
650 return dma_hw->ints0 & (1u << channel);
651}
652
659 static inline bool dma_channel_get_irq1_status(uint channel) {
660 check_dma_channel_param(channel);
661 return dma_hw->ints1 & (1u << channel);
662}
663
671 static inline bool dma_irqn_get_channel_status(uint irq_index, uint channel) {
672 invalid_params_if(HARDWARE_DMA, irq_index >= NUM_DMA_IRQS);
673 check_dma_channel_param(channel);
674 return dma_hw->irq_ctrl[irq_index].ints & (1u << channel);
675}
676
682 static inline void dma_channel_acknowledge_irq0(uint channel) {
683 check_dma_channel_param(channel);
684 dma_hw->ints0 = 1u << channel;
685}
686
692 static inline void dma_channel_acknowledge_irq1(uint channel) {
693 check_dma_channel_param(channel);
694 dma_hw->ints1 = 1u << channel;
695}
696
703 static inline void dma_irqn_acknowledge_channel(uint irq_index, uint channel) {
704 invalid_params_if(HARDWARE_DMA, irq_index >= NUM_DMA_IRQS);
705 check_dma_channel_param(channel);
706 dma_hw->irq_ctrl[irq_index].ints = 1u << channel;
707}
708
715 inline static bool dma_channel_is_busy(uint channel) {
716 check_dma_channel_param(channel);
717 return dma_hw->ch[channel].al1_ctrl & DMA_CH0_CTRL_TRIG_BUSY_BITS;
718}
719
725 inline static void dma_channel_wait_for_finish_blocking(uint channel) {
726 while (dma_channel_is_busy(channel)) tight_loop_contents();
727 // stop the compiler hoisting a non-volatile buffer access above the DMA completion.
728 __compiler_memory_barrier();
729}
730
751 inline static void dma_sniffer_enable(uint channel, uint mode, bool force_channel_enable) {
752 check_dma_channel_param(channel);
753 check_hw_layout(dma_hw_t, sniff_ctrl, DMA_SNIFF_CTRL_OFFSET);
754 if (force_channel_enable) {
755 hw_set_bits(&dma_hw->ch[channel].al1_ctrl, DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
756 }
757 hw_write_masked(&dma_hw->sniff_ctrl,
758 (((channel << DMA_SNIFF_CTRL_DMACH_LSB) & DMA_SNIFF_CTRL_DMACH_BITS) |
759 ((mode << DMA_SNIFF_CTRL_CALC_LSB) & DMA_SNIFF_CTRL_CALC_BITS) |
760 DMA_SNIFF_CTRL_EN_BITS),
761 (DMA_SNIFF_CTRL_DMACH_BITS |
762 DMA_SNIFF_CTRL_CALC_BITS |
763 DMA_SNIFF_CTRL_EN_BITS));
764}
765
777 inline static void dma_sniffer_set_byte_swap_enabled(bool swap) {
778 if (swap)
779 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_BSWAP_BITS);
780 else
781 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_BSWAP_BITS);
782}
783
792 inline static void dma_sniffer_set_output_invert_enabled(bool invert) {
793 if (invert)
794 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_INV_BITS);
795 else
796 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_INV_BITS);
797}
798
807 inline static void dma_sniffer_set_output_reverse_enabled(bool reverse) {
808 if (reverse)
809 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_REV_BITS);
810 else
811 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_REV_BITS);
812}
813
818 inline static void dma_sniffer_disable(void) {
819 dma_hw->sniff_ctrl = 0;
820}
821
830 inline static void dma_sniffer_set_data_accumulator(uint32_t seed_value) {
831 dma_hw->sniff_data = seed_value;
832}
833
839 inline static uint32_t dma_sniffer_get_data_accumulator(void) {
840 return dma_hw->sniff_data;
841}
842
852void dma_timer_claim(uint timer);
853
861void dma_timer_unclaim(uint timer);
862
869int dma_claim_unused_timer(bool required);
870
878bool dma_timer_is_claimed(uint timer);
879
891 static inline void dma_timer_set_fraction(uint timer, uint16_t numerator, uint16_t denominator) {
892 check_dma_timer_param(timer);
893 invalid_params_if(HARDWARE_DMA, numerator > denominator);
894 dma_hw->timer[timer] = (((uint32_t)numerator) << DMA_TIMER0_X_LSB) | (((uint32_t)denominator) << DMA_TIMER0_Y_LSB);
895}
896
902 static inline uint dma_get_timer_dreq(uint timer_num) {
903 static_assert(DREQ_DMA_TIMER1 == DREQ_DMA_TIMER0 + 1, "");
904 static_assert(DREQ_DMA_TIMER2 == DREQ_DMA_TIMER0 + 2, "");
905 static_assert(DREQ_DMA_TIMER3 == DREQ_DMA_TIMER0 + 3, "");
906 check_dma_timer_param(timer_num);
907 return DREQ_DMA_TIMER0 + timer_num;
908}
909
916 static inline int dma_get_irq_num(uint irq_index) {
917 valid_params_if(HARDWARE_DMA, irq_index < NUM_DMA_IRQS);
918 return DMA_IRQ_NUM(irq_index);
919}
920
938void dma_channel_cleanup(uint channel);
939
940#ifndef NDEBUG
941void print_dma_ctrl(dma_channel_hw_t *channel);
942#endif
943
944#ifdef __cplusplus
945}
946#endif
947
948#endif
channel_config_set_high_priority
static void channel_config_set_high_priority(dma_channel_config *c, bool high_priority)
Set the channel priority in a channel configuration object.
Definition: dma.h:286
channel_config_set_read_increment
static void channel_config_set_read_increment(dma_channel_config *c, bool incr)
Set DMA channel read increment in a channel configuration object.
Definition: dma.h:160
dma_get_channel_config
static dma_channel_config dma_get_channel_config(uint channel)
Get the current configuration for the specified channel.
Definition: dma.h:360
dma_channel_get_default_config
static dma_channel_config dma_channel_get_default_config(uint channel)
Get the default channel configuration for a given channel.
Definition: dma.h:338
channel_config_set_bswap
static void channel_config_set_bswap(dma_channel_config *c, bool bswap)
Set DMA byte swapping config in a channel configuration object.
Definition: dma.h:254
channel_config_set_sniff_enable
static void channel_config_set_sniff_enable(dma_channel_config *c, bool sniff_enable)
Enable access to channel by sniff hardware in a channel configuration object.
Definition: dma.h:313
channel_config_set_dreq
static void channel_config_set_dreq(dma_channel_config *c, uint dreq)
Select a transfer request signal in a channel configuration object.
Definition: dma.h:190
channel_config_set_chain_to
static void channel_config_set_chain_to(dma_channel_config *c, uint chain_to)
Set DMA channel chain_to channel in a channel configuration object.
Definition: dma.h:204
channel_config_get_ctrl_value
static uint32_t channel_config_get_ctrl_value(const dma_channel_config *config)
Get the raw configuration register from a channel configuration.
Definition: dma.h:372
channel_config_set_write_increment
static void channel_config_set_write_increment(dma_channel_config *c, bool incr)
Set DMA channel write increment in a channel configuration object.
Definition: dma.h:171
channel_config_set_irq_quiet
static void channel_config_set_irq_quiet(dma_channel_config *c, bool irq_quiet)
Set IRQ quiet mode in a channel configuration object.
Definition: dma.h:268
channel_config_set_enable
static void channel_config_set_enable(dma_channel_config *c, bool enable)
Enable/Disable the DMA channel in a channel configuration object.
Definition: dma.h:301
channel_config_set_transfer_data_size
static void channel_config_set_transfer_data_size(dma_channel_config *c, enum dma_channel_transfer_size size)
Set the size of each DMA bus transfer in a channel configuration object.
Definition: dma.h:218
channel_config_set_ring
static void channel_config_set_ring(dma_channel_config *c, bool write, uint size_bits)
Set address wrapping parameters in a channel configuration object.
Definition: dma.h:238
hw_set_bits
static __force_inline void hw_set_bits(io_rw_32 *addr, uint32_t mask)
Atomically set the specified bits to 1 in a HW register.
Definition: address_mapped.h:135
hw_write_masked
static __force_inline void hw_write_masked(io_rw_32 *addr, uint32_t values, uint32_t write_mask)
Set new values for a sub-set of the bits in a HW register.
Definition: address_mapped.h:171
hw_clear_bits
static __force_inline void hw_clear_bits(io_rw_32 *addr, uint32_t mask)
Atomically clear the specified bits to 0 in a HW register.
Definition: address_mapped.h:145
dma_unclaim_mask
void dma_unclaim_mask(uint32_t channel_mask)
Mark multiple dma channels as no longer used.
Definition: dma.c:39
dma_sniffer_enable
static void dma_sniffer_enable(uint channel, uint mode, bool force_channel_enable)
Enable the DMA sniffing targeting the specified channel.
Definition: dma.h:751
dma_timer_claim
void dma_timer_claim(uint timer)
Mark a dma timer as used.
Definition: dma.c:54
dma_sniffer_set_output_invert_enabled
static void dma_sniffer_set_output_invert_enabled(bool invert)
Enable the Sniffer output invert function.
Definition: dma.h:792
dma_channel_set_trans_count
static void dma_channel_set_trans_count(uint channel, uint32_t trans_count, bool trigger)
Set the number of bus transfers the channel will do.
Definition: dma.h:429
dma_claim_unused_timer
int dma_claim_unused_timer(bool required)
Claim a free dma timer.
Definition: dma.c:64
dma_sniffer_get_data_accumulator
static uint32_t dma_sniffer_get_data_accumulator(void)
Get the sniffer's data accumulator value.
Definition: dma.h:839
dma_channel_start
static void dma_channel_start(uint channel)
Start a single DMA channel.
Definition: dma.h:500
dma_irqn_get_channel_status
static bool dma_irqn_get_channel_status(uint irq_index, uint channel)
Determine if a particular channel is a cause of DMA_IRQ_N.
Definition: dma.h:671
dma_claim_unused_channel
int dma_claim_unused_channel(bool required)
Claim a free dma channel.
Definition: dma.c:45
dma_channel_acknowledge_irq1
static void dma_channel_acknowledge_irq1(uint channel)
Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_1.
Definition: dma.h:692
dma_channel_set_irq1_enabled
static void dma_channel_set_irq1_enabled(uint channel, bool enabled)
Enable single DMA channel's interrupt via DMA_IRQ_1.
Definition: dma.h:587
dma_timer_set_fraction
static void dma_timer_set_fraction(uint timer, uint16_t numerator, uint16_t denominator)
Set the multiplier for the given DMA timer.
Definition: dma.h:891
dma_get_irq_num
static int dma_get_irq_num(uint irq_index)
Return DMA_IRQ_<irqn>
Definition: dma.h:916
dma_start_channel_mask
static void dma_start_channel_mask(uint32_t chan_mask)
Start one or more channels simultaneously.
Definition: dma.h:490
dma_channel_cleanup
void dma_channel_cleanup(uint channel)
Performs DMA channel cleanup after use.
Definition: dma.c:73
DMA_IRQ_NUM
#define DMA_IRQ_NUM(irq_index)
Returns the irq_num_t for the nth DMA interrupt.
Definition: dma.h:56
dma_irqn_set_channel_enabled
static void dma_irqn_set_channel_enabled(uint irq_index, uint channel, bool enabled)
Enable single DMA channel interrupt on either DMA_IRQ_0 or DMA_IRQ_1.
Definition: dma.h:617
dma_irqn_set_channel_mask_enabled
static void dma_irqn_set_channel_mask_enabled(uint irq_index, uint32_t channel_mask, bool enabled)
Enable multiple DMA channels' interrupt via either DMA_IRQ_0 or DMA_IRQ_1.
Definition: dma.h:633
dma_channel_abort
static void dma_channel_abort(uint channel)
Stop a DMA transfer.
Definition: dma.h:544
dma_channel_set_config
static void dma_channel_set_config(uint channel, const dma_channel_config *config, bool trigger)
Set a channel configuration.
Definition: dma.h:383
dma_get_timer_dreq
static uint dma_get_timer_dreq(uint timer_num)
Return the DREQ number for a given DMA timer.
Definition: dma.h:902
dma_timer_unclaim
void dma_timer_unclaim(uint timer)
Mark a dma timer as no longer used.
Definition: dma.c:59
dma_channel_transfer_to_buffer_now
static void dma_channel_transfer_to_buffer_now(uint channel, volatile void *write_addr, uint32_t transfer_count)
Start a DMA transfer to a buffer immediately.
Definition: dma.h:479
dma_channel_configure
static void dma_channel_configure(uint channel, const dma_channel_config *config, volatile void *write_addr, const volatile void *read_addr, uint transfer_count, bool trigger)
Configure all DMA parameters and optionally start transfer.
Definition: dma.h:447
dma_channel_is_claimed
bool dma_channel_is_claimed(uint channel)
Determine if a dma channel is claimed.
Definition: dma.c:49
dma_timer_is_claimed
bool dma_timer_is_claimed(uint timer)
Determine if a dma timer is claimed.
Definition: dma.c:68
dma_sniffer_disable
static void dma_sniffer_disable(void)
Disable the DMA sniffer.
Definition: dma.h:818
dma_sniffer_set_output_reverse_enabled
static void dma_sniffer_set_output_reverse_enabled(bool reverse)
Enable the Sniffer output bit reversal function.
Definition: dma.h:807
dma_claim_mask
void dma_claim_mask(uint32_t channel_mask)
Mark multiple dma channels as used.
Definition: dma.c:28
dma_channel_get_irq0_status
static bool dma_channel_get_irq0_status(uint channel)
Determine if a particular channel is a cause of DMA_IRQ_0.
Definition: dma.h:648
dma_set_irq1_channel_mask_enabled
static void dma_set_irq1_channel_mask_enabled(uint32_t channel_mask, bool enabled)
Enable multiple DMA channels' interrupts via DMA_IRQ_1.
Definition: dma.h:602
dma_channel_wait_for_finish_blocking
static void dma_channel_wait_for_finish_blocking(uint channel)
Wait for a DMA channel transfer to complete.
Definition: dma.h:725
dma_channel_transfer_from_buffer_now
static void dma_channel_transfer_from_buffer_now(uint channel, const volatile void *read_addr, uint32_t transfer_count)
Start a DMA transfer from a buffer immediately.
Definition: dma.h:463
dma_channel_set_read_addr
static void dma_channel_set_read_addr(uint channel, const volatile void *read_addr, bool trigger)
Set the DMA initial read address.
Definition: dma.h:399
dma_sniffer_set_byte_swap_enabled
static void dma_sniffer_set_byte_swap_enabled(bool swap)
Enable the Sniffer byte swap function.
Definition: dma.h:777
dma_channel_unclaim
void dma_channel_unclaim(uint channel)
Mark a dma channel as no longer used.
Definition: dma.c:34
dma_sniffer_set_data_accumulator
static void dma_sniffer_set_data_accumulator(uint32_t seed_value)
Set the sniffer's data accumulator with initial value.
Definition: dma.h:830
dma_channel_transfer_size
dma_channel_transfer_size
Enumeration of available DMA channel transfer sizes.
Definition: dma.h:143
dma_irqn_acknowledge_channel
static void dma_irqn_acknowledge_channel(uint irq_index, uint channel)
Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_N.
Definition: dma.h:703
dma_set_irq0_channel_mask_enabled
static void dma_set_irq0_channel_mask_enabled(uint32_t channel_mask, bool enabled)
Enable multiple DMA channels' interrupts via DMA_IRQ_0.
Definition: dma.h:573
dma_channel_claim
void dma_channel_claim(uint channel)
Mark a dma channel as used.
Definition: dma.c:23
dma_channel_set_write_addr
static void dma_channel_set_write_addr(uint channel, volatile void *write_addr, bool trigger)
Set the DMA initial write address.
Definition: dma.h:414
dma_channel_set_irq0_enabled
static void dma_channel_set_irq0_enabled(uint channel, bool enabled)
Enable single DMA channel's interrupt via DMA_IRQ_0.
Definition: dma.h:558
dma_channel_get_irq1_status
static bool dma_channel_get_irq1_status(uint channel)
Determine if a particular channel is a cause of DMA_IRQ_1.
Definition: dma.h:659
dma_channel_is_busy
static bool dma_channel_is_busy(uint channel)
Check if DMA channel is busy.
Definition: dma.h:715
dma_channel_acknowledge_irq0
static void dma_channel_acknowledge_irq0(uint channel)
Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_0.
Definition: dma.h:682
DREQ_DMA_TIMER1
@ DREQ_DMA_TIMER1
Select DMA_TIMER0 as DREQ.
Definition: dreq.h:138
DREQ_DMA_TIMER0
@ DREQ_DMA_TIMER0
Select DMA_TIMER0 as DREQ.
Definition: dreq.h:137
DREQ_DMA_TIMER3
@ DREQ_DMA_TIMER3
Select DMA_TIMER3 as DREQ.
Definition: dreq.h:140
DREQ_DMA_TIMER2
@ DREQ_DMA_TIMER2
Select DMA_TIMER1 as DREQ.
Definition: dreq.h:139
DREQ_FORCE
@ DREQ_FORCE
Select FORCE as DREQ.
Definition: dreq.h:141
DMA_SIZE_16
@ DMA_SIZE_16
Half word transfer (16 bits)
Definition: dma.h:145
DMA_SIZE_8
@ DMA_SIZE_8
Byte transfer (8 bits)
Definition: dma.h:144
DMA_SIZE_32
@ DMA_SIZE_32
Word transfer (32 bits)
Definition: dma.h:146
tight_loop_contents
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:67
__compiler_memory_barrier
static __always_inline void __compiler_memory_barrier(void)
Ensure that the compiler does not move memory access across this method call.
Definition: compiler.h:171
pico.h
dma_channel_config
Definition: dma.h:149
dma_channel_hw_t
Definition: dma.h:27
dma_hw_t
Definition: dma.h:146