Loading...
Searching...
No Matches
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
37
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
137
148
160
164typedef struct {
165 uint32_t ctrl;
167
168// backwards compatibility
169typedef dma_channel_config_t dma_channel_config;
170
171#ifndef DMA_ADDRESS_UPDATE_TYPE_TO_DMA_CH_CTRL_READ_BITS
172#if PICO_RP2040
173#define DMA_ADDRESS_UPDATE_TYPE_TO_DMA_CH_CTRL_READ_BITS(u) (((u)&1) << DMA_CH0_CTRL_TRIG_INCR_READ_LSB)
174#else
175#define DMA_ADDRESS_UPDATE_TYPE_TO_DMA_CH_CTRL_READ_BITS(u) \
176 ((((u)&1) << DMA_CH0_CTRL_TRIG_INCR_READ_LSB) | \
177 (((u)&2) << (DMA_CH0_CTRL_TRIG_INCR_READ_REV_LSB - 1)))
178#endif
179#endif
180
181#ifndef DMA_ADDRESS_UPDATE_TYPE_TO_DMA_CH_CTRL_WRITE_BITS
182#if PICO_RP2040
183#define DMA_ADDRESS_UPDATE_TYPE_TO_DMA_CH_CTRL_WRITE_BITS(u) (((u)&1) << DMA_CH0_CTRL_TRIG_INCR_WRITE_LSB)
184#else
185#define DMA_ADDRESS_UPDATE_TYPE_TO_DMA_CH_CTRL_WRITE_BITS(u) \
186((((u)&1) << DMA_CH0_CTRL_TRIG_INCR_WRITE_LSB) | \
187(((u)&2) << (DMA_CH0_CTRL_TRIG_INCR_WRITE_REV_LSB - 1)))
188#endif
189#endif
190
191#ifndef DMA_CH_CTRL_ALL_ADDRESS_UPDATE_READ_BITS
192#if PICO_RP2040
193#define DMA_CH_CTRL_ALL_ADDRESS_UPDATE_READ_BITS DMA_CH0_CTRL_TRIG_INCR_READ_BITS
194#else
195#define DMA_CH_CTRL_ALL_ADDRESS_UPDATE_READ_BITS (DMA_CH0_CTRL_TRIG_INCR_READ_BITS | DMA_CH0_CTRL_TRIG_INCR_READ_REV_BITS)
196#endif
197#endif
198
199#ifndef DMA_CH_CTRL_ALL_ADDRESS_UPDATE_WRITE_BITS
200#if PICO_RP2040
201#define DMA_CH_CTRL_ALL_ADDRESS_UPDATE_WRITE_BITS DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS
202#else
203#define DMA_CH_CTRL_ALL_ADDRESS_UPDATE_WRITE_BITS (DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS | DMA_CH0_CTRL_TRIG_INCR_WRITE_REV_BITS)
204#endif
205#endif
206
216 c->ctrl = (c->ctrl & ~DMA_CH_CTRL_ALL_ADDRESS_UPDATE_READ_BITS) |
217 DMA_ADDRESS_UPDATE_TYPE_TO_DMA_CH_CTRL_READ_BITS(update_type);
218}
219
229 c->ctrl = (c->ctrl & ~DMA_CH_CTRL_ALL_ADDRESS_UPDATE_WRITE_BITS) |
230 DMA_ADDRESS_UPDATE_TYPE_TO_DMA_CH_CTRL_WRITE_BITS(update_type);
231}
232
249
266
282static inline void channel_config_set_dreq(dma_channel_config_t *c, uint dreq) {
283 assert(dreq <= DREQ_FORCE);
284 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_TREQ_SEL_BITS) | (dreq << DMA_CH0_CTRL_TRIG_TREQ_SEL_LSB);
285}
286
296static inline void channel_config_set_chain_to(dma_channel_config_t *c, uint chain_to) {
297 assert(chain_to <= NUM_DMA_CHANNELS);
298 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (chain_to << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB);
299}
300
311 assert(size == DMA_SIZE_8 || size == DMA_SIZE_16 || size == DMA_SIZE_32);
312 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_DATA_SIZE_BITS) | (((uint)size) << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB);
313}
314
330static inline void channel_config_set_ring(dma_channel_config_t *c, bool write, uint size_bits) {
331 assert(size_bits < 32);
332 c->ctrl = (c->ctrl & ~(DMA_CH0_CTRL_TRIG_RING_SIZE_BITS | DMA_CH0_CTRL_TRIG_RING_SEL_BITS)) |
333 (size_bits << DMA_CH0_CTRL_TRIG_RING_SIZE_LSB) |
334 (write ? DMA_CH0_CTRL_TRIG_RING_SEL_BITS : 0);
335}
336
346static inline void channel_config_set_bswap(dma_channel_config_t *c, bool bswap) {
347 c->ctrl = bswap ? (c->ctrl | DMA_CH0_CTRL_TRIG_BSWAP_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_BSWAP_BITS);
348}
349
360static inline void channel_config_set_irq_quiet(dma_channel_config_t *c, bool irq_quiet) {
361 c->ctrl = irq_quiet ? (c->ctrl | DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS);
362}
363
378static inline void channel_config_set_high_priority(dma_channel_config_t *c, bool high_priority) {
379 c->ctrl = high_priority ? (c->ctrl | DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS);
380}
381
393static inline void channel_config_set_enable(dma_channel_config_t *c, bool enable) {
394 c->ctrl = enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_EN_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_EN_BITS);
395}
396
405static inline void channel_config_set_sniff_enable(dma_channel_config_t *c, bool sniff_enable) {
406 c->ctrl = sniff_enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS) : (c->ctrl &
407 ~DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
408}
409
445
452static inline dma_channel_config_t dma_get_channel_config(uint channel) {
454 c.ctrl = dma_channel_hw_addr(channel)->ctrl_trig;
455 return c;
456}
457
464static inline uint32_t channel_config_get_ctrl_value(const dma_channel_config_t *config) {
465 return config->ctrl;
466}
467
475static inline void dma_channel_set_config(uint channel, const dma_channel_config_t *config, bool trigger) {
476 // Don't use CTRL_TRIG since we don't want to start a transfer
477 if (!trigger) {
478 dma_channel_hw_addr(channel)->al1_ctrl = channel_config_get_ctrl_value(config);
479 } else {
480 dma_channel_hw_addr(channel)->ctrl_trig = channel_config_get_ctrl_value(config);
481 }
482}
483
491static inline void dma_channel_set_read_addr(uint channel, const volatile void *read_addr, bool trigger) {
492 if (!trigger) {
493 dma_channel_hw_addr(channel)->read_addr = (uintptr_t) read_addr;
494 } else {
495 dma_channel_hw_addr(channel)->al3_read_addr_trig = (uintptr_t) read_addr;
496 }
497}
498
506static inline void dma_channel_set_write_addr(uint channel, volatile void *write_addr, bool trigger) {
507 if (!trigger) {
508 dma_channel_hw_addr(channel)->write_addr = (uintptr_t) write_addr;
509 } else {
510 dma_channel_hw_addr(channel)->al2_write_addr_trig = (uintptr_t) write_addr;
511 }
512}
513
531static inline uint32_t dma_encode_transfer_count(uint transfer_count) {
532#if !PICO_RP2040
533 invalid_params_if(HARDWARE_DMA, transfer_count & DMA_CH0_TRANS_COUNT_MODE_BITS);
534 return transfer_count & DMA_CH0_TRANS_COUNT_COUNT_BITS;
535#else
536 return transfer_count;
537#endif
538}
539
557static inline uint32_t dma_encode_transfer_count_with_self_trigger(uint transfer_count) {
558#if PICO_RP2040
559 (void)transfer_count;
561#else
562 return dma_encode_transfer_count(transfer_count) | (DMA_CH0_TRANS_COUNT_MODE_VALUE_TRIGGER_SELF << DMA_CH0_TRANS_COUNT_MODE_LSB);
563#endif
564}
565
578static inline uint32_t dma_encode_endless_transfer_count(void) {
579#if PICO_RP2040
581#else
582 static_assert(DMA_CH0_TRANS_COUNT_MODE_VALUE_ENDLESS == 0xf, "");
583 static_assert(DMA_CH0_TRANS_COUNT_MODE_LSB == 28, "");
584 return 0xffffffffu;
585#endif
586}
587
606static inline void dma_channel_set_transfer_count(uint channel, uint32_t encoded_transfer_count, bool trigger) {
607 if (!trigger) {
608 dma_channel_hw_addr(channel)->transfer_count = encoded_transfer_count;
609 } else {
610 dma_channel_hw_addr(channel)->al1_transfer_count_trig = encoded_transfer_count;
611 }
612}
613
614// backwards compatibility with SDK < 2.2.0
615static inline void dma_channel_set_trans_count(uint channel, uint32_t trans_count, bool trigger) {
616 dma_channel_set_transfer_count(channel, trans_count, trigger);
617}
618
640static inline void dma_channel_configure(uint channel, const dma_channel_config_t *config, volatile void *write_addr,
641 const volatile void *read_addr,
642 uint32_t encoded_transfer_count, bool trigger) {
643 dma_channel_set_read_addr(channel, read_addr, false);
644 dma_channel_set_write_addr(channel, write_addr, false);
645 dma_channel_set_transfer_count(channel, encoded_transfer_count, false);
646 dma_channel_set_config(channel, config, trigger);
647}
648
667inline static void __attribute__((always_inline)) dma_channel_transfer_from_buffer_now(uint channel,
668 const volatile void *read_addr,
669 uint32_t encoded_transfer_count) {
670// check_dma_channel_param(channel);
671 dma_channel_hw_t *hw = dma_channel_hw_addr(channel);
672 hw->read_addr = (uintptr_t) read_addr;
673 hw->al1_transfer_count_trig = encoded_transfer_count;
674}
675
694inline static void dma_channel_transfer_to_buffer_now(uint channel, volatile void *write_addr, uint32_t encoded_transfer_count) {
695 dma_channel_hw_t *hw = dma_channel_hw_addr(channel);
696 hw->write_addr = (uintptr_t) write_addr;
697 hw->al1_transfer_count_trig = encoded_transfer_count;
698}
699
705static inline void dma_start_channel_mask(uint32_t chan_mask) {
706 valid_params_if(HARDWARE_DMA, chan_mask && chan_mask < (1u << NUM_DMA_CHANNELS));
707 dma_hw->multi_channel_trigger = chan_mask;
708}
709
715static inline void dma_channel_start(uint channel) {
716 dma_start_channel_mask(1u << channel);
717}
718
759static inline void dma_channel_abort(uint channel) {
760 check_dma_channel_param(channel);
761 dma_hw->abort = 1u << channel;
762 // Bit will go 0 once channel has reached safe state
763 // (i.e. any in-flight transfers have retired)
764 while (dma_hw->ch[channel].ctrl_trig & DMA_CH0_CTRL_TRIG_BUSY_BITS) tight_loop_contents();
765}
766
773static inline void dma_channel_set_irq0_enabled(uint channel, bool enabled) {
774 check_dma_channel_param(channel);
775 check_hw_layout(dma_hw_t, inte0, DMA_INTE0_OFFSET);
776 if (enabled)
777 hw_set_bits(&dma_hw->inte0, 1u << channel);
778 else
779 hw_clear_bits(&dma_hw->inte0, 1u << channel);
780}
781
788static inline void dma_set_irq0_channel_mask_enabled(uint32_t channel_mask, bool enabled) {
789 if (enabled) {
790 hw_set_bits(&dma_hw->inte0, channel_mask);
791 } else {
792 hw_clear_bits(&dma_hw->inte0, channel_mask);
793 }
794}
795
802static inline void dma_channel_set_irq1_enabled(uint channel, bool enabled) {
803 check_dma_channel_param(channel);
804 check_hw_layout(dma_hw_t, inte1, DMA_INTE1_OFFSET);
805 if (enabled)
806 hw_set_bits(&dma_hw->inte1, 1u << channel);
807 else
808 hw_clear_bits(&dma_hw->inte1, 1u << channel);
809}
810
817static inline void dma_set_irq1_channel_mask_enabled(uint32_t channel_mask, bool enabled) {
818 if (enabled) {
819 hw_set_bits(&dma_hw->inte1, channel_mask);
820 } else {
821 hw_clear_bits(&dma_hw->inte1, channel_mask);
822 }
823}
824
832static inline void dma_irqn_set_channel_enabled(uint irq_index, uint channel, bool enabled) {
833 invalid_params_if(HARDWARE_DMA, irq_index >= NUM_DMA_IRQS);
834
835 if (enabled)
836 hw_set_bits(&dma_hw->irq_ctrl[irq_index].inte, 1u << channel);
837 else
838 hw_clear_bits(&dma_hw->irq_ctrl[irq_index].inte, 1u << channel);
839}
840
848static inline void dma_irqn_set_channel_mask_enabled(uint irq_index, uint32_t channel_mask, bool enabled) {
849 invalid_params_if(HARDWARE_DMA, irq_index >= NUM_DMA_IRQS);
850 if (enabled) {
851 hw_set_bits(&dma_hw->irq_ctrl[irq_index].inte, channel_mask);
852 } else {
853 hw_clear_bits(&dma_hw->irq_ctrl[irq_index].inte, channel_mask);
854 }
855}
856
863static inline bool dma_channel_get_irq0_status(uint channel) {
864 check_dma_channel_param(channel);
865 return dma_hw->ints0 & (1u << channel);
866}
867
874static inline bool dma_channel_get_irq1_status(uint channel) {
875 check_dma_channel_param(channel);
876 return dma_hw->ints1 & (1u << channel);
877}
878
886static inline bool dma_irqn_get_channel_status(uint irq_index, uint channel) {
887 invalid_params_if(HARDWARE_DMA, irq_index >= NUM_DMA_IRQS);
888 check_dma_channel_param(channel);
889 return dma_hw->irq_ctrl[irq_index].ints & (1u << channel);
890}
891
897static inline void dma_channel_acknowledge_irq0(uint channel) {
898 check_dma_channel_param(channel);
899 dma_hw->ints0 = 1u << channel;
900}
901
907static inline void dma_channel_acknowledge_irq1(uint channel) {
908 check_dma_channel_param(channel);
909 dma_hw->ints1 = 1u << channel;
910}
911
918static inline void dma_irqn_acknowledge_channel(uint irq_index, uint channel) {
919 invalid_params_if(HARDWARE_DMA, irq_index >= NUM_DMA_IRQS);
920 check_dma_channel_param(channel);
921 dma_hw->irq_ctrl[irq_index].ints = 1u << channel;
922}
923
930inline static bool dma_channel_is_busy(uint channel) {
931 check_dma_channel_param(channel);
932 return dma_hw->ch[channel].al1_ctrl & DMA_CH0_CTRL_TRIG_BUSY_BITS;
933}
934
940inline static void dma_channel_wait_for_finish_blocking(uint channel) {
941 while (dma_channel_is_busy(channel)) tight_loop_contents();
942 // stop the compiler hoisting a non-volatile buffer access above the DMA completion.
944}
945
966inline static void dma_sniffer_enable(uint channel, uint mode, bool force_channel_enable) {
967 check_dma_channel_param(channel);
968 check_hw_layout(dma_hw_t, sniff_ctrl, DMA_SNIFF_CTRL_OFFSET);
969 if (force_channel_enable) {
970 hw_set_bits(&dma_hw->ch[channel].al1_ctrl, DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
971 }
972 hw_write_masked(&dma_hw->sniff_ctrl,
973 (((channel << DMA_SNIFF_CTRL_DMACH_LSB) & DMA_SNIFF_CTRL_DMACH_BITS) |
974 ((mode << DMA_SNIFF_CTRL_CALC_LSB) & DMA_SNIFF_CTRL_CALC_BITS) |
975 DMA_SNIFF_CTRL_EN_BITS),
976 (DMA_SNIFF_CTRL_DMACH_BITS |
977 DMA_SNIFF_CTRL_CALC_BITS |
978 DMA_SNIFF_CTRL_EN_BITS));
979}
980
992inline static void dma_sniffer_set_byte_swap_enabled(bool swap) {
993 if (swap)
994 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_BSWAP_BITS);
995 else
996 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_BSWAP_BITS);
997}
998
1007inline static void dma_sniffer_set_output_invert_enabled(bool invert) {
1008 if (invert)
1009 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_INV_BITS);
1010 else
1011 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_INV_BITS);
1012}
1013
1022inline static void dma_sniffer_set_output_reverse_enabled(bool reverse) {
1023 if (reverse)
1024 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_REV_BITS);
1025 else
1026 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_REV_BITS);
1027}
1028
1033inline static void dma_sniffer_disable(void) {
1034 dma_hw->sniff_ctrl = 0;
1035}
1036
1045inline static void dma_sniffer_set_data_accumulator(uint32_t seed_value) {
1046 dma_hw->sniff_data = seed_value;
1047}
1048
1054inline static uint32_t dma_sniffer_get_data_accumulator(void) {
1055 return dma_hw->sniff_data;
1056}
1057
1067void dma_timer_claim(uint timer);
1068
1076void dma_timer_unclaim(uint timer);
1077
1084int dma_claim_unused_timer(bool required);
1085
1093bool dma_timer_is_claimed(uint timer);
1094
1106static inline void dma_timer_set_fraction(uint timer, uint16_t numerator, uint16_t denominator) {
1107 check_dma_timer_param(timer);
1108 invalid_params_if(HARDWARE_DMA, numerator > denominator);
1109 dma_hw->timer[timer] = (((uint32_t)numerator) << DMA_TIMER0_X_LSB) | (((uint32_t)denominator) << DMA_TIMER0_Y_LSB);
1110}
1111
1117static inline uint dma_get_timer_dreq(uint timer_num) {
1118 static_assert(DREQ_DMA_TIMER1 == DREQ_DMA_TIMER0 + 1, "");
1119 static_assert(DREQ_DMA_TIMER2 == DREQ_DMA_TIMER0 + 2, "");
1120 static_assert(DREQ_DMA_TIMER3 == DREQ_DMA_TIMER0 + 3, "");
1121 check_dma_timer_param(timer_num);
1122 return DREQ_DMA_TIMER0 + timer_num;
1123}
1124
1131static inline int dma_get_irq_num(uint irq_index) {
1132 valid_params_if(HARDWARE_DMA, irq_index < NUM_DMA_IRQS);
1133 return DMA_IRQ_NUM(irq_index);
1134}
1135
1153void dma_channel_cleanup(uint channel);
1154
1155#ifndef NDEBUG
1156void print_dma_ctrl(dma_channel_hw_t *channel);
1157#endif
1158
1159#ifdef __cplusplus
1160}
1161#endif
1162
1163#endif
static void channel_config_set_enable(dma_channel_config_t *c, bool enable)
Enable/Disable the DMA channel in a channel configuration object.
Definition dma.h:393
static void channel_config_set_transfer_data_size(dma_channel_config_t *c, dma_channel_transfer_size_t size)
Set the size of each DMA bus transfer in a channel configuration object.
Definition dma.h:310
static void channel_config_set_bswap(dma_channel_config_t *c, bool bswap)
Set DMA byte swapping config in a channel configuration object.
Definition dma.h:346
static void channel_config_set_sniff_enable(dma_channel_config_t *c, bool sniff_enable)
Enable access to channel by sniff hardware in a channel configuration object.
Definition dma.h:405
static void channel_config_set_high_priority(dma_channel_config_t *c, bool high_priority)
Set the channel priority in a channel configuration object.
Definition dma.h:378
static void channel_config_set_read_increment(dma_channel_config_t *c, bool incr)
Set DMA channel read increment in a channel configuration object.
Definition dma.h:246
static dma_channel_config_t dma_channel_get_default_config(uint channel)
Get the default channel configuration for a given channel.
Definition dma.h:430
static void channel_config_set_read_address_update_type(dma_channel_config_t *c, dma_address_update_type_t update_type)
Set DMA channel read address update type in a channel configuration object.
Definition dma.h:215
static void channel_config_set_write_address_update_type(dma_channel_config_t *c, dma_address_update_type_t update_type)
Set DMA channel write address update type in a channel configuration object.
Definition dma.h:228
static void channel_config_set_write_increment(dma_channel_config_t *c, bool incr)
Set DMA channel write increment in a channel configuration object.
Definition dma.h:263
static uint32_t channel_config_get_ctrl_value(const dma_channel_config_t *config)
Get the raw configuration register from a channel configuration.
Definition dma.h:464
static void channel_config_set_dreq(dma_channel_config_t *c, uint dreq)
Select a transfer request signal in a channel configuration object.
Definition dma.h:282
static void channel_config_set_chain_to(dma_channel_config_t *c, uint chain_to)
Set DMA channel chain_to channel in a channel configuration object.
Definition dma.h:296
static void channel_config_set_irq_quiet(dma_channel_config_t *c, bool irq_quiet)
Set IRQ quiet mode in a channel configuration object.
Definition dma.h:360
static dma_channel_config_t dma_get_channel_config(uint channel)
Get the current configuration for the specified channel.
Definition dma.h:452
static void channel_config_set_ring(dma_channel_config_t *c, bool write, uint size_bits)
Set address wrapping parameters in a channel configuration object.
Definition dma.h:330
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
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
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
void dma_unclaim_mask(uint32_t channel_mask)
Mark multiple dma channels as no longer used.
Definition dma.c:39
static void dma_sniffer_enable(uint channel, uint mode, bool force_channel_enable)
Enable the DMA sniffing targeting the specified channel.
Definition dma.h:966
void dma_timer_claim(uint timer)
Mark a dma timer as used.
Definition dma.c:54
dma_address_update_type
Enumeration of types of updates that can be made to the DMA read or write address after each transfer...
Definition dma.h:152
static void dma_channel_set_transfer_count(uint channel, uint32_t encoded_transfer_count, bool trigger)
Set the number of bus transfers the channel will do.
Definition dma.h:606
static void dma_sniffer_set_output_invert_enabled(bool invert)
Enable the Sniffer output invert function.
Definition dma.h:1007
enum dma_address_update_type dma_address_update_type_t
Enumeration of types of updates that can be made to the DMA read or write address after each transfer...
int dma_claim_unused_timer(bool required)
Claim a free dma timer.
Definition dma.c:64
static uint32_t dma_sniffer_get_data_accumulator(void)
Get the sniffer's data accumulator value.
Definition dma.h:1054
static void dma_channel_start(uint channel)
Start a single DMA channel.
Definition dma.h:715
static void dma_channel_set_config(uint channel, const dma_channel_config_t *config, bool trigger)
Set a channel configuration.
Definition dma.h:475
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:886
int dma_claim_unused_channel(bool required)
Claim a free dma channel.
Definition dma.c:45
static void dma_channel_acknowledge_irq1(uint channel)
Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_1.
Definition dma.h:907
static void dma_channel_set_irq1_enabled(uint channel, bool enabled)
Enable single DMA channel's interrupt via DMA_IRQ_1.
Definition dma.h:802
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:1106
static uint32_t dma_encode_transfer_count_with_self_trigger(uint transfer_count)
Encode the specified transfer length, along with a flag to indicate the DMA transfer should be self-t...
Definition dma.h:557
static int dma_get_irq_num(uint irq_index)
Return DMA_IRQ_<irqn>.
Definition dma.h:1131
static void dma_start_channel_mask(uint32_t chan_mask)
Start one or more channels simultaneously.
Definition dma.h:705
void dma_channel_cleanup(uint channel)
Performs DMA channel cleanup after use.
Definition dma.c:73
#define DMA_IRQ_NUM(irq_index)
Returns the irq_num_t for the nth DMA interrupt.
Definition dma.h:56
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:832
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:848
static void dma_channel_abort(uint channel)
Stop a DMA transfer.
Definition dma.h:759
static uint dma_get_timer_dreq(uint timer_num)
Return the DREQ number for a given DMA timer.
Definition dma.h:1117
void dma_timer_unclaim(uint timer)
Mark a dma timer as no longer used.
Definition dma.c:59
static uint32_t dma_encode_endless_transfer_count(void)
Return an endless transfer as an "encoded_transfer_length" value suitable for the referenced methods.
Definition dma.h:578
static uint32_t dma_encode_transfer_count(uint transfer_count)
Encode the specified transfer length into an "encoded_transfer_length" value suitable for the referen...
Definition dma.h:531
bool dma_channel_is_claimed(uint channel)
Determine if a dma channel is claimed.
Definition dma.c:49
bool dma_timer_is_claimed(uint timer)
Determine if a dma timer is claimed.
Definition dma.c:68
static void dma_sniffer_disable(void)
Disable the DMA sniffer.
Definition dma.h:1033
static void dma_sniffer_set_output_reverse_enabled(bool reverse)
Enable the Sniffer output bit reversal function.
Definition dma.h:1022
void dma_claim_mask(uint32_t channel_mask)
Mark multiple dma channels as used.
Definition dma.c:28
static bool dma_channel_get_irq0_status(uint channel)
Determine if a particular channel is a cause of DMA_IRQ_0.
Definition dma.h:863
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:817
static void dma_channel_wait_for_finish_blocking(uint channel)
Wait for a DMA channel transfer to complete.
Definition dma.h:940
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:491
static void dma_channel_transfer_to_buffer_now(uint channel, volatile void *write_addr, uint32_t encoded_transfer_count)
Start a DMA transfer to a buffer immediately.
Definition dma.h:694
static void dma_sniffer_set_byte_swap_enabled(bool swap)
Enable the Sniffer byte swap function.
Definition dma.h:992
static void dma_channel_transfer_from_buffer_now(uint channel, const volatile void *read_addr, uint32_t encoded_transfer_count)
Start a DMA transfer from a buffer immediately.
Definition dma.h:667
void dma_channel_unclaim(uint channel)
Mark a dma channel as no longer used.
Definition dma.c:34
static void dma_sniffer_set_data_accumulator(uint32_t seed_value)
Set the sniffer's data accumulator with initial value.
Definition dma.h:1045
dma_channel_transfer_size
Enumeration of available DMA channel transfer sizes.
Definition dma.h:143
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:918
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:788
void dma_channel_claim(uint channel)
Mark a dma channel as used.
Definition dma.c:23
enum dma_channel_transfer_size dma_channel_transfer_size_t
Enumeration of available DMA channel transfer sizes.
static void dma_channel_configure(uint channel, const dma_channel_config_t *config, volatile void *write_addr, const volatile void *read_addr, uint32_t encoded_transfer_count, bool trigger)
Configure all DMA parameters and optionally start transfer.
Definition dma.h:640
static void dma_channel_set_write_addr(uint channel, volatile void *write_addr, bool trigger)
Set the DMA initial write address.
Definition dma.h:506
static void dma_channel_set_irq0_enabled(uint channel, bool enabled)
Enable single DMA channel's interrupt via DMA_IRQ_0.
Definition dma.h:773
static bool dma_channel_get_irq1_status(uint channel)
Determine if a particular channel is a cause of DMA_IRQ_1.
Definition dma.h:874
static bool dma_channel_is_busy(uint channel)
Check if DMA channel is busy.
Definition dma.h:930
static void dma_channel_acknowledge_irq0(uint channel)
Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_0.
Definition dma.h:897
@ DMA_ADDRESS_UPDATE_INCREMENT_BY_TWO
(RP2350 only) The address is incremented by twice the transfer size after each transfer
Definition dma.h:156
@ DMA_ADDRESS_UPDATE_DECREMENT
(RP2350 only) The address is decremented by the transfer size after each transfer
Definition dma.h:157
@ DMA_ADDRESS_UPDATE_NONE
The address remains the same after each transfer.
Definition dma.h:153
@ DMA_ADDRESS_UPDATE_INCREMENT
The address is incremented by the transfer size after each transfer.
Definition dma.h:154
@ DREQ_DMA_TIMER1
Select DMA_TIMER1 as DREQ.
Definition dreq.h:138
@ DREQ_DMA_TIMER0
Select DMA_TIMER0 as DREQ.
Definition dreq.h:137
@ DREQ_DMA_TIMER3
Select DMA_TIMER3 as DREQ.
Definition dreq.h:140
@ DREQ_DMA_TIMER2
Select DMA_TIMER2 as DREQ.
Definition dreq.h:139
@ DREQ_FORCE
Select FORCE as DREQ.
Definition dreq.h:141
@ DMA_SIZE_16
Half word transfer (16 bits).
Definition dma.h:145
@ DMA_SIZE_8
Byte transfer (8 bits).
Definition dma.h:144
@ DMA_SIZE_32
Word transfer (32 bits).
Definition dma.h:146
void panic_unsupported(void)
Panics with the message "Unsupported".
Definition panic.c:20
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition common.h:79
static __always_inline void __compiler_memory_barrier(void)
Ensure that the compiler does not move memory access across this method call.
Definition compiler.h:176
Opaque representation of a DMA channel configuration that can be later applied to a hardware DMA chan...
Definition dma.h:164
uint32_t ctrl
Raw control register value encoding all channel configuration bits.
Definition dma.h:165
Definition dma.h:27
Definition dma.h:164