123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759 |
- /*
- * Copyright (c) 2021-2022 HPMicro
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
- #ifndef HPM_DMAV2_DRV_H
- #define HPM_DMAV2_DRV_H
- #include "hpm_common.h"
- #include "hpm_soc_feature.h"
- #include "hpm_dmav2_regs.h"
- /**
- *
- * @brief DMA driver APIs
- * @defgroup dma_interface DMA driver APIs
- * @ingroup io_interfaces
- * @{
- */
- #define DMA_Type DMAV2_Type
- #define DMA_CHANNEL_PRIORITY_LOW (0U)
- #define DMA_CHANNEL_PRIORITY_HIGH (1U)
- #define DMA_NUM_TRANSFER_PER_BURST_1T (0U)
- #define DMA_NUM_TRANSFER_PER_BURST_2T (1U)
- #define DMA_NUM_TRANSFER_PER_BURST_4T (2U)
- #define DMA_NUM_TRANSFER_PER_BURST_8T (3U)
- #define DMA_NUM_TRANSFER_PER_BURST_16T (4U)
- #define DMA_NUM_TRANSFER_PER_BURST_32T (5U)
- #define DMA_NUM_TRANSFER_PER_BURST_64T (6U)
- #define DMA_NUM_TRANSFER_PER_BURST_128T (7U)
- #define DMA_NUM_TRANSFER_PER_BURST_256T (8U)
- #define DMA_NUM_TRANSFER_PER_BURST_512T (9U)
- #define DMA_NUM_TRANSFER_PER_BURST_1024T (10U)
- #define DMA_TRANSFER_WIDTH_BYTE (0U)
- #define DMA_TRANSFER_WIDTH_HALF_WORD (1U)
- #define DMA_TRANSFER_WIDTH_WORD (2U)
- #define DMA_TRANSFER_WIDTH_DOUBLE_WORD (3U)
- #define DMA_ALIGN_HALF_WORD(x) (x & ~(1u))
- #define DMA_ALIGN_WORD(x) (x & ~(3u))
- #define DMA_ALIGN_DOUBLE_WORD(x) (x & ~(7u))
- #define DMA_CHANNEL_STATUS_ONGOING (1U)
- #define DMA_CHANNEL_STATUS_ERROR (2U)
- #define DMA_CHANNEL_STATUS_ABORT (4U)
- #define DMA_CHANNEL_STATUS_TC (8U)
- #define DMA_CHANNEL_STATUS_HALF_TC (16U)
- #define DMA_CHANNEL_IRQ_STATUS_ERROR(x) (uint32_t)(1 << x)
- #define DMA_CHANNEL_IRQ_STATUS_ABORT(x) (uint32_t)(1 << x)
- #define DMA_CHANNEL_IRQ_STATUS_TC(x) (uint32_t)(1 << x)
- #define DMA_CHANNEL_IRQ_STATUS_HALF_TC(x) (uint32_t)(1 << x)
- #define DMA_HANDSHAKE_MODE_NORMAL (0U)
- #define DMA_HANDSHAKE_MODE_HANDSHAKE (1U)
- #define DMA_ADDRESS_CONTROL_INCREMENT (0U)
- #define DMA_ADDRESS_CONTROL_DECREMENT (1U)
- #define DMA_ADDRESS_CONTROL_FIXED (2U)
- #define DMA_SRC_BURST_OPT_STANDAND_SIZE (0U)
- #define DMA_SRC_BURST_OPT_CUSTOM_SIZE (1U)
- #define DMA_HANDSHAKE_OPT_ONE_BURST (0U)
- #define DMA_HANDSHAKE_OPT_ALL_TRANSIZE (1U)
- #define DMA_SWAP_MODE_TABLE (0U)
- #define DMA_SWAP_MODE_BYTE (1U)
- #define DMA_SWAP_MODE_HALF_WORD (2U)
- #define DMA_SWAP_MODE_WORD (3U)
- #define DMA_INTERRUPT_MASK_NONE (0U)
- #define DMA_INTERRUPT_MASK_ERROR DMAV2_CHCTRL_CTRL_INTERRMASK_MASK
- #define DMA_INTERRUPT_MASK_ABORT DMAV2_CHCTRL_CTRL_INTABTMASK_MASK
- #define DMA_INTERRUPT_MASK_TERMINAL_COUNT DMAV2_CHCTRL_CTRL_INTTCMASK_MASK
- #define DMA_INTERRUPT_MASK_HALF_TC DMAV2_CHCTRL_CTRL_INTHALFCNTMASK_MASK
- #define DMA_INTERRUPT_MASK_ALL \
- (uint8_t)(DMA_INTERRUPT_MASK_TERMINAL_COUNT \
- | DMA_INTERRUPT_MASK_ABORT \
- | DMA_INTERRUPT_MASK_ERROR \
- | DMA_INTERRUPT_MASK_HALF_TC)
- #define DMA_SUPPORT_64BIT_ADDR (0)
- enum {
- dmav2_state_idle = 0,
- dmav2_state_read,
- dmav2_state_read_ack,
- dmav2_state_write,
- dmav2_state_write_ack,
- dmav2_state_ll,
- dmav2_state_end,
- dmav2_state_end_wait,
- };
- /**
- * @brief Linked descriptor
- *
- * It is consumed by DMA controlled directly
- */
- typedef struct dma_linked_descriptor {
- uint32_t ctrl; /**< Control */
- uint32_t trans_size; /**< Transfer size in source width */
- uint32_t src_addr; /**< Source address */
- uint32_t req_ctrl; /**< Request select */
- uint32_t dst_addr; /**< Destination address */
- uint32_t swap_table; /**< Swap table */
- uint32_t linked_ptr; /**< Linked descriptor address */
- uint32_t reserved0; /**< not used on dmav2 */
- } dma_linked_descriptor_t;
- /* @brief Channel config */
- typedef struct dma_channel_config {
- uint8_t priority; /**< Channel priority */
- uint8_t src_burst_size; /**< Source burst size */
- uint8_t src_mode; /**< Source work mode */
- uint8_t dst_mode; /**< Destination work mode */
- uint8_t src_width; /**< Source width */
- uint8_t dst_width; /**< Destination width */
- uint8_t src_addr_ctrl; /**< Source address control */
- uint8_t dst_addr_ctrl; /**< Destination address control */
- uint16_t interrupt_mask; /**< Interrupt mask */
- uint32_t src_addr; /**< Source address */
- uint32_t dst_addr; /**< Destination address */
- uint32_t linked_ptr; /**< Next linked descriptor */
- uint32_t size_in_byte; /**< Total size to be transferred in byte */
- bool en_infiniteloop; /**< Infinite loop transfer enable. Attention: only DMAV2 support */
- uint8_t handshake_opt; /**< Handshake transfer option. Attention: only DMAV2 support */
- uint8_t burst_opt; /**< Burst size option. Attention: only DMAV2 support */
- #if defined(HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS) && (HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS == 1)
- bool en_src_burst_in_fixed_trans; /**< Source burst in fix transfer size enable, discard src_addr_ctrl setting. Attention: only DMAV2 support */
- bool en_dst_burst_in_fixed_trans; /**< Destination burst in fix transfer size enable, discard dst_addr_ctrl setting. Attention: only DMAV2 support */
- #endif
- #if defined(HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP) && (HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP == 1)
- uint8_t swap_mode; /**< Swap Mode. Attention: only DMAV2 support */
- uint32_t swap_table; /**< Swap Table. Attention: only DMAV2 support */
- #endif
- } dma_channel_config_t;
- /* @brief Channel config */
- typedef struct dma_handshake_config {
- uint32_t dst;
- uint32_t src;
- uint32_t size_in_byte;
- uint8_t data_width; /* data width, value defined by DMA_TRANSFER_WIDTH_xxx */
- uint8_t ch_index;
- bool dst_fixed;
- bool src_fixed;
- bool en_infiniteloop;
- uint16_t interrupt_mask;
- } dma_handshake_config_t;
- /* @brief DMA specific status */
- enum {
- status_dma_transfer_done = MAKE_STATUS(status_group_dma, 0),
- status_dma_transfer_error = MAKE_STATUS(status_group_dma, 1),
- status_dma_transfer_abort = MAKE_STATUS(status_group_dma, 2),
- status_dma_transfer_ongoing = MAKE_STATUS(status_group_dma, 3),
- status_dma_alignment_error = MAKE_STATUS(status_group_dma, 4),
- status_dma_transfer_half_done = MAKE_STATUS(status_group_dma, 5),
- };
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * @brief Reset DMA
- *
- * @param[in] ptr DMA base address
- */
- static inline void dma_reset(DMAV2_Type *ptr)
- {
- ptr->DMACTRL |= DMAV2_DMACTRL_RESET_MASK;
- }
- /**
- * @brief Enable DMA channel
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel to be enabled
- *
- * @return status_success if everything's okay
- */
- static inline hpm_stat_t dma_enable_channel(DMAV2_Type *ptr, uint32_t ch_index)
- {
- ptr->CHCTRL[ch_index].CTRL |= DMAV2_CHCTRL_CTRL_ENABLE_MASK;
- if ((ptr->CHEN == 0) || !(ptr->CHEN & 1 << ch_index)) {
- return status_fail;
- }
- return status_success;
- }
- /**
- * @brief Disable DMA channel
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel to be disabled
- *
- */
- static inline void dma_disable_channel(DMAV2_Type *ptr, uint32_t ch_index)
- {
- ptr->CHCTRL[ch_index].CTRL &= ~DMAV2_CHCTRL_CTRL_ENABLE_MASK;
- }
- /**
- * @brief Check whether DMA channel is enable
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- *
- * @return true if DMA channel is enable
- *
- */
- static inline bool dma_channel_is_enable(DMAV2_Type *ptr, uint32_t ch_index)
- {
- return (ptr->CHCTRL[ch_index].CTRL & DMAV2_CHCTRL_CTRL_ENABLE_MASK) ? true : false;
- }
- /**
- * @brief Set DMA channel priority
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] priority dma priority
- * @arg @ref DMA_CHANNEL_PRIORITY_LOW
- * @arg @ref DMA_CHANNEL_PRIORITY_HIGH
- *
- */
- static inline void dma_set_priority(DMAV2_Type *ptr, uint32_t ch_index, uint8_t priority)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_PRIORITY_MASK) | DMAV2_CHCTRL_CTRL_PRIORITY_SET(priority);
- }
- /**
- * @brief Set DMA channel source work mode
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] mode source work mode
- * @arg @ref DMA_HANDSHAKE_MODE_NORMAL
- * @arg @ref DMA_HANDSHAKE_MODE_HANDSHAKE
- *
- */
- static inline void dma_set_source_work_mode(DMAV2_Type *ptr, uint32_t ch_index, uint8_t mode)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCMODE_MASK) | DMAV2_CHCTRL_CTRL_SRCMODE_SET(mode);
- }
- /**
- * @brief Set DMA channel destination work mode
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] mode destination work mode
- * @arg @ref DMA_HANDSHAKE_MODE_NORMAL
- * @arg @ref DMA_HANDSHAKE_MODE_HANDSHAKE
- *
- */
- static inline void dma_set_destination_work_mode(DMAV2_Type *ptr, uint32_t ch_index, uint8_t mode)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DSTMODE_MASK) | DMAV2_CHCTRL_CTRL_DSTMODE_SET(mode);
- }
- /**
- * @brief Set DMA channel source burst size
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] burstsize source burst size
- * when BURSTOPT is 0, please reference follows:
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_1T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_2T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_4T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_8T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_16T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_32T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_64T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_128T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_256T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_512T
- * @arg @ref DMA_NUM_TRANSFER_PER_BURST_1024T
- * when BURSTOPT is 1, burst size is (burstsize + 1).
- *
- */
- static inline void dma_set_source_burst_size(DMAV2_Type *ptr, uint32_t ch_index, uint8_t burstsize)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCBURSTSIZE_MASK) | DMAV2_CHCTRL_CTRL_SRCBURSTSIZE_SET(burstsize);
- }
- /**
- * @brief Get DMA channel remaining transfer size
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- *
- * @return remaining transfer size
- *
- */
- static inline uint32_t dma_get_remaining_transfer_size(DMAV2_Type *ptr, uint32_t ch_index)
- {
- return ptr->CHCTRL[ch_index].TRANSIZE;
- }
- /**
- * @brief Set DMA channel transfer size
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] size_in_width transfer size of the channel. The width is current dma channel configured source width.
- * Transfer total bytes are (size_in_width * source width).
- *
- */
- static inline void dma_set_transfer_size(DMAV2_Type *ptr, uint32_t ch_index, uint32_t size_in_width)
- {
- ptr->CHCTRL[ch_index].TRANSIZE = DMAV2_CHCTRL_TRANSIZE_TRANSIZE_SET(size_in_width);
- }
- /**
- * @brief Set DMA channel source width
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] width transfer source width of the channel
- * @arg @ref DMA_TRANSFER_WIDTH_BYTE
- * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
- * @arg @ref DMA_TRANSFER_WIDTH_WORD
- * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
- */
- static inline void dma_set_source_width(DMAV2_Type *ptr, uint32_t ch_index, uint8_t width)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCWIDTH_MASK) | DMAV2_CHCTRL_CTRL_SRCWIDTH_SET(width);
- }
- /**
- * @brief Set DMA channel destination width
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] width transfer destination width of the channel
- * @arg @ref DMA_TRANSFER_WIDTH_BYTE
- * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
- * @arg @ref DMA_TRANSFER_WIDTH_WORD
- * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
- */
- static inline void dma_set_destination_width(DMAV2_Type *ptr, uint32_t ch_index, uint8_t width)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DSTWIDTH_MASK) | DMAV2_CHCTRL_CTRL_DSTWIDTH_SET(width);
- }
- /**
- * @brief Set DMA channel transfer width and size in byte
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] src_width transfer source width of the channel
- * @arg @ref DMA_TRANSFER_WIDTH_BYTE
- * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
- * @arg @ref DMA_TRANSFER_WIDTH_WORD
- * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
- * @param[in] size_in_byte transfer size in byte of the channel. The dma transfer size is (size_in_byte >> src_width).
- *
- */
- static inline void dma_set_transfer_src_width_byte_size(DMAV2_Type *ptr, uint32_t ch_index, uint8_t src_width, uint32_t size_in_byte)
- {
- assert((src_width == DMA_TRANSFER_WIDTH_BYTE) || (src_width == DMA_TRANSFER_WIDTH_HALF_WORD)
- || (src_width == DMA_TRANSFER_WIDTH_WORD) || (src_width == DMA_TRANSFER_WIDTH_DOUBLE_WORD));
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCWIDTH_MASK) | DMAV2_CHCTRL_CTRL_SRCWIDTH_SET(src_width);
- ptr->CHCTRL[ch_index].TRANSIZE = DMAV2_CHCTRL_TRANSIZE_TRANSIZE_SET(size_in_byte >> src_width);
- }
- /**
- * @brief Set DMA channel source address
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] addr source address
- *
- */
- static inline void dma_set_source_address(DMAV2_Type *ptr, uint32_t ch_index, uint32_t addr)
- {
- ptr->CHCTRL[ch_index].SRCADDR = addr;
- }
- /**
- * @brief Set DMA channel destination address
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] addr destination address
- *
- */
- static inline void dma_set_destination_address(DMAV2_Type *ptr, uint32_t ch_index, uint32_t addr)
- {
- ptr->CHCTRL[ch_index].DSTADDR = addr;
- }
- /**
- * @brief Set DMA channel source address control mode
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] addr_ctrl source address control mode
- * @arg @ref DMA_ADDRESS_CONTROL_INCREMENT
- * @arg @ref DMA_ADDRESS_CONTROL_DECREMENT
- * @arg @ref DMA_ADDRESS_CONTROL_FIXED
- *
- */
- static inline void dma_set_source_address_ctrl(DMAV2_Type *ptr, uint32_t ch_index, uint8_t addr_ctrl)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCADDRCTRL_MASK) | DMAV2_CHCTRL_CTRL_SRCADDRCTRL_SET(addr_ctrl);
- }
- /**
- * @brief Set DMA channel destination address control mode
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] addr_ctrl destination address control mode
- * @arg @ref DMA_ADDRESS_CONTROL_INCREMENT
- * @arg @ref DMA_ADDRESS_CONTROL_DECREMENT
- * @arg @ref DMA_ADDRESS_CONTROL_FIXED
- *
- */
- static inline void dma_set_destination_address_ctrl(DMAV2_Type *ptr, uint32_t ch_index, uint8_t addr_ctrl)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DSTADDRCTRL_MASK) | DMAV2_CHCTRL_CTRL_DSTADDRCTRL_SET(addr_ctrl);
- }
- /**
- * @brief Set DMA channel infinite loop mode
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] infinite_loop false - normal mode(single times mode); true - infinite loop mode(cycle mode)
- *
- */
- static inline void dma_set_infinite_loop_mode(DMAV2_Type *ptr, uint32_t ch_index, bool infinite_loop)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_INFINITELOOP_MASK) | DMAV2_CHCTRL_CTRL_INFINITELOOP_SET(infinite_loop);
- }
- /**
- * @brief Set DMA channel source burst option
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] burst_opt burst option
- * @arg @ref DMA_SRC_BURST_OPT_STANDAND_SIZE
- * @arg @ref DMA_SRC_BURST_OPT_CUSTOM_SIZE
- *
- */
- static inline void dma_set_src_busrt_option(DMAV2_Type *ptr, uint32_t ch_index, uint8_t burst_opt)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_BURSTOPT_MASK) | DMAV2_CHCTRL_CTRL_BURSTOPT_SET(burst_opt);
- }
- /**
- * @brief Set DMA channel handshake option
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] handshake_opt handshake option
- * @arg @ref DMA_HANDSHAKE_OPT_ONE_BURST
- * @arg @ref DMA_HANDSHAKE_OPT_ALL_TRANSIZE
- *
- */
- static inline void dma_set_handshake_option(DMAV2_Type *ptr, uint32_t ch_index, uint8_t handshake_opt)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_HANDSHAKEOPT_MASK) | DMAV2_CHCTRL_CTRL_HANDSHAKEOPT_SET(handshake_opt);
- }
- #if defined(HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS) && (HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS == 1)
- /**
- * @brief Set DMA channel source burst in fixed transfer size enable or disable
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] enable false - disable; true - enable
- *
- */
- static inline void dma_set_source_burst_in_fixed_transize_enable(DMAV2_Type *ptr, uint32_t ch_index, bool enable)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRC_FIXBURST_MASK) | DMAV2_CHCTRL_CTRL_SRC_FIXBURST_SET(enable);
- }
- /**
- * @brief Set DMA channel destination burst in fixed transfer size enable or disable
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] enable false - disable; true - enable
- *
- */
- static inline void dma_set_destination_burst_in_fixed_transize_enable(DMAV2_Type *ptr, uint32_t ch_index, bool enable)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DST_FIXBURST_MASK) | DMAV2_CHCTRL_CTRL_DST_FIXBURST_SET(enable);
- }
- #endif
- #if defined(HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP) && (HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP == 1)
- /**
- * @brief Set DMA channel swap mode
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] swap_mode swap mode
- * @arg @ref DMA_SWAP_MODE_TABLE
- * @arg @ref DMA_SWAP_MODE_BYTE
- * @arg @ref DMA_SWAP_MODE_HALF_WORD
- * @arg @ref DMA_SWAP_MODE_WORD
- *
- */
- static inline void dma_set_swap_mode(DMAV2_Type *ptr, uint32_t ch_index, uint8_t swap_mode)
- {
- ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SWAP_CTL_MASK) | DMAV2_CHCTRL_CTRL_SWAP_CTL_SET(swap_mode);
- }
- /**
- * @brief Set DMA channel swap table
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Index of the channel
- * @param[in] swap_table swap table
- *
- */
- static inline void dma_set_swap_table(DMAV2_Type *ptr, uint32_t ch_index, uint32_t swap_table)
- {
- ptr->CHCTRL[ch_index].SWAPTABLE = swap_table;
- }
- #endif
- /**
- * @brief Abort channel transfer with mask
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index_mask Mask of channels to be aborted
- */
- static inline void dma_abort_channel(DMAV2_Type *ptr, uint32_t ch_index_mask)
- {
- ptr->CHABORT |= DMAV2_CHABORT_CHABORT_SET(ch_index_mask);
- }
- /**
- * @brief Check if channels are enabled with mask
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index_mask Mask of channels to be checked
- *
- * @return Enabled channel mask
- */
- static inline uint32_t dma_check_enabled_channel(DMAV2_Type *ptr,
- uint32_t ch_index_mask)
- {
- return (ch_index_mask & ptr->CHEN);
- }
- /**
- * @brief Check if linked pointer has been configured
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Target channel index to be checked
- *
- * @return true if linked pointer has been configured
- */
- static inline bool dma_has_linked_pointer_configured(DMAV2_Type *ptr, uint32_t ch_index)
- {
- return ptr->CHCTRL[ch_index].LLPOINTER != 0;
- }
- /**
- * @brief Check transfer status
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Target channel index to be checked
- *
- * @retval DMA_CHANNEL_STATUS_ONGOING if transfer is still ongoing
- * @retval DMA_CHANNEL_STATUS_ERROR if any error occurred during transferring
- * @retval DMA_CHANNEL_STATUS_ABORT if transfer is aborted
- * @retval DMA_CHANNEL_STATUS_TC if transfer is finished without error
- * @retval DMA_CHANNEL_STATUS_HALF_TC if half transfer complete without error
- */
- static inline uint32_t dma_check_transfer_status(DMAV2_Type *ptr, uint8_t ch_index)
- {
- uint32_t dma_status = 0;
- if (ptr->INTTCSTS & (1 << ch_index)) {
- dma_status |= DMA_CHANNEL_STATUS_TC;
- ptr->INTTCSTS = (1 << ch_index); /* W1C clear status*/
- }
- if (ptr->INTHALFSTS & (1 << ch_index)) {
- dma_status |= DMA_CHANNEL_STATUS_HALF_TC;
- ptr->INTHALFSTS = (1 << ch_index); /* W1C clear status*/
- }
- if (ptr->INTERRSTS & (1 << ch_index)) {
- dma_status |= DMA_CHANNEL_STATUS_ERROR;
- ptr->INTERRSTS = (1 << ch_index); /* W1C clear status*/
- }
- if (ptr->INTABORTSTS & (1 << ch_index)) {
- dma_status |= DMA_CHANNEL_STATUS_ABORT;
- ptr->INTABORTSTS = (1 << ch_index); /* W1C clear status*/
- }
- if (dma_status == 0) {
- dma_status = DMA_CHANNEL_STATUS_ONGOING;
- }
- return dma_status;
- }
- /**
- * @brief Clear transfer status
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Target channel index
- *
- */
- static inline void dma_clear_transfer_status(DMAV2_Type *ptr, uint8_t ch_index)
- {
- /* W1C */
- ptr->INTHALFSTS = (1 << ch_index);
- ptr->INTTCSTS = (1 << ch_index);
- ptr->INTABORTSTS = (1 << ch_index);
- ptr->INTERRSTS = (1 << ch_index);
- }
- /**
- * @brief Enable DMA Channel interrupt
- *
- * @param [in] ptr DMA base address
- * @param [in] ch_index Target channel index
- * @param [in] interrupt_mask Interrupt mask
- */
- static inline void dma_enable_channel_interrupt(DMAV2_Type *ptr, uint8_t ch_index, int32_t interrupt_mask)
- {
- ptr->CHCTRL[ch_index].CTRL &= ~(interrupt_mask & DMA_INTERRUPT_MASK_ALL);
- }
- /**
- * @brief Disable DMA Channel interrupt
- *
- * @param [in] ptr DMA base address
- * @param [in] ch_index Target channel index
- * @param [in] interrupt_mask Interrupt mask
- */
- static inline void dma_disable_channel_interrupt(DMAV2_Type *ptr, uint8_t ch_index, int32_t interrupt_mask)
- {
- ptr->CHCTRL[ch_index].CTRL |= (interrupt_mask & DMA_INTERRUPT_MASK_ALL);
- }
- /**
- * @brief Check Channel interrupt master
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_index Target channel index to be checked
- * @return uint32_t Interrupt mask
- */
- static inline uint32_t dma_check_channel_interrupt_mask(DMAV2_Type *ptr, uint8_t ch_index)
- {
- return ptr->CHCTRL[ch_index].CTRL & DMA_INTERRUPT_MASK_ALL;
- }
- /**
- * @brief Get default channel config
- *
- * @param[in] ptr DMA base address
- * @param[in] ch Channel config
- */
- void dma_default_channel_config(DMAV2_Type *ptr, dma_channel_config_t *ch);
- /**
- * @brief Setup DMA channel
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_num Target channel index to be configured
- * @param[in] ch Channel config
- * @param[in] start_transfer Set true to start transfer
- *
- * @return status_success if everything is okay
- */
- hpm_stat_t dma_setup_channel(DMAV2_Type *ptr, uint8_t ch_num,
- dma_channel_config_t *ch, bool start_transfer);
- /**
- * @brief Config linked descriptor function
- *
- * @param[in] ptr DMA base address
- * @param[in] descriptor Linked descriptor pointer
- * @param[in] ch_num Target channel index to be configured
- * @param[in] config Descriptor config pointer
- *
- * @return status_success if everything is okay
- */
- hpm_stat_t dma_config_linked_descriptor(DMAV2_Type *ptr, dma_linked_descriptor_t *descriptor, uint8_t ch_num, dma_channel_config_t *config);
- /**
- * @brief Start DMA copy
- *
- * @param[in] ptr DMA base address
- * @param[in] ch_num Target channel index
- * @param[in] dst Destination address
- * @param[in] src Source Address
- * @param[in] size_in_byte Size in byte
- * @param[in] burst_len_in_byte Burst length in byte
- *
- * @return status_success if everthing is okay
- * @note: dst, src, size should be aligned with burst_len_in_byte
- */
- hpm_stat_t dma_start_memcpy(DMAV2_Type *ptr, uint8_t ch_num,
- uint32_t dst, uint32_t src,
- uint32_t size_in_byte, uint32_t burst_len_in_byte);
- /**
- * @brief Get default handshake config
- *
- * @param[in] ptr DMA base address
- * @param[in] config default config
- */
- void dma_default_handshake_config(DMAV2_Type *ptr, dma_handshake_config_t *config);
- /**
- * @brief config dma handshake function
- *
- * @param[in] ptr DMA base address
- * @param[in] pconfig dma handshake config pointer
- * @param[in] start_transfer Set true to start transfer
- *
- * @return status_success if everything is okay
- */
- hpm_stat_t dma_setup_handshake(DMAV2_Type *ptr, dma_handshake_config_t *pconfig, bool start_transfer);
- /**
- * @brief Check whether DMA is idle
- * @param [in] ptr DMA base address
- * @return true DMA is idle
- * @return false DMA is busy
- */
- static inline bool dma_is_idle(DMAV2_Type *ptr)
- {
- return (DMAV2_IDMISC_DMASTATE_GET(ptr->IDMISC) == dmav2_state_idle) ? true : false;
- }
- #ifdef __cplusplus
- }
- #endif
- /**
- * @}
- */
- #endif /* HPM_DMAV2_DRV_H */
|