/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef _HARDWARE_DMA_H_
#define _HARDWARE_DMA_H_

#include "pico.h"
#include "hardware/structs/dma.h"
#include "hardware/regs/dreq.h"
#include "pico/assert.h"

#ifdef __cplusplus
extern "C" {
#endif

/** \file hardware/dma.h
 *  \defgroup hardware_dma hardware_dma
 *
 * DMA Controller API
 *
 * The RP2040 Direct Memory Access (DMA) master performs bulk data transfers on a processor’s
 * behalf. This leaves processors free to attend to other tasks, or enter low-power sleep states. The
 * data throughput of the DMA is also significantly higher than one of RP2040’s processors.
 *
 * The DMA can perform one read access and one write access, up to 32 bits in size, every clock cycle.
 * There are 12 independent channels, which each supervise a sequence of bus transfers, usually in
 * one of the following scenarios:
 *
 * * Memory to peripheral
 * * Peripheral to memory
 * * Memory to memory
 */

// these are not defined in generated dreq.h
#define DREQ_DMA_TIMER0 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER0
#define DREQ_DMA_TIMER1 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER1
#define DREQ_DMA_TIMER2 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER2
#define DREQ_DMA_TIMER3 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER3
#define DREQ_FORCE      DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_PERMANENT

// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_DMA, Enable/disable DMA assertions, type=bool, default=0, group=hardware_dma
#ifndef PARAM_ASSERTIONS_ENABLED_DMA
#define PARAM_ASSERTIONS_ENABLED_DMA 0
#endif

static inline void check_dma_channel_param(__unused uint channel) {
#if PARAM_ASSERTIONS_ENABLED(DMA)
    // this method is used a lot by inline functions so avoid code bloat by deferring to function
    extern void check_dma_channel_param_impl(uint channel);
    check_dma_channel_param_impl(channel);
#endif
}

static inline void check_dma_timer_param(__unused uint timer_num) {
    valid_params_if(DMA, timer_num < NUM_DMA_TIMERS);
}

inline static dma_channel_hw_t *dma_channel_hw_addr(uint channel) {
    check_dma_channel_param(channel);
    return &dma_hw->ch[channel];
}

/*! \brief Mark a dma channel as used
 *  \ingroup hardware_dma
 *
 * Method for cooperative claiming of hardware. Will cause a panic if the channel
 * is already claimed. Use of this method by libraries detects accidental
 * configurations that would fail in unpredictable ways.
 *
 * \param channel the dma channel
 */
void dma_channel_claim(uint channel);

/*! \brief Mark multiple dma channels as used
 *  \ingroup hardware_dma
 *
 * Method for cooperative claiming of hardware. Will cause a panic if any of the channels
 * are already claimed. Use of this method by libraries detects accidental
 * configurations that would fail in unpredictable ways.
 *
 * \param channel_mask Bitfield of all required channels to claim (bit 0 == channel 0, bit 1 == channel 1 etc)
 */
void dma_claim_mask(uint32_t channel_mask);

/*! \brief Mark a dma channel as no longer used
 *  \ingroup hardware_dma
 *
 * Method for cooperative claiming of hardware.
 *
 * \param channel the dma channel to release
 */
void dma_channel_unclaim(uint channel);

/*! \brief Claim a free dma channel
 *  \ingroup hardware_dma
 *
 * \param required if true the function will panic if none are available
 * \return the dma channel number or -1 if required was false, and none were free
 */
int dma_claim_unused_channel(bool required);

/*! \brief Determine if a dma channel is claimed
 *  \ingroup hardware_dma
 *
 * \param channel the dma channel
 * \return true if the channel is claimed, false otherwise
 * \see dma_channel_claim
 * \see dma_channel_claim_mask
 */
bool dma_channel_is_claimed(uint channel);

/** \brief DMA channel configuration
 *  \defgroup channel_config channel_config
 *  \ingroup hardware_dma
 *
 * A DMA channel needs to be configured, these functions provide handy helpers to set up configuration
 * structures. See \ref dma_channel_config
 *
 */

/*! \brief Enumeration of available DMA channel transfer sizes.
 *  \ingroup hardware_dma
 *
 * Names indicate the number of bits.
 */
enum dma_channel_transfer_size {
    DMA_SIZE_8 = 0,    ///< Byte transfer (8 bits)
    DMA_SIZE_16 = 1,   ///< Half word transfer (16 bits)
    DMA_SIZE_32 = 2    ///< Word transfer (32 bits)
};

typedef struct {
    uint32_t ctrl;
} dma_channel_config;

/*! \brief  Set DMA channel read increment
 *  \ingroup channel_config
 *
 * \param c Pointer to channel configuration data
 * \param incr True to enable read address increments, if false, each read will be from the same address
 *             Usually disabled for peripheral to memory transfers
 */
static inline void channel_config_set_read_increment(dma_channel_config *c, bool incr) {
    c->ctrl = incr ? (c->ctrl | DMA_CH0_CTRL_TRIG_INCR_READ_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_INCR_READ_BITS);
}

/*! \brief  Set DMA channel write increment
 *  \ingroup channel_config
 *
 * \param c Pointer to channel configuration data
 * \param incr True to enable write address increments, if false, each write will be to the same address
 *             Usually disabled for memory to peripheral transfers
 * Usually disabled for memory to peripheral transfers
 */
static inline void channel_config_set_write_increment(dma_channel_config *c, bool incr) {
    c->ctrl = incr ? (c->ctrl | DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_INCR_WRITE_BITS);
}

/*! \brief  Select a transfer request signal
 *  \ingroup channel_config
 *
 * The channel uses the transfer request signal to pace its data transfer rate.
 * Sources for TREQ signals are internal (TIMERS) or external (DREQ, a Data Request from the system).
 * 0x0 to 0x3a -> select DREQ n as TREQ
 * 0x3b -> Select Timer 0 as TREQ
 * 0x3c -> Select Timer 1 as TREQ
 * 0x3d -> Select Timer 2 as TREQ (Optional)
 * 0x3e -> Select Timer 3 as TREQ (Optional)
 * 0x3f -> Permanent request, for unpaced transfers.
 *
 * \param c Pointer to channel configuration data
 * \param dreq Source (see description)
 */
static inline void channel_config_set_dreq(dma_channel_config *c, uint dreq) {
    assert(dreq <= DREQ_FORCE);
    c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_TREQ_SEL_BITS) | (dreq << DMA_CH0_CTRL_TRIG_TREQ_SEL_LSB);
}

/*! \brief  Set DMA channel completion channel
 *  \ingroup channel_config
 *
 * When this channel completes, it will trigger the channel indicated by chain_to. Disable by
 * setting chain_to to itself (the same channel)
 *
 * \param c Pointer to channel configuration data
 * \param chain_to Channel to trigger when this channel completes.
 */
static inline void channel_config_set_chain_to(dma_channel_config *c, uint chain_to) {
    assert(chain_to <= NUM_DMA_CHANNELS);
    c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (chain_to << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB);
}

/*! \brief Set the size of each DMA bus transfer
 *  \ingroup channel_config
 *
 * Set the size of each bus transfer (byte/halfword/word). The read and write addresses
 * advance by the specific amount (1/2/4 bytes) with each transfer.
 *
 * \param c Pointer to channel configuration data
 * \param size See enum for possible values.
 */
static inline void channel_config_set_transfer_data_size(dma_channel_config *c, enum dma_channel_transfer_size size) {
    assert(size == DMA_SIZE_8 || size == DMA_SIZE_16 || size == DMA_SIZE_32);
    c->ctrl = (c->ctrl & ~DMA_CH0_CTRL_TRIG_DATA_SIZE_BITS) | (((uint)size) << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB);
}

/*! \brief  Set address wrapping parameters
 *  \ingroup channel_config
 *
 * Size of address wrap region. If 0, don’t wrap. For values n > 0, only the lower n bits of the address
 * will change. This wraps the address on a (1 << n) byte boundary, facilitating access to naturally-aligned
 * ring buffers.
 * Ring sizes between 2 and 32768 bytes are possible (size_bits from 1 - 15)
 *
 * 0x0 -> No wrapping.
 *
 * \param c Pointer to channel configuration data
 * \param write True to apply to write addresses, false to apply to read addresses
 * \param size_bits 0 to disable wrapping. Otherwise the size in bits of the changing part of the address.
 *        Effectively wraps the address on a (1 << size_bits) byte boundary.
 */
static inline void channel_config_set_ring(dma_channel_config *c, bool write, uint size_bits) {
    assert(size_bits < 32);
    c->ctrl = (c->ctrl & ~(DMA_CH0_CTRL_TRIG_RING_SIZE_BITS | DMA_CH0_CTRL_TRIG_RING_SEL_BITS)) |
              (size_bits << DMA_CH0_CTRL_TRIG_RING_SIZE_LSB) |
              (write ? DMA_CH0_CTRL_TRIG_RING_SEL_BITS : 0);
}

/*! \brief  Set DMA byte swapping
 *  \ingroup channel_config
 *
 * No 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.
 *
 * \param c Pointer to channel configuration data
 * \param bswap True to enable byte swapping
 */
static inline void channel_config_set_bswap(dma_channel_config *c, bool bswap) {
    c->ctrl = bswap ? (c->ctrl | DMA_CH0_CTRL_TRIG_BSWAP_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_BSWAP_BITS);
}

/*! \brief  Set IRQ quiet mode
 *  \ingroup channel_config
 *
 * In QUIET mode, the channel does not generate IRQs at the end of every transfer block. Instead,
 * an IRQ is raised when NULL is written to a trigger register, indicating the end of a control
 * block chain.
 *
 * \param c Pointer to channel configuration data
 * \param irq_quiet True to enable quiet mode, false to disable.
 */
static inline void channel_config_set_irq_quiet(dma_channel_config *c, bool irq_quiet) {
    c->ctrl = irq_quiet ? (c->ctrl | DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS);
}

/*!
 *  \brief Enable/Disable the DMA channel
 *  \ingroup channel_config
 *
 * When false, the channel will ignore triggers, stop issuing transfers, and pause the current transfer sequence (i.e. BUSY will
 * remain high if already high)
 *
 * \param c Pointer to channel configuration data
 * \param enable True to enable the DMA channel. When enabled, the channel will respond to triggering events, and start transferring data.
 *
 */
static inline void channel_config_set_enable(dma_channel_config *c, bool enable) {
    c->ctrl = enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_EN_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_EN_BITS);
}

/*! \brief  Enable access to channel by sniff hardware.
 *  \ingroup channel_config
 *
 * Sniff HW must be enabled and have this channel selected.
 *
 * \param c Pointer to channel configuration data
 * \param sniff_enable True to enable the Sniff HW access to this DMA channel.
 */
static inline void channel_config_set_sniff_enable(dma_channel_config *c, bool sniff_enable) {
    c->ctrl = sniff_enable ? (c->ctrl | DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS) : (c->ctrl &
                                                                             ~DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
}

/*! \brief  Get the default channel configuration for a given channel
 *  \ingroup channel_config
 *
 * Setting | Default
 * --------|--------
 * Read Increment | true
 * Write Increment | false
 * DReq | DREQ_FORCE
 * Chain to | self
 * Data size | DMA_SIZE_32
 * Ring | write=false, size=0 (i.e. off)
 * Byte Swap | false
 * Quiet IRQs | false
 * Channel Enable | true
 * Sniff Enable | false
 *
 * \param channel DMA channel
 * \return the default configuration which can then be modified.
 */
static inline dma_channel_config dma_channel_get_default_config(uint channel) {
    dma_channel_config c = {0};
    channel_config_set_read_increment(&c, true);
    channel_config_set_write_increment(&c, false);
    channel_config_set_dreq(&c, DREQ_FORCE);
    channel_config_set_chain_to(&c, channel);
    channel_config_set_transfer_data_size(&c, DMA_SIZE_32);
    channel_config_set_ring(&c, false, 0);
    channel_config_set_bswap(&c, false);
    channel_config_set_irq_quiet(&c, false);
    channel_config_set_enable(&c, true);
    channel_config_set_sniff_enable(&c, false);
    return c;
}

/*! \brief  Get the current configuration for the specified channel.
 *  \ingroup channel_config
 *
 * \param channel DMA channel
 * \return The current configuration as read from the HW register (not cached)
 */
static inline dma_channel_config dma_get_channel_config(uint channel) {
    dma_channel_config c;
    c.ctrl = dma_channel_hw_addr(channel)->ctrl_trig;
    return c;
}

/*! \brief  Get the raw configuration register from a channel configuration
 *  \ingroup channel_config
 *
 * \param config Pointer to a config structure.
 * \return Register content
 */
static inline uint32_t channel_config_get_ctrl_value(const dma_channel_config *config) {
    return config->ctrl;
}

/*! \brief  Set a channel configuration
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param config Pointer to a config structure with required configuration
 * \param trigger True to trigger the transfer immediately
 */
static inline void dma_channel_set_config(uint channel, const dma_channel_config *config, bool trigger) {
    // Don't use CTRL_TRIG since we don't want to start a transfer
    if (!trigger) {
        dma_channel_hw_addr(channel)->al1_ctrl = channel_config_get_ctrl_value(config);
    } else {
        dma_channel_hw_addr(channel)->ctrl_trig = channel_config_get_ctrl_value(config);
    }
}

/*! \brief  Set the DMA initial read address.
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param read_addr Initial read address of transfer.
 * \param trigger True to start the transfer immediately
 */
static inline void dma_channel_set_read_addr(uint channel, const volatile void *read_addr, bool trigger) {
    if (!trigger) {
        dma_channel_hw_addr(channel)->read_addr = (uintptr_t) read_addr;
    } else {
        dma_channel_hw_addr(channel)->al3_read_addr_trig = (uintptr_t) read_addr;
    }
}

/*! \brief  Set the DMA initial write address
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param write_addr Initial write address of transfer.
 * \param trigger True to start the transfer immediately
 */
static inline void dma_channel_set_write_addr(uint channel, volatile void *write_addr, bool trigger) {
    if (!trigger) {
        dma_channel_hw_addr(channel)->write_addr = (uintptr_t) write_addr;
    } else {
        dma_channel_hw_addr(channel)->al2_write_addr_trig = (uintptr_t) write_addr;
    }
}

/*! \brief  Set the number of bus transfers the channel will do
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param trans_count The number of transfers (not NOT bytes, see channel_config_set_transfer_data_size)
 * \param trigger True to start the transfer immediately
 */
static inline void dma_channel_set_trans_count(uint channel, uint32_t trans_count, bool trigger) {
    if (!trigger) {
        dma_channel_hw_addr(channel)->transfer_count = trans_count;
    } else {
        dma_channel_hw_addr(channel)->al1_transfer_count_trig = trans_count;
    }
}

/*! \brief  Configure all DMA parameters and optionally start transfer
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param config Pointer to DMA config structure
 * \param write_addr Initial write address
 * \param read_addr Initial read address
 * \param transfer_count Number of transfers to perform
 * \param trigger True to start the transfer immediately
 */
static inline 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) {
    dma_channel_set_read_addr(channel, read_addr, false);
    dma_channel_set_write_addr(channel, write_addr, false);
    dma_channel_set_trans_count(channel, transfer_count, false);
    dma_channel_set_config(channel, config, trigger);
}

/*! \brief Start a DMA transfer from a buffer immediately
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param read_addr Sets the initial read address
 * \param transfer_count Number of transfers to make. Not bytes, but the number of transfers of channel_config_set_transfer_data_size() to be sent.
 */
inline static void __attribute__((always_inline)) dma_channel_transfer_from_buffer_now(uint channel, 
                                                                                       const volatile void *read_addr,
                                                                                       uint32_t transfer_count) {
//    check_dma_channel_param(channel);
    dma_channel_hw_t *hw = dma_channel_hw_addr(channel);
    hw->read_addr = (uintptr_t) read_addr;
    hw->al1_transfer_count_trig = transfer_count;
}

/*! \brief Start a DMA transfer to a buffer immediately
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param write_addr Sets the initial write address
 * \param transfer_count Number of transfers to make. Not bytes, but the number of transfers of channel_config_set_transfer_data_size() to be sent.
 */
inline static void dma_channel_transfer_to_buffer_now(uint channel, volatile void *write_addr, uint32_t transfer_count) {
    dma_channel_hw_t *hw = dma_channel_hw_addr(channel);
    hw->write_addr = (uintptr_t) write_addr;
    hw->al1_transfer_count_trig = transfer_count;
}

/*! \brief  Start one or more channels simultaneously
 *  \ingroup hardware_dma
 *
 * \param chan_mask Bitmask of all the channels requiring starting. Channel 0 = bit 0, channel 1 = bit 1 etc.
 */
static inline void dma_start_channel_mask(uint32_t chan_mask) {
    valid_params_if(DMA, chan_mask && chan_mask < (1u << NUM_DMA_CHANNELS));
    dma_hw->multi_channel_trigger = chan_mask;
}

/*! \brief  Start a single DMA channel
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 */
static inline void dma_channel_start(uint channel) {
    dma_start_channel_mask(1u << channel);
}

/*! \brief  Stop a DMA transfer
 *  \ingroup hardware_dma
 *
 * Function will only return once the DMA has stopped.
 *
 * \param channel DMA channel
 */
static inline void dma_channel_abort(uint channel) {
    check_dma_channel_param(channel);
    dma_hw->abort = 1u << channel;
    // Bit will go 0 once channel has reached safe state
    // (i.e. any in-flight transfers have retired)
    while (dma_hw->abort & (1ul << channel)) tight_loop_contents();
}

/*! \brief  Enable single DMA channel's interrupt via DMA_IRQ_0
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param enabled true to enable interrupt 0 on specified channel, false to disable.
 */
static inline void dma_channel_set_irq0_enabled(uint channel, bool enabled) {
    check_dma_channel_param(channel);
    check_hw_layout(dma_hw_t, inte0, DMA_INTE0_OFFSET);
    if (enabled)
        hw_set_bits(&dma_hw->inte0, 1u << channel);
    else
        hw_clear_bits(&dma_hw->inte0, 1u << channel);
}

/*! \brief  Enable multiple DMA channels' interrupts via DMA_IRQ_0
 *  \ingroup hardware_dma
 *
 * \param channel_mask Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.
 * \param enabled true to enable all the interrupts specified in the mask, false to disable all the interrupts specified in the mask.
 */
static inline void dma_set_irq0_channel_mask_enabled(uint32_t channel_mask, bool enabled) {
    if (enabled) {
        hw_set_bits(&dma_hw->inte0, channel_mask);
    } else {
        hw_clear_bits(&dma_hw->inte0, channel_mask);
    }
}

/*! \brief  Enable single DMA channel's interrupt via DMA_IRQ_1
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \param enabled true to enable interrupt 1 on specified channel, false to disable.
 */
static inline void dma_channel_set_irq1_enabled(uint channel, bool enabled) {
    check_dma_channel_param(channel);
    check_hw_layout(dma_hw_t, inte1, DMA_INTE1_OFFSET);
    if (enabled)
        hw_set_bits(&dma_hw->inte1, 1u << channel);
    else
        hw_clear_bits(&dma_hw->inte1, 1u << channel);
}

/*! \brief  Enable multiple DMA channels' interrupts via DMA_IRQ_1
 *  \ingroup hardware_dma
 *
 * \param channel_mask Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.
 * \param enabled true to enable all the interrupts specified in the mask, false to disable all the interrupts specified in the mask.
 */
static inline void dma_set_irq1_channel_mask_enabled(uint32_t channel_mask, bool enabled) {
    if (enabled) {
        hw_set_bits(&dma_hw->inte1, channel_mask);
    } else {
        hw_clear_bits(&dma_hw->inte1, channel_mask);
    }
}

/*! \brief  Enable single DMA channel interrupt on either DMA_IRQ_0 or DMA_IRQ_1
 *  \ingroup hardware_dma
 *
 * \param irq_index the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1
 * \param channel DMA channel
 * \param enabled true to enable interrupt via irq_index for specified channel, false to disable.
 */
static inline void dma_irqn_set_channel_enabled(uint irq_index, uint channel, bool enabled) {
    invalid_params_if(DMA, irq_index > 1);
    if (irq_index) {
        dma_channel_set_irq1_enabled(channel, enabled);
    } else {
        dma_channel_set_irq0_enabled(channel, enabled);
    }
}

/*! \brief  Enable multiple DMA channels' interrupt via either DMA_IRQ_0 or DMA_IRQ_1
 *  \ingroup hardware_dma
 *
 * \param irq_index the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1
 * \param channel_mask Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.
 * \param enabled true to enable all the interrupts specified in the mask, false to disable all the interrupts specified in the mask.
 */
static inline void dma_irqn_set_channel_mask_enabled(uint irq_index, uint32_t channel_mask,  bool enabled) {
    invalid_params_if(DMA, irq_index > 1);
    if (irq_index) {
        dma_set_irq1_channel_mask_enabled(channel_mask, enabled);
    } else {
        dma_set_irq0_channel_mask_enabled(channel_mask, enabled);
    }
}

/*! \brief  Determine if a particular channel is a cause of DMA_IRQ_0
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \return true if the channel is a cause of DMA_IRQ_0, false otherwise
 */
static inline bool dma_channel_get_irq0_status(uint channel) {
    check_dma_channel_param(channel);
    return dma_hw->ints0 & (1u << channel);
}

/*! \brief  Determine if a particular channel is a cause of DMA_IRQ_1
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \return true if the channel is a cause of DMA_IRQ_1, false otherwise
 */
static inline bool dma_channel_get_irq1_status(uint channel) {
    check_dma_channel_param(channel);
    return dma_hw->ints1 & (1u << channel);
}

/*! \brief  Determine if a particular channel is a cause of DMA_IRQ_N
 *  \ingroup hardware_dma
 *
 * \param irq_index the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1
 * \param channel DMA channel
 * \return true if the channel is a cause of the DMA_IRQ_N, false otherwise
 */
static inline bool dma_irqn_get_channel_status(uint irq_index, uint channel) {
    invalid_params_if(DMA, irq_index > 1);
    check_dma_channel_param(channel);
    return (irq_index ? dma_hw->ints1 : dma_hw->ints0) & (1u << channel);
}

/*! \brief  Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_0
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 */
static inline void dma_channel_acknowledge_irq0(uint channel) {
    check_dma_channel_param(channel);
    hw_set_bits(&dma_hw->ints0, (1u << channel));
}

/*! \brief  Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_1
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 */
static inline void dma_channel_acknowledge_irq1(uint channel) {
    check_dma_channel_param(channel);
    hw_set_bits(&dma_hw->ints1, (1u << channel));
}

/*! \brief  Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_N
 *  \ingroup hardware_dma
 *
 * \param irq_index the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1
 * \param channel DMA channel
 */
static inline void dma_irqn_acknowledge_channel(uint irq_index, uint channel) {
    invalid_params_if(DMA, irq_index > 1);
    check_dma_channel_param(channel);
    hw_set_bits(irq_index ? &dma_hw->ints1 : &dma_hw->ints0, (1u << channel));
}

/*! \brief  Check if DMA channel is busy
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 * \return true if the channel is currently busy
 */
inline static bool dma_channel_is_busy(uint channel) {
    check_dma_channel_param(channel);
    return !!(dma_hw->ch[channel].al1_ctrl & DMA_CH0_CTRL_TRIG_BUSY_BITS);
}

/*! \brief  Wait for a DMA channel transfer to complete
 *  \ingroup hardware_dma
 *
 * \param channel DMA channel
 */
inline static void dma_channel_wait_for_finish_blocking(uint channel) {
    while (dma_channel_is_busy(channel)) tight_loop_contents();
    // stop the compiler hoisting a non volatile buffer access above the DMA completion.
    __compiler_memory_barrier();
}

/*! \brief Enable the DMA sniffing targeting the specified channel
 *  \ingroup hardware_dma
 *
 * The mode can be one of the following:
 *
 * Mode | Function
 * -----|---------
 * 0x0 | Calculate a CRC-32 (IEEE802.3 polynomial)
 * 0x1 | Calculate a CRC-32 (IEEE802.3 polynomial) with bit reversed data
 * 0x2 | Calculate a CRC-16-CCITT
 * 0x3 | Calculate a CRC-16-CCITT with bit reversed data
 * 0xe | XOR reduction over all data. == 1 if the total 1 population count is odd.
 * 0xf | Calculate a simple 32-bit checksum (addition with a 32 bit accumulator)
 *
 * \param channel DMA channel
 * \param mode See description
 * \param force_channel_enable Set true to also turn on sniffing in the channel configuration (this
 * is usually what you want, but sometimes you might have a chain DMA with only certain segments
 * of the chain sniffed, in which case you might pass false).
 */
inline static void dma_sniffer_enable(uint channel, uint mode, bool force_channel_enable) {
    check_dma_channel_param(channel);
    check_hw_layout(dma_hw_t, sniff_ctrl, DMA_SNIFF_CTRL_OFFSET);
    if (force_channel_enable) {
        hw_set_bits(&dma_hw->ch[channel].al1_ctrl, DMA_CH0_CTRL_TRIG_SNIFF_EN_BITS);
    }
    dma_hw->sniff_ctrl = ((channel << DMA_SNIFF_CTRL_DMACH_LSB) & DMA_SNIFF_CTRL_DMACH_BITS) |
                         ((mode << DMA_SNIFF_CTRL_CALC_LSB) & DMA_SNIFF_CTRL_CALC_BITS) |
                         DMA_SNIFF_CTRL_EN_BITS;
}

/*! \brief Enable the Sniffer byte swap function
 *  \ingroup hardware_dma
 *
 * Locally perform a byte reverse on the sniffed data, before feeding into checksum.
 *
 * Note that the sniff hardware is downstream of the DMA channel byteswap performed in the
 * read master: if channel_config_set_bswap() and dma_sniffer_set_byte_swap_enabled() are both enabled,
 * their effects cancel from the sniffer’s point of view.
 *
 * \param swap Set true to enable byte swapping
 */
inline static void dma_sniffer_set_byte_swap_enabled(bool swap) {
    if (swap)
        hw_set_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_BSWAP_BITS);
    else
        hw_clear_bits(&dma_hw->sniff_ctrl, DMA_SNIFF_CTRL_BSWAP_BITS);
}

/*! \brief Disable the DMA sniffer
 *  \ingroup hardware_dma
 *
 */
inline static void dma_sniffer_disable(void) {
    dma_hw->sniff_ctrl = 0;
}

/*! \brief Mark a dma timer as used
 *  \ingroup hardware_dma
 *
 * Method for cooperative claiming of hardware. Will cause a panic if the timer
 * is already claimed. Use of this method by libraries detects accidental
 * configurations that would fail in unpredictable ways.
 *
 * \param timer the dma timer
 */
void dma_timer_claim(uint timer);

/*! \brief Mark a dma timer as no longer used
 *  \ingroup hardware_dma
 *
 * Method for cooperative claiming of hardware.
 *
 * \param timer the dma timer to release
 */
void dma_timer_unclaim(uint timer);

/*! \brief Claim a free dma timer
 *  \ingroup hardware_dma
 *
 * \param required if true the function will panic if none are available
 * \return the dma timer number or -1 if required was false, and none were free
 */
int dma_claim_unused_timer(bool required);

/*! \brief Determine if a dma timer is claimed
 *  \ingroup hardware_dma
 *
 * \param timer the dma timer
 * \return true if the timer is claimed, false otherwise
 * \see dma_timer_claim
 */
bool dma_timer_is_claimed(uint timer);

/*! \brief Set the divider for the given DMA timer
 *  \ingroup hardware_dma
 *
 * The timer will run at the system_clock_freq * numerator / denominator, so this is the speed
 * that data elements will be transferred at via a DMA channel using this timer as a DREQ
 *
 * \param timer the dma timer
 * \param numerator the fraction's numerator
 * \param denominator the fraction's denominator
 */
static inline void dma_timer_set_fraction(uint timer, uint16_t numerator, uint16_t denominator) {
    check_dma_timer_param(timer);
    dma_hw->timer[timer] = (((uint32_t)numerator) << DMA_TIMER0_X_LSB) | (((uint32_t)denominator) << DMA_TIMER0_Y_LSB);
}

/*! \brief Return the DREQ number for a given DMA timer
 *  \ingroup hardware_dma
 *
 * \param timer_num DMA timer number 0-3
 */
static inline uint dma_get_timer_dreq(uint timer_num) {
    static_assert(DREQ_DMA_TIMER1 == DREQ_DMA_TIMER0 + 1, "");
    static_assert(DREQ_DMA_TIMER2 == DREQ_DMA_TIMER0 + 2, "");
    static_assert(DREQ_DMA_TIMER3 == DREQ_DMA_TIMER0 + 3, "");
    check_dma_timer_param(timer_num);
    return DREQ_DMA_TIMER0 + timer_num;
}

#ifndef NDEBUG
void print_dma_ctrl(dma_channel_hw_t *channel);
#endif

#ifdef __cplusplus
}
#endif

#endif
