neorv32/sw/lib/include/neorv32_dma.h

137 lines
8.2 KiB
C

// #################################################################################################
// # << NEORV32: neorv32_dma.h - Direct Memory Access Controller (DMA) HW Driver >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2024, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
// # #
// # 1. Redistributions of source code must retain the above copyright notice, this list of #
// # conditions and the following disclaimer. #
// # #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
// # conditions and the following disclaimer in the documentation and/or other materials #
// # provided with the distribution. #
// # #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
// # endorse or promote products derived from this software without specific prior written #
// # permission. #
// # #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
// # OF THE POSSIBILITY OF SUCH DAMAGE. #
// # ********************************************************************************************* #
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
// #################################################################################################
/**********************************************************************//**
* @file neorv32_dma.h
* @brief Direct Memory Access Controller (DMA) HW driver header file.
*
* @note These functions should only be used if the DMA controller was synthesized (IO_DMA_EN = true).
**************************************************************************/
#ifndef neorv32_dma_h
#define neorv32_dma_h
/**********************************************************************//**
* @name IO Device: Direct Memory Access Controller (DMA)
**************************************************************************/
/**@{*/
/** DMA module prototype */
typedef volatile struct __attribute__((packed,aligned(4))) {
uint32_t CTRL; /**< offset 0: control and status register (#NEORV32_DMA_CTRL_enum) */
uint32_t SRC_BASE; /**< offset 4: source base address register */
uint32_t DST_BASE; /**< offset 8: destination base address register */
uint32_t TTYPE; /**< offset 12: transfer type configuration register & manual trigger (#NEORV32_DMA_TTYPE_enum) */
} neorv32_dma_t;
/** DMA module hardware access (#neorv32_dma_t) */
#define NEORV32_DMA ((neorv32_dma_t*) (NEORV32_DMA_BASE))
/** DMA control and status register bits */
enum NEORV32_DMA_CTRL_enum {
DMA_CTRL_EN = 0, /**< DMA control register(0) (r/w): DMA enable */
DMA_CTRL_AUTO = 1, /**< DMA control register(1) (r/w): Automatic trigger mode enable */
DMA_CTRL_FENCE = 2, /**< DMA control register(2) (r/w): Issue FENCE downstream operation when DMA transfer is completed */
DMA_CTRL_ERROR_RD = 8, /**< DMA control register(8) (r/-): Error during read access; SRC_BASE shows the faulting address */
DMA_CTRL_ERROR_WR = 9, /**< DMA control register(9) (r/-): Error during write access; DST_BASE shows the faulting address */
DMA_CTRL_BUSY = 10, /**< DMA control register(10) (r/-): DMA busy / transfer in progress */
DMA_CTRL_DONE = 11, /**< DMA control register(11) (r/c): A transfer was executed when set */
DMA_CTRL_FIRQ_MASK_LSB = 16, /**< DMA control register(16) (r/w): FIRQ trigger mask LSB */
DMA_CTRL_FIRQ_MASK_MSB = 31 /**< DMA control register(31) (r/w): FIRQ trigger mask MSB */
};
/** DMA transfer type bits */
enum NEORV32_DMA_TTYPE_enum {
DMA_TTYPE_NUM_LSB = 0, /**< DMA transfer type register(0) (r/w): Number of elements to transfer, LSB */
DMA_TTYPE_NUM_MSB = 23, /**< DMA transfer type register(23) (r/w): Number of elements to transfer, MSB */
DMA_TTYPE_QSEL_LSB = 27, /**< DMA transfer type register(27) (r/w): Data quantity select, LSB */
DMA_TTYPE_QSEL_MSB = 28, /**< DMA transfer type register(28) (r/w): Data quantity select, MSB */
DMA_TTYPE_SRC_INC = 29, /**< DMA transfer type register(29) (r/w): SRC constant (0) or incrementing (1) address */
DMA_TTYPE_DST_INC = 30, /**< DMA transfer type register(30) (r/w): SRC constant (0) or incrementing (1) address */
DMA_TTYPE_ENDIAN = 31 /**< DMA transfer type register(31) (r/w): Convert Endianness when set */
};
/**@}*/
/**********************************************************************//**
* DMA transfer type commands
**************************************************************************/
/**@{*/
#define DMA_CMD_B2B (0b00 << DMA_TTYPE_QSEL_LSB) // byte to byte
#define DMA_CMD_B2UW (0b01 << DMA_TTYPE_QSEL_LSB) // byte to unsigned word
#define DMA_CMD_B2SW (0b10 << DMA_TTYPE_QSEL_LSB) // byte to signed word
#define DMA_CMD_W2W (0b11 << DMA_TTYPE_QSEL_LSB) // word to word
#define DMA_CMD_SRC_CONST (0b0 << DMA_TTYPE_SRC_INC) // constant source address
#define DMA_CMD_SRC_INC (0b1 << DMA_TTYPE_SRC_INC) // incrementing source address
#define DMA_CMD_DST_CONST (0b0 << DMA_TTYPE_DST_INC) // constant destination address
#define DMA_CMD_DST_INC (0b1 << DMA_TTYPE_DST_INC) // incrementing destination address
#define DMA_CMD_ENDIAN (0b1 << DMA_TTYPE_ENDIAN) // convert endianness
/**@}*/
/**********************************************************************//**
* DMA status
**************************************************************************/
enum NEORV32_DMA_STATUS_enum {
DMA_STATUS_ERR_WR = -2, /**< write access error during last transfer (-2) */
DMA_STATUS_ERR_RD = -1, /**< read access error during last transfer (-1) */
DMA_STATUS_IDLE = 0, /**< DMA idle (0) */
DMA_STATUS_BUSY = 1 /**< DMA busy (1) */
};
/**********************************************************************//**
* @name Prototypes
**************************************************************************/
/**@{*/
int neorv32_dma_available(void);
void neorv32_dma_enable(void);
void neorv32_dma_disable(void);
void neorv32_dma_fence_enable(void);
void neorv32_dma_fence_disable(void);
void neorv32_dma_transfer(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config);
void neorv32_dma_transfer_auto(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config, uint32_t firq_mask);
int neorv32_dma_status(void);
int neorv32_dma_done(void);
/**@}*/
#endif // neorv32_dma_h