diff --git a/src/rp2_common/hardware_dma/include/hardware/dma.h b/src/rp2_common/hardware_dma/include/hardware/dma.h index f823caa..8ebd2e5 100644 --- a/src/rp2_common/hardware_dma/include/hardware/dma.h +++ b/src/rp2_common/hardware_dma/include/hardware/dma.h @@ -118,7 +118,6 @@ bool dma_channel_is_claimed(uint channel); * * 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. @@ -136,10 +135,10 @@ typedef struct { uint32_t ctrl; } dma_channel_config; -/*! \brief Set DMA channel read increment +/*! \brief Set DMA channel read increment in a channel configuration object * \ingroup channel_config * - * \param c Pointer to channel configuration data + * \param c Pointer to channel configuration object * \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 */ @@ -147,10 +146,10 @@ static inline void channel_config_set_read_increment(dma_channel_config *c, bool 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 +/*! \brief Set DMA channel write increment in a channel configuration object * \ingroup channel_config * - * \param c Pointer to channel configuration data + * \param c Pointer to channel configuration object * \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 @@ -159,7 +158,7 @@ static inline void channel_config_set_write_increment(dma_channel_config *c, boo 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 +/*! \brief Select a transfer request signal in a channel configuration object * \ingroup channel_config * * The channel uses the transfer request signal to pace its data transfer rate. @@ -179,13 +178,13 @@ static inline void channel_config_set_dreq(dma_channel_config *c, uint dreq) { 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 +/*! \brief Set DMA channel chain_to channel in a channel configuration object * \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 c Pointer to channel configuration object * \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) { @@ -193,13 +192,13 @@ static inline void channel_config_set_chain_to(dma_channel_config *c, uint chain 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 +/*! \brief Set the size of each DMA bus transfer in a channel configuration object * \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 c Pointer to channel configuration object * \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) { @@ -207,7 +206,7 @@ static inline void channel_config_set_transfer_data_size(dma_channel_config *c, 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 +/*! \brief Set address wrapping parameters in a channel configuration object * \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 @@ -217,7 +216,7 @@ static inline void channel_config_set_transfer_data_size(dma_channel_config *c, * * 0x0 -> No wrapping. * - * \param c Pointer to channel configuration data + * \param c Pointer to channel configuration object * \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. @@ -229,27 +228,27 @@ static inline void channel_config_set_ring(dma_channel_config *c, bool write, ui (write ? DMA_CH0_CTRL_TRIG_RING_SEL_BITS : 0); } -/*! \brief Set DMA byte swapping +/*! \brief Set DMA byte swapping config in a channel configuration object * \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 c Pointer to channel configuration object * \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 +/*! \brief Set IRQ quiet mode in a channel configuration object * \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 c Pointer to channel configuration object * \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) { @@ -257,13 +256,31 @@ static inline void channel_config_set_irq_quiet(dma_channel_config *c, bool irq_ } /*! - * \brief Enable/Disable the DMA channel + * \brief Set the channel priority in a channel configuration object + * \ingroup channel_config + * + * When true, gives a channel preferential treatment in issue scheduling: in each scheduling round, + * all high priority channels are considered first, and then only a single low + * priority channel, before returning to the high priority channels. + * + * This only affects the order in which the DMA schedules channels. The DMA's bus priority is not changed. + * If the DMA is not saturated then a low priority channel will see no loss of throughput. + * + * \param c Pointer to channel configuration object + * \param high_priority True to enable high priority + */ +static inline void channel_config_set_high_priority(dma_channel_config *c, bool high_priority) { + c->ctrl = high_priority ? (c->ctrl | DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS) : (c->ctrl & ~DMA_CH0_CTRL_TRIG_HIGH_PRIORITY_BITS); +} + +/*! + * \brief Enable/Disable the DMA channel in a channel configuration object * \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 c Pointer to channel configuration object * \param enable True to enable the DMA channel. When enabled, the channel will respond to triggering events, and start transferring data. * */ @@ -271,12 +288,12 @@ 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. +/*! \brief Enable access to channel by sniff hardware in a channel configuration object * \ingroup channel_config * * Sniff HW must be enabled and have this channel selected. * - * \param c Pointer to channel configuration data + * \param c Pointer to channel configuration object * \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) { @@ -297,6 +314,7 @@ static inline void channel_config_set_sniff_enable(dma_channel_config *c, bool s * Ring | write=false, size=0 (i.e. off) * Byte Swap | false * Quiet IRQs | false + * High Priority | false * Channel Enable | true * Sniff Enable | false * @@ -315,6 +333,7 @@ static inline dma_channel_config dma_channel_get_default_config(uint channel) { channel_config_set_irq_quiet(&c, false); channel_config_set_enable(&c, true); channel_config_set_sniff_enable(&c, false); + channel_config_set_high_priority( &c, false); return c; }