7 #ifndef _HARDWARE_DMA_H 8 #define _HARDWARE_DMA_H 11 #include "hardware/structs/dma.h" 12 #include "hardware/regs/dreq.h" 13 #include "pico/assert.h" 38 #define DREQ_DMA_TIMER0 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER0 39 #define DREQ_DMA_TIMER1 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER1 40 #define DREQ_DMA_TIMER2 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER2 41 #define DREQ_DMA_TIMER3 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER3 42 #define DREQ_FORCE DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_PERMANENT 45 #ifndef PARAM_ASSERTIONS_ENABLED_DMA 46 #define PARAM_ASSERTIONS_ENABLED_DMA 0 49 static inline void check_dma_channel_param(__unused uint channel) {
50 #if PARAM_ASSERTIONS_ENABLED(DMA) 52 extern void check_dma_channel_param_impl(uint channel);
53 check_dma_channel_param_impl(channel);
57 static inline void check_dma_timer_param(__unused uint timer_num) {
58 valid_params_if(DMA, timer_num < NUM_DMA_TIMERS);
62 check_dma_channel_param(channel);
63 return &dma_hw->ch[channel];
151 c->ctrl = incr ? (c->ctrl | DMA_CH0_CTRL_TRIG_INCR_READ_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_INCR_READ_BITS);
162 c->ctrl = incr ? (c->ctrl | DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS);
181 assert(dreq <= DREQ_FORCE);
182 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_TREQ_SEL_BITS) | (dreq << DMA_CH0_CTRL_TRIG_TREQ_SEL_LSB);
195 assert(chain_to <= NUM_DMA_CHANNELS);
196 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (chain_to << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB);
210 c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_DATA_SIZE_BITS) | (((uint)size) << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB);
229 assert(size_bits < 32);
230 c->ctrl = (c->ctrl & ~(DMA_CH0_CTRL_TRIG_RING_SIZE_BITS | DMA_CH0_CTRL_TRIG_RING_SEL_BITS)) |
231 (size_bits << DMA_CH0_CTRL_TRIG_RING_SIZE_LSB) |
232 (write ? DMA_CH0_CTRL_TRIG_RING_SEL_BITS : 0);
245 c->ctrl = bswap ? (c->ctrl | DMA_CH0_CTRL_TRIG_BSWAP_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_BSWAP_BITS);
259 c->ctrl = irq_quiet ? (c->ctrl | DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS);
277 c->ctrl = high_priority ? (c->ctrl | DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS);
292 c->ctrl = enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_EN_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_EN_BITS);
304 c->ctrl = sniff_enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS) : (c->ctrl &
305 ~DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
352 c.ctrl = dma_channel_hw_addr(channel)->ctrl_trig;
391 dma_channel_hw_addr(channel)->read_addr = (uintptr_t) read_addr;
393 dma_channel_hw_addr(channel)->al3_read_addr_trig = (uintptr_t) read_addr;
406 dma_channel_hw_addr(channel)->write_addr = (uintptr_t) write_addr;
408 dma_channel_hw_addr(channel)->al2_write_addr_trig = (uintptr_t) write_addr;
421 dma_channel_hw_addr(channel)->transfer_count = trans_count;
423 dma_channel_hw_addr(channel)->al1_transfer_count_trig = trans_count;
438 const volatile void *read_addr,
439 uint transfer_count,
bool trigger) {
454 const volatile void *read_addr,
455 uint32_t transfer_count) {
458 hw->read_addr = (uintptr_t) read_addr;
459 hw->al1_transfer_count_trig = transfer_count;
471 hw->write_addr = (uintptr_t) write_addr;
472 hw->al1_transfer_count_trig = transfer_count;
481 valid_params_if(DMA, chan_mask && chan_mask < (1u << NUM_DMA_CHANNELS));
482 dma_hw->multi_channel_trigger = chan_mask;
528 check_dma_channel_param(channel);
529 dma_hw->abort = 1u << channel;
542 check_dma_channel_param(channel);
543 check_hw_layout(
dma_hw_t, inte0, DMA_INTE0_OFFSET);
571 check_dma_channel_param(channel);
572 check_hw_layout(
dma_hw_t, inte1, DMA_INTE1_OFFSET);
601 invalid_params_if(DMA, irq_index > 1);
617 invalid_params_if(DMA, irq_index > 1);
632 check_dma_channel_param(channel);
633 return dma_hw->ints0 & (1u << channel);
643 check_dma_channel_param(channel);
644 return dma_hw->ints1 & (1u << channel);
655 invalid_params_if(DMA, irq_index > 1);
656 check_dma_channel_param(channel);
657 return (irq_index ? dma_hw->ints1 : dma_hw->ints0) & (1u << channel);
666 check_dma_channel_param(channel);
667 dma_hw->ints0 = 1u << channel;
676 check_dma_channel_param(channel);
677 dma_hw->ints1 = 1u << channel;
687 invalid_params_if(DMA, irq_index > 1);
688 check_dma_channel_param(channel);
690 dma_hw->ints1 = 1u << channel;
692 dma_hw->ints0 = 1u << channel;
702 check_dma_channel_param(channel);
703 return !!(dma_hw->ch[channel].al1_ctrl & DMA_CH0_CTRL_TRIG_BUSY_BITS);
738 check_dma_channel_param(channel);
739 check_hw_layout(
dma_hw_t, sniff_ctrl, DMA_SNIFF_CTRL_OFFSET);
740 if (force_channel_enable) {
741 hw_set_bits(&dma_hw->ch[channel].al1_ctrl, DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
744 (((channel << DMA_SNIFF_CTRL_DMACH_LSB) & DMA_SNIFF_CTRL_DMACH_BITS) |
745 ((mode << DMA_SNIFF_CTRL_CALC_LSB) & DMA_SNIFF_CTRL_CALC_BITS) |
746 DMA_SNIFF_CTRL_EN_BITS),
747 (DMA_SNIFF_CTRL_DMACH_BITS |
748 DMA_SNIFF_CTRL_CALC_BITS |
749 DMA_SNIFF_CTRL_EN_BITS));
765 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_BSWAP_BITS);
767 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_BSWAP_BITS);
780 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_INV_BITS);
782 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_INV_BITS);
795 hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_REV_BITS);
797 hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_OUT_REV_BITS);
805 dma_hw->sniff_ctrl = 0;
817 dma_hw->sniff_data = seed_value;
826 return dma_hw->sniff_data;
877 check_dma_timer_param(timer);
878 dma_hw->timer[timer] = (((uint32_t)numerator) << DMA_TIMER0_X_LSB) | (((uint32_t)denominator) << DMA_TIMER0_Y_LSB);
887 static_assert(DREQ_DMA_TIMER1 == DREQ_DMA_TIMER0 + 1,
"");
888 static_assert(DREQ_DMA_TIMER2 == DREQ_DMA_TIMER0 + 2,
"");
889 static_assert(DREQ_DMA_TIMER3 == DREQ_DMA_TIMER0 + 3,
"");
890 check_dma_timer_param(timer_num);
891 return DREQ_DMA_TIMER0 + timer_num;
static void channel_config_set_high_priority(dma_channel_config *c, bool high_priority)
Set the channel priority in a channel configuration objectWhen true, gives a channel preferential tre...
Definition: dma.h:276
static bool dma_channel_get_irq0_status(uint channel)
Determine if a particular channel is a cause of DMA_IRQ_0.
Definition: dma.h:631
static bool dma_channel_is_busy(uint channel)
Check if DMA channel is busy.
Definition: dma.h:701
static void dma_sniffer_disable(void)
Disable the DMA sniffer.
Definition: dma.h:804
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:419
static void dma_sniffer_enable(uint channel, uint mode, bool force_channel_enable)
Enable the DMA sniffing targeting the specified channelThe mode can be one of the following: ...
Definition: dma.h:737
static void channel_config_set_chain_to(dma_channel_config *c, uint chain_to)
Set DMA channel chain_to channel in a channel configuration objectWhen this channel completes...
Definition: dma.h:194
static void dma_channel_acknowledge_irq1(uint channel)
Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_1.
Definition: dma.h:675
static void dma_channel_set_irq1_enabled(uint channel, bool enabled)
Enable single DMA channel's interrupt via DMA_IRQ_1.
Definition: dma.h:570
static void dma_channel_set_config(uint channel, const dma_channel_config *config, bool trigger)
Set a channel configuration.
Definition: dma.h:373
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 objectSet the size of each bus trans...
Definition: dma.h:208
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:600
dma_channel_transfer_size
Enumeration of available DMA channel transfer sizes.Names indicate the number of bits.
Definition: dma.h:133
static void dma_sniffer_set_data_accumulator(uint32_t seed_value)
Set the sniffer's data accumulator with initial valueGenerally, CRC algorithms are used with the data...
Definition: dma.h:816
static void dma_channel_acknowledge_irq0(uint channel)
Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_0.
Definition: dma.h:665
static void dma_channel_start(uint channel)
Start a single DMA channel.
Definition: dma.h:490
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:686
static void channel_config_set_dreq(dma_channel_config *c, uint dreq)
Select a transfer request signal in a channel configuration objectThe channel uses the transfer reque...
Definition: dma.h:180
void dma_claim_mask(uint32_t channel_mask)
Mark multiple dma channels as usedMethod for cooperative claiming of hardware. Will cause a panic if ...
Definition: dma.c:28
static void dma_sniffer_set_output_reverse_enabled(bool reverse)
Enable the Sniffer output bit reversal functionIf enabled, the sniff data result appears bit-reversed...
Definition: dma.h:793
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:389
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:362
Byte transfer (8 bits)
Definition: dma.h:134
static uint32_t dma_sniffer_get_data_accumulator(void)
Get the sniffer's data accumulator valueRead value calculated by the hardware from sniffing the DMA s...
Definition: dma.h:825
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 registerSets destination bits to values specified in...
Definition: address_mapped.h:157
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:437
int dma_claim_unused_timer(bool required)
Claim a free dma timer.
Definition: dma.c:64
static void channel_config_set_bswap(dma_channel_config *c, bool bswap)
Set DMA byte swapping config in a channel configuration objectNo effect for byte data, for halfword data, the two bytes of each halfword are swapped. For word data, the four bytes of each word are swapped to reverse their order.
Definition: dma.h:244
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
void dma_unclaim_mask(uint32_t channel_mask)
Mark multiple dma channels as no longer used.
Definition: dma.c:39
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:654
static void dma_channel_abort(uint channel)
Stop a DMA transferFunction will only return once the DMA has stopped.
Definition: dma.h:527
static void channel_config_set_ring(dma_channel_config *c, bool write, uint size_bits)
Set address wrapping parameters in a channel configuration objectSize of address wrap region...
Definition: dma.h:228
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 objectSniff HW must be enabled ...
Definition: dma.h:303
Half word transfer (16 bits)
Definition: dma.h:135
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:121
void dma_channel_claim(uint channel)
Mark a dma channel as usedMethod for cooperative claiming of hardware. Will cause a panic if the chan...
Definition: dma.c:23
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:150
static void channel_config_set_irq_quiet(dma_channel_config *c, bool irq_quiet)
Set IRQ quiet mode in a channel configuration objectIn QUIET mode, the channel does not generate IRQs...
Definition: dma.h:258
int dma_claim_unused_channel(bool required)
Claim a free dma channel.
Definition: dma.c:45
static void dma_channel_set_write_addr(uint channel, volatile void *write_addr, bool trigger)
Set the DMA initial write address.
Definition: dma.h:404
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:453
void dma_timer_unclaim(uint timer)
Mark a dma timer as no longer usedMethod for cooperative claiming of hardware.
Definition: dma.c:59
static void dma_timer_set_fraction(uint timer, uint16_t numerator, uint16_t denominator)
Set the divider for the given DMA timerThe timer will run at the system_clock_freq * numerator / deno...
Definition: dma.h:876
static void dma_channel_wait_for_finish_blocking(uint channel)
Wait for a DMA channel transfer to complete.
Definition: dma.h:711
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:556
static bool dma_channel_get_irq1_status(uint channel)
Determine if a particular channel is a cause of DMA_IRQ_1.
Definition: dma.h:642
static void dma_channel_set_irq0_enabled(uint channel, bool enabled)
Enable single DMA channel's interrupt via DMA_IRQ_0.
Definition: dma.h:541
static dma_channel_config dma_channel_get_default_config(uint channel)
Get the default channel configuration for a given channelSetting Default Read Increment true Write I...
Definition: dma.h:328
static dma_channel_config dma_get_channel_config(uint channel)
Get the current configuration for the specified channel.
Definition: dma.h:350
static uint dma_get_timer_dreq(uint timer_num)
Return the DREQ number for a given DMA timer.
Definition: dma.h:886
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:469
void dma_timer_claim(uint timer)
Mark a dma timer as usedMethod for cooperative claiming of hardware. Will cause a panic if the timer ...
Definition: dma.c:54
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:161
static void dma_sniffer_set_byte_swap_enabled(bool swap)
Enable the Sniffer byte swap functionLocally perform a byte reverse on the sniffed data...
Definition: dma.h:763
static void channel_config_set_enable(dma_channel_config *c, bool enable)
Enable/Disable the DMA channel in a channel configuration objectWhen false, the channel will ignore t...
Definition: dma.h:291
Word transfer (32 bits)
Definition: dma.h:136
void dma_channel_unclaim(uint channel)
Mark a dma channel as no longer used.
Definition: dma.c:34
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:585
static void dma_sniffer_set_output_invert_enabled(bool invert)
Enable the Sniffer output invert functionIf enabled, the sniff data result appears bit-inverted when ...
Definition: dma.h:778
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:131
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:616
static void dma_start_channel_mask(uint32_t chan_mask)
Start one or more channels simultaneously.
Definition: dma.h:480