Boen_Shi 8be2866433 feat(base): 初始化 MSPM0 开发环境
- 添加头文件和配置文件支持
- 更新.gitignore忽略编译和IDE相关文件
- 添加基础的bsp代码
2026-07-16 14:45:26 +08:00

1652 lines
59 KiB
C

/*
* Copyright (c) 2020, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * 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.
*
* * Neither the name of Texas Instruments Incorporated 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 OWNER 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.
*/
/*!****************************************************************************
* @file dl_dma.h
* @brief Direct Memory Access (DMA) Driver Library
* @defgroup DMA Direct Memory Access (DMA)
*
* @anchor ti_dl_dl_m0p_dma_Overview
* # Overview
*
* The Direct Memory Access (DMA) Library allows full configuration of
* the MSPM0 DMA module.
* The DMA controller transfers data from one address to another, without CPU
* intervention, across the entire address range.
* DMA controllers have multiple channels that can be configured independently
*
******************************************************************************
*/
/** @addtogroup DMA
* @{
*/
#ifndef ti_dl_dl_m0p_dma__include
#define ti_dl_dl_m0p_dma__include
#include <stdbool.h>
#include <stdint.h>
#include <ti/devices/msp/msp.h>
#include <ti/driverlib/dl_common.h>
#ifdef __cplusplus
extern "C" {
#endif
#if (DMA_SYS_N_DMA_FULL_CHANNEL > 0)
/*!
* @brief Device has support for DMA FULL channels
*/
#define DEVICE_HAS_DMA_FULL_CHANNEL
#endif
#ifdef DMA_SYS_MMR_LLONG
/*!
* @brief Device has support for DMA 128-bit access on all channels
*/
#define DEVICE_HAS_LLONG_ACCESS
/*!
* @brief If device has LLONG support, it will also support AUTO reg and GATHER mode
*/
#define DEVICE_HAS_AUTO_AND_GATHER
#endif
/* clang-format off */
/** @addtogroup DL_DMA_INTERRUPT
* @{
*/
/*!
* @brief DMA channel 0 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL0 (DMA_CPU_INT_IMASK_DMACH0_SET)
/*!
* @brief DMA channel 1 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL1 (DMA_CPU_INT_IMASK_DMACH1_SET)
/*!
* @brief DMA channel 2 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL2 (DMA_CPU_INT_IMASK_DMACH2_SET)
/*!
* @brief DMA channel 3 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL3 (DMA_CPU_INT_IMASK_DMACH3_SET)
/*!
* @brief DMA channel 4 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL4 (DMA_CPU_INT_IMASK_DMACH4_SET)
/*!
* @brief DMA channel 5 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL5 (DMA_CPU_INT_IMASK_DMACH5_SET)
/*!
* @brief DMA channel 6 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL6 (DMA_CPU_INT_IMASK_DMACH6_SET)
/*!
* @brief DMA channel 7 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL7 (DMA_CPU_INT_IMASK_DMACH7_SET)
/*!
* @brief DMA channel 8 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL8 (DMA_CPU_INT_IMASK_DMACH8_SET)
/*!
* @brief DMA channel 9 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL9 (DMA_CPU_INT_IMASK_DMACH9_SET)
/*!
* @brief DMA channel 10 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL10 (DMA_CPU_INT_IMASK_DMACH10_SET)
/*!
* @brief DMA channel 12 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL12 (DMA_CPU_INT_IMASK_DMACH12_SET)
/*!
* @brief DMA channel 13 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL13 (DMA_CPU_INT_IMASK_DMACH13_SET)
/*!
* @brief DMA channel 14 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL14 (DMA_CPU_INT_IMASK_DMACH14_SET)
/*!
* @brief DMA channel 15 interrupt
*/
#define DL_DMA_INTERRUPT_CHANNEL15 (DMA_CPU_INT_IMASK_DMACH15_SET)
#ifdef DEVICE_HAS_DMA_FULL_CHANNEL
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 0 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_INTERRUPT_EARLY_CHANNEL0 (DMA_CPU_INT_IMASK_PREIRQCH0_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 1 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_INTERRUPT_EARLY_CHANNEL1 (DMA_CPU_INT_IMASK_PREIRQCH1_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 2 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_INTERRUPT_EARLY_CHANNEL2 (DMA_CPU_INT_IMASK_PREIRQCH2_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 3 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_INTERRUPT_EARLY_CHANNEL3 (DMA_CPU_INT_IMASK_PREIRQCH3_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 4 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_INTERRUPT_EARLY_CHANNEL4 (DMA_CPU_INT_IMASK_PREIRQCH4_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 5 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_INTERRUPT_EARLY_CHANNEL5 (DMA_CPU_INT_IMASK_PREIRQCH5_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 6 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_INTERRUPT_EARLY_CHANNEL6 (DMA_CPU_INT_IMASK_PREIRQCH6_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 7 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_INTERRUPT_EARLY_CHANNEL7 (DMA_CPU_INT_IMASK_PREIRQCH7_SET)
#endif /* DEVICE_HAS_DMA_FULL_CHANNEL */
/*!
* @brief DMA address error, source address not reachable
*/
#define DL_DMA_INTERRUPT_ADDR_ERROR (DMA_CPU_INT_IMASK_ADDRERR_SET)
/*!
* @brief DMA data error, source data might be corrupted (PAR or ECC error)
*/
#define DL_DMA_INTERRUPT_DATA_ERROR (DMA_CPU_INT_IMASK_DATAERR_SET)
/** @}*/
/** @addtogroup DL_DMA_EVENT
* @{
*/
/*!
* @brief DMA channel 0 interrupt
*/
#define DL_DMA_EVENT_CHANNEL0 (DMA_GEN_EVENT_IMASK_DMACH0_SET)
/*!
* @brief DMA channel 1 interrupt
*/
#define DL_DMA_EVENT_CHANNEL1 (DMA_GEN_EVENT_IMASK_DMACH1_SET)
/*!
* @brief DMA channel 2 interrupt
*/
#define DL_DMA_EVENT_CHANNEL2 (DMA_GEN_EVENT_IMASK_DMACH2_SET)
/*!
* @brief DMA channel 3 interrupt
*/
#define DL_DMA_EVENT_CHANNEL3 (DMA_GEN_EVENT_IMASK_DMACH3_SET)
/*!
* @brief DMA channel 4 interrupt
*/
#define DL_DMA_EVENT_CHANNEL4 (DMA_GEN_EVENT_IMASK_DMACH4_SET)
/*!
* @brief DMA channel 5 interrupt
*/
#define DL_DMA_EVENT_CHANNEL5 (DMA_GEN_EVENT_IMASK_DMACH5_SET)
/*!
* @brief DMA channel 6 interrupt
*/
#define DL_DMA_EVENT_CHANNEL6 (DMA_GEN_EVENT_IMASK_DMACH6_SET)
/*!
* @brief DMA channel 7 interrupt
*/
#define DL_DMA_EVENT_CHANNEL7 (DMA_GEN_EVENT_IMASK_DMACH7_SET)
/*!
* @brief DMA channel 8 interrupt
*/
#define DL_DMA_EVENT_CHANNEL8 (DMA_GEN_EVENT_IMASK_DMACH8_SET)
/*!
* @brief DMA channel 9 interrupt
*/
#define DL_DMA_EVENT_CHANNEL9 (DMA_GEN_EVENT_IMASK_DMACH9_SET)
/*!
* @brief DMA channel 10 interrupt
*/
#define DL_DMA_EVENT_CHANNEL10 (DMA_GEN_EVENT_IMASK_DMACH10_SET)
/*!
* @brief DMA channel 12 interrupt
*/
#define DL_DMA_EVENT_CHANNEL12 (DMA_GEN_EVENT_IMASK_DMACH12_SET)
/*!
* @brief DMA channel 13 interrupt
*/
#define DL_DMA_EVENT_CHANNEL13 (DMA_GEN_EVENT_IMASK_DMACH13_SET)
/*!
* @brief DMA channel 14 interrupt
*/
#define DL_DMA_EVENT_CHANNEL14 (DMA_GEN_EVENT_IMASK_DMACH14_SET)
/*!
* @brief DMA channel 15 interrupt
*/
#define DL_DMA_EVENT_CHANNEL15 (DMA_GEN_EVENT_IMASK_DMACH15_SET)
#ifdef DEVICE_HAS_DMA_FULL_CHANNEL
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 0 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_EVENT_EARLY_CHANNEL0 (DMA_GEN_EVENT_IMASK_PREIRQCH0_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 1 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_EVENT_EARLY_CHANNEL1 (DMA_GEN_EVENT_IMASK_PREIRQCH1_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 2 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_EVENT_EARLY_CHANNEL2 (DMA_GEN_EVENT_IMASK_PREIRQCH2_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 3 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_EVENT_EARLY_CHANNEL3 (DMA_GEN_EVENT_IMASK_PREIRQCH3_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 4 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_EVENT_EARLY_CHANNEL4 (DMA_GEN_EVENT_IMASK_PREIRQCH4_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 5 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_EVENT_EARLY_CHANNEL5 (DMA_GEN_EVENT_IMASK_PREIRQCH5_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 6 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_EVENT_EARLY_CHANNEL6 (DMA_GEN_EVENT_IMASK_PREIRQCH6_SET)
/*!
* @brief Available for FULL-channel configuration only. Early IRQ for DMA
* channel 7 interrupt. Size counter has reached early IRQ threshold.
*/
#define DL_DMA_FULL_CH_EVENT_EARLY_CHANNEL7 (DMA_GEN_EVENT_IMASK_PREIRQCH7_SET)
#endif /* DEVICE_HAS_DMA_FULL_CHANNEL */
/*!
* @brief DMA address error, source address not reachable
*/
#define DL_DMA_EVENT_ADDR_ERROR (DMA_GEN_EVENT_IMASK_ADDRERR_SET)
/*!
* @brief DMA data error, source data might be corrupted (PAR or ECC error)
*/
#define DL_DMA_EVENT_DATA_ERROR (DMA_GEN_EVENT_IMASK_DATAERR_SET)
/** @}*/
/*! @enum DL_DMA_TRANSFER_MODE */
typedef enum {
/*! Each DMA trigger results in a single data transfer, once */
DL_DMA_SINGLE_TRANSFER_MODE = DMA_DMACTL_DMATM_SINGLE,
/*! Each DMA trigger results in a transfer of a block of data, once */
DL_DMA_SINGLE_BLOCK_TRANSFER_MODE = DMA_DMACTL_DMATM_BLOCK,
#ifdef DEVICE_HAS_DMA_FULL_CHANNEL
/*! Available for FULL-channel configuration only. Each DMA trigger results
* in a single data transfer, repeating */
DL_DMA_FULL_CH_REPEAT_SINGLE_TRANSFER_MODE = DMA_DMACTL_DMATM_RPTSNGL,
/*! Available for FULL-channel configuration only. Each DMA trigger results
* in a transfer of a block of data, repeating */
DL_DMA_FULL_CH_REPEAT_BLOCK_TRANSFER_MODE = DMA_DMACTL_DMATM_RPTBLCK,
#endif /* DEVICE_HAS_DMA_FULL_CHANNEL */
} DL_DMA_TRANSFER_MODE;
/*! @enum DL_DMA_EXTENDED_MODE */
typedef enum {
/*! Normal operation */
DL_DMA_NORMAL_MODE = DMA_DMACTL_DMAEM_NORMAL,
#ifdef DEVICE_HAS_DMA_FULL_CHANNEL
#ifdef DEVICE_HAS_AUTO_AND_GATHER
/*! Available for FULL-channel configuration only. Reads data from
* address table located at source address and transfers data to
* destination address */
DL_DMA_FULL_CH_GATHER_MODE = DMA_DMACTL_DMAEM_GATHERMODE,
#endif /* DEVICE_HAS_AUTO_AND_GATHER */
/*! Available for FULL-channel configuration only. Fills the destination
* with a specific value */
DL_DMA_FULL_CH_FILL_MODE = DMA_DMACTL_DMAEM_FILLMODE,
/*! Available for FULL-channel configuration only. The source data contains
* addresses and data */
DL_DMA_FULL_CH_TABLE_MODE = DMA_DMACTL_DMAEM_TABLEMODE,
#endif /* DEVICE_HAS_DMA_FULL_CHANNEL */
} DL_DMA_EXTENDED_MODE;
/*! @enum DL_DMA_INCREMENT */
typedef enum {
/*! Do not change address after each transfer */
DL_DMA_ADDR_UNCHANGED = DMA_DMACTL_DMASRCINCR_UNCHANGED,
/*! Decrement address by 1 * DL_DMA_WIDTH after each transfer */
DL_DMA_ADDR_DECREMENT = DMA_DMACTL_DMASRCINCR_DECREMENT,
/*! Increment address by 1 * DL_DMA_WIDTH after each transfer */
DL_DMA_ADDR_INCREMENT = DMA_DMACTL_DMASRCINCR_INCREMENT,
/*! Stride mode 2, increment address by 2 * DL_DMA_WIDTH (skip over every
* other element) */
DL_DMA_ADDR_STRIDE_2 = DMA_DMACTL_DMASRCINCR_STRIDE_2,
/*! Stride mode 3, increment address by 3 * DL_DMA_WIDTH (skip over two
* elements */
DL_DMA_ADDR_STRIDE_3 = DMA_DMACTL_DMASRCINCR_STRIDE_3,
/*! Stride mode 4, increment address by 4 * DL_DMA_WIDTH (skip over three
* elements */
DL_DMA_ADDR_STRIDE_4 = DMA_DMACTL_DMASRCINCR_STRIDE_4,
/*! Stride mode 5, increment address by 5 * DL_DMA_WIDTH (skip over four
* elements */
DL_DMA_ADDR_STRIDE_5 = DMA_DMACTL_DMASRCINCR_STRIDE_5,
/*! Stride mode 6, increment address by 6 * DL_DMA_WIDTH (skip over five
* elements */
DL_DMA_ADDR_STRIDE_6 = DMA_DMACTL_DMASRCINCR_STRIDE_6,
/*! Stride mode 7, increment address by 7 * DL_DMA_WIDTH (skip over six
* elements */
DL_DMA_ADDR_STRIDE_7 = DMA_DMACTL_DMASRCINCR_STRIDE_7,
/*! Stride mode 8, increment address by 8 * DL_DMA_WIDTH (skip over seven
* elements */
DL_DMA_ADDR_STRIDE_8 = DMA_DMACTL_DMASRCINCR_STRIDE_8,
/*! Stride mode 9, increment address by 9 * DL_DMA_WIDTH (skip over eight
* elements */
DL_DMA_ADDR_STRIDE_9 = DMA_DMACTL_DMASRCINCR_STRIDE_9,
} DL_DMA_INCREMENT;
/*! @enum DL_DMA_EARLY_INTERRUPT_THRESHOLD */
typedef enum {
/*! Disable early interrupt events */
DL_DMA_EARLY_INTERRUPT_THRESHOLD_DISABLED = DMA_DMACTL_DMAPREIRQ_PREIRQ_DISABLE,
/*! Generate Early-IRQ event with one transfer pending (DMASZ=1) */
DL_DMA_EARLY_INTERRUPT_THRESHOLD_1 = DMA_DMACTL_DMAPREIRQ_PREIRQ_1,
/*! Generate Early-IRQ event with two transfers pending (DMASZ=2) */
DL_DMA_EARLY_INTERRUPT_THRESHOLD_2 = DMA_DMACTL_DMAPREIRQ_PREIRQ_2,
/*! Generate Early-IRQ event with three transfers pending (DMASZ=4) */
DL_DMA_EARLY_INTERRUPT_THRESHOLD_4 = DMA_DMACTL_DMAPREIRQ_PREIRQ_4,
/*! Generate Early-IRQ event with eight transfers pending (DMASZ=8) */
DL_DMA_EARLY_INTERRUPT_THRESHOLD_8 = DMA_DMACTL_DMAPREIRQ_PREIRQ_8,
/*! Generate Early-IRQ event with 32 transfers pending (DMASZ=32) */
DL_DMA_EARLY_INTERRUPT_THRESHOLD_32 = DMA_DMACTL_DMAPREIRQ_PREIRQ_32,
/*! Generate Early-IRQ event with 64 transfers pending (DMASZ=64) */
DL_DMA_EARLY_INTERRUPT_THRESHOLD_64 = DMA_DMACTL_DMAPREIRQ_PREIRQ_64,
/*! Generate Early-IRQ event when DMASZ reaches the half size point of the
* original transfer size */
DL_DMA_EARLY_INTERRUPT_THRESHOLD_HALF = DMA_DMACTL_DMAPREIRQ_PREIRQ_HALF,
} DL_DMA_EARLY_INTERRUPT_THRESHOLD;
/*! @enum DL_DMA_BURST_SIZE */
typedef enum {
/*! No burst interruption. The block transfer always transfers all elements
* defined in the DMASZ register before priority is newly evaluated */
DL_DMA_BURST_SIZE_INFINITY = DMA_DMAPRIO_BURSTSZ_INFINITI,
/*! Burst size of a block transfer is 8 */
DL_DMA_BURST_SIZE_8 = DMA_DMAPRIO_BURSTSZ_BURST_8,
/*! Burst size of a block transfer is 16 */
DL_DMA_BURST_SIZE_16 = DMA_DMAPRIO_BURSTSZ_BUSRT_16,
/*! Burst size of a block transfer is 32 */
DL_DMA_BURST_SIZE_32 = DMA_DMAPRIO_BURSTSZ_BURST_32,
} DL_DMA_BURST_SIZE;
/*! @enum DL_DMA_TRIGGER_TYPE */
typedef enum {
/*! Internal DMA channel is selected as the DMA trigger */
DL_DMA_TRIGGER_TYPE_INTERNAL = DMA_DMATCTL_DMATINT_INTERNAL,
/*! External DMA channel is selected as the DMA trigger */
DL_DMA_TRIGGER_TYPE_EXTERNAL = DMA_DMATCTL_DMATINT_EXTERNAL,
} DL_DMA_TRIGGER_TYPE;
/*! @enum DL_DMA_WIDTH */
typedef enum {
/*! Byte Acccess (8-bit) */
DL_DMA_WIDTH_BYTE = DMA_DMACTL_DMASRCWDTH_BYTE,
/*! Half Word Acccess (16-bit) */
DL_DMA_WIDTH_HALF_WORD = DMA_DMACTL_DMASRCWDTH_HALF,
/*! Word Acccess (32-bit) */
DL_DMA_WIDTH_WORD = DMA_DMACTL_DMASRCWDTH_WORD,
/*! Long Acccess (64-bit) */
DL_DMA_WIDTH_LONG = DMA_DMACTL_DMASRCWDTH_LONG,
#ifdef DEVICE_HAS_LLONG_ACCESS
/*! Long-long Acccess (128-bit) */
DL_DMA_WIDTH_LONG_LONG = DMA_DMACTL_DMASRCWDTH_LONGLONG,
#endif /* DEVICE_HAS_LLONG_ACCESS*/
} DL_DMA_WIDTH;
/*! @enum DL_DMA_EVENT_IIDX */
typedef enum {
/*! Enum to indicate that no DMA event has taken place */
DL_DMA_EVENT_IIDX_NO_INTR = DMA_GEN_EVENT_IIDX_STAT_NO_INTR,
/*! Enum to indicate that the channel 0 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH0 = DMA_GEN_EVENT_IIDX_STAT_DMACH0,
/*! Enum to indicate that the channel 1 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH1 = DMA_GEN_EVENT_IIDX_STAT_DMACH1,
/*! Enum to indicate that the channel 2 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH2 = DMA_GEN_EVENT_IIDX_STAT_DMACH2,
/*! Enum to indicate that the channel 3 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH3 = DMA_GEN_EVENT_IIDX_STAT_DMACH3,
/*! Enum to indicate that the channel 4 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH4 = DMA_GEN_EVENT_IIDX_STAT_DMACH4,
/*! Enum to indicate that the channel 5 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH5 = DMA_GEN_EVENT_IIDX_STAT_DMACH5,
/*! Enum to indicate that the channel 6 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH6 = DMA_GEN_EVENT_IIDX_STAT_DMACH6,
/*! Enum to indicate that the channel 7 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH7 = DMA_GEN_EVENT_IIDX_STAT_DMACH7,
/*! Enum to indicate that the channel 8 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH8 = DMA_GEN_EVENT_IIDX_STAT_DMACH8,
/*! Enum to indicate that the channel 9 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH9 = DMA_GEN_EVENT_IIDX_STAT_DMACH9,
/*! Enum to indicate that the channel 10 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH10 = DMA_GEN_EVENT_IIDX_STAT_DMACH10,
/*! Enum to indicate that the channel 11 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH11 = DMA_GEN_EVENT_IIDX_STAT_DMACH11,
/*! Enum to indicate that the channel 12 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH12 = DMA_GEN_EVENT_IIDX_STAT_DMACH12,
/*! Enum to indicate that the channel 13 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH13 = DMA_GEN_EVENT_IIDX_STAT_DMACH13,
/*! Enum to indicate that the channel 14 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH14 = DMA_GEN_EVENT_IIDX_STAT_DMACH14,
/*! Enum to indicate that the channel 15 interrupt has fired */
DL_DMA_EVENT_IIDX_DMACH15 = DMA_GEN_EVENT_IIDX_STAT_DMACH15,
#ifdef DEVICE_HAS_DMA_FULL_CHANNEL
/*! Available for FULL-channel configuration only. Enum to indicate that the
* early interrupt event for channel 0 interrupt has fired */
DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH0 = DMA_GEN_EVENT_IIDX_STAT_PREIRQCH0,
/*! Available for FULL-channel configuration only. Enum to indicate that the
* early interrupt event for channel 1 interrupt has fired */
DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH1 = DMA_GEN_EVENT_IIDX_STAT_PREIRQCH1,
/*! Available for FULL-channel configuration only. Enum to indicate that the
* early interrupt event for channel 2 interrupt has fired */
DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH2 = DMA_GEN_EVENT_IIDX_STAT_PREIRQCH2,
/*! Available for FULL-channel configuration only. Enum to indicate that the
* early interrupt event for channel 3 interrupt has fired */
DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH3 = DMA_GEN_EVENT_IIDX_STAT_PREIRQCH3,
/*! Available for FULL-channel configuration only. Enum to indicate that the
* early interrupt event for channel 4 interrupt has fired */
DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH4 = DMA_GEN_EVENT_IIDX_STAT_PREIRQCH4,
/*! Available for FULL-channel configuration only. Enum to indicate that the
* early interrupt event for channel 5 interrupt has fired */
DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH5 = DMA_GEN_EVENT_IIDX_STAT_PREIRQCH5,
/*! Available for FULL-channel configuration only. Enum to indicate that the
* early interrupt event for channel 6 interrupt has fired */
DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH6 = DMA_GEN_EVENT_IIDX_STAT_PREIRQCH6,
/*! Available for FULL-channel configuration only. Enum to indicate that the
* early interrupt event for channel 7 interrupt has fired */
DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH7 = DMA_GEN_EVENT_IIDX_STAT_PREIRQCH7,
#endif /* DEVICE_HAS_DMA_FULL_CHANNEL */
/*! Enum to indicate that a DMA address error has occurred */
DL_DMA_EVENT_IIDX_ADDR_ERROR = DMA_GEN_EVENT_IIDX_STAT_ADDRERR,
/*! Enum to indicate that a DMA data error has occurred */
DL_DMA_EVENT_IIDX_DATA_ERROR = DMA_GEN_EVENT_IIDX_STAT_DATAERR
} DL_DMA_EVENT_IIDX;
/*! @enum DL_DMA_PUBLISHER_INDEX */
typedef enum {
/*! DMA Publisher index 0 */
DL_DMA_PUBLISHER_INDEX_0 = 0,
} DL_DMA_PUBLISHER_INDEX;
/*! @enum DL_DMA_SUBSCRIBER_INDEX */
typedef enum {
/*! DMA Subscriber index 0 */
DL_DMA_SUBSCRIBER_INDEX_0 = 0,
/*! DMA Subscriber index 1 */
DL_DMA_SUBSCRIBER_INDEX_1 = 1
} DL_DMA_SUBSCRIBER_INDEX;
/*! @enum DL_DMA_AUTOEN */
typedef enum {
/*! No automatic DMA enable */
DL_DMA_AUTOEN_DISABLE = DMA_DMACTL_DMAAUTOEN_DISABLE,
#ifdef DEVICE_HAS_AUTO_AND_GATHER
/*! Automatic DMA enable on DMASA register write */
DL_DMA_AUTOEN_DMASA = DMA_DMACTL_DMAAUTOEN_DMASA,
/*! Automatic DMA enable on DMADA register write */
DL_DMA_AUTOEN_DMADA = DMA_DMACTL_DMAAUTOEN_DMADA,
/*! Automatic DMA enable on DMASZ register write */
DL_DMA_AUTOEN_DMASZ = DMA_DMACTL_DMAAUTOEN_DMASZ,
#endif /* DEVICE_HAS_AUTO_AND_GATHER*/
} DL_DMA_AUTOEN;
/* clang-format on */
/*!
* @brief Configuration struct for @ref DL_DMA_initChannel.
*/
typedef struct {
/*!
* The event that should trigger a DMA transfer. Refer to the datasheet of
* the device for which DMA trigger values map to which events.
*/
uint8_t trigger;
/*!
* Configure whether the DMA selects an internal or external channel as
* the DMA trigger
*/
DL_DMA_TRIGGER_TYPE triggerType;
/*!
* The transfer mode to use. Refer to the device datasheet to determine
* which modes are supported in the selected channel.
* One of @ref DL_DMA_TRANSFER_MODE.
*/
DL_DMA_TRANSFER_MODE transferMode;
/*! The extended mode to use. One of @ref DL_DMA_EXTENDED_MODE. */
DL_DMA_EXTENDED_MODE extendedMode;
/*! The width of the DMA source. One of @ref DL_DMA_WIDTH. */
DL_DMA_WIDTH srcWidth;
/*! The width of the DMA destination. One of @ref DL_DMA_WIDTH. */
DL_DMA_WIDTH destWidth;
/*!
* Amount to increment/decrement the DMA source address by. One of
* @ref DL_DMA_INCREMENT.
*/
DL_DMA_INCREMENT srcIncrement;
/*!
* Amount to increment/decrement the DMA destination address by. One of
* @ref DL_DMA_INCREMENT.
*/
DL_DMA_INCREMENT destIncrement;
} DL_DMA_Config;
/**
* @brief Initialize a DMA channel
*
* Initializes all the configurable options for a DMA channel. The DMA channel
* is not enabled in this API.
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] config Pointer to DMA channel configuration settings
*/
void DL_DMA_initChannel(
DMA_Regs *dma, uint8_t channelNum, const DL_DMA_Config *config);
/**
* @brief Configure a DMA channel for a transfer
*
* Configures the transfer settings for a DMA channel. The DMA channel is
* not enabled in this API.
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] transferMode The transfer mode to use. Refer to the device
* datasheet to determine which modes are supported
* in the selected channel. One of
* @ref DL_DMA_TRANSFER_MODE.
* @param[in] extendedMode The extended mode to use. One of
* @ref DL_DMA_EXTENDED_MODE.
* @param[in] srcWidth The width of the DMA source. One of
* @ref DL_DMA_WIDTH.
* @param[in] destWidth The width of the DMA destination. One of
* @ref DL_DMA_WIDTH.
* @param[in] srcIncrement Amount to increment/decrement the DMA source
* address by. One of @ref DL_DMA_INCREMENT.
* @param[in] destIncrement Amount to increment/decrement the DMA destination
* address by. One of @ref DL_DMA_INCREMENT.
*/
__STATIC_INLINE void DL_DMA_configTransfer(DMA_Regs *dma, uint8_t channelNum,
DL_DMA_TRANSFER_MODE transferMode, DL_DMA_EXTENDED_MODE extendedMode,
DL_DMA_WIDTH srcWidth, DL_DMA_WIDTH destWidth,
DL_DMA_INCREMENT srcIncrement, DL_DMA_INCREMENT destIncrement)
{
dma->DMACHAN[channelNum].DMACTL =
((uint32_t) transferMode | (uint32_t) extendedMode |
(((uint32_t) destIncrement) << 4) | (uint32_t) srcIncrement |
((uint32_t) destWidth << 4) | (uint32_t) srcWidth);
}
/**
* @brief Configure the DMA for round-robin priority
*
* When round-robin priority is enabled, the channel that completes a transfer
* becomes the lowest priority. If multiple triggers happen simultaneously or
* are pending, the channel that transferred least recently will transfer
* first. Once it's complete the next highest priority channel will transfer.
*
* @param[in] dma Pointer to the register overlay for the peripheral
*/
__STATIC_INLINE void DL_DMA_enableRoundRobinPriority(DMA_Regs *dma)
{
dma->DMAPRIO |= DMA_DMAPRIO_ROUNDROBIN_ENABLE;
}
/**
* @brief Disable round-robin priority for the DMA
*
* When round-robin priority is disabled, the channel priorities are fixed
* in ascending order (Channel 0 is the lowed priority). If multiple triggers
* happen simultaneously or are pending, the channel with the highest priority
* completes its transfer before the next-highest transfer can start.
*
* @param[in] dma Pointer to the register overlay for the peripheral
*/
__STATIC_INLINE void DL_DMA_disableRoundRobinPriority(DMA_Regs *dma)
{
dma->DMAPRIO &= ~(DMA_DMAPRIO_ROUNDROBIN_MASK);
}
/**
* @brief Check if round-robin priority is enabled for the DMA
*
* @param[in] dma Pointer to the register overlay for the peripheral
*
* @return The status of round-robin priority
*
* @retval true Round-robin priority is enabled
* @retval false Round-robin priority is disabled
*/
__STATIC_INLINE bool DL_DMA_isRoundRobinPriorityEnabled(const DMA_Regs *dma)
{
return ((dma->DMAPRIO & DMA_DMAPRIO_ROUNDROBIN_MASK) ==
DMA_DMAPRIO_ROUNDROBIN_ENABLE);
}
/**
* @brief Set the burst size for block transfers
*
* After the DMA transfers the amount of transfers defined by
* @ref DL_DMA_BURST_SIZE, the ongoing block transfer is interrupted and the
* priority encoder has the chance to assign a higher priority channel. The
* previously interrupted block transfer is internally marked as pending and
* when no other high priority channel is pending the block transfer will
* continue with the next burst or until DMASZ counts down to 0.
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] burstSize The burst size to set. One of
* @ref DL_DMA_BURST_SIZE.
*
* @sa DL_DMA_configTransfer
*/
__STATIC_INLINE void DL_DMA_setBurstSize(
DMA_Regs *dma, DL_DMA_BURST_SIZE burstSize)
{
DL_Common_updateReg(
&dma->DMAPRIO, (uint32_t) burstSize, DMA_DMAPRIO_BURSTSZ_MASK);
}
/**
* @brief Get the burst size for block transfers
*
* @param[in] dma Pointer to the register overlay for the peripheral
*
* @return The burst size for block transfers
*
* @retval One of @ref DL_DMA_BURST_SIZE
*/
__STATIC_INLINE DL_DMA_BURST_SIZE DL_DMA_getBurstSize(const DMA_Regs *dma)
{
uint32_t burstSize = dma->DMAPRIO & DMA_DMAPRIO_BURSTSZ_MASK;
return (DL_DMA_BURST_SIZE)(burstSize);
}
/**
* @brief Enable a DMA channel for transfers
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*/
__STATIC_INLINE void DL_DMA_enableChannel(DMA_Regs *dma, uint8_t channelNum)
{
dma->DMACHAN[channelNum].DMACTL |= DMA_DMACTL_DMAEN_ENABLE;
}
/**
* @brief Disable a DMA channel for transfers
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*/
__STATIC_INLINE void DL_DMA_disableChannel(DMA_Regs *dma, uint8_t channelNum)
{
dma->DMACHAN[channelNum].DMACTL &= ~(DMA_DMACTL_DMAEN_MASK);
}
/**
* @brief Check if a DMA channel is enabled for transfers
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The status of the DMA channel
*
* @retval true The DMA channel is enabled
* @retval false The DMA channel is disabled
*/
__STATIC_INLINE bool DL_DMA_isChannelEnabled(
const DMA_Regs *dma, uint8_t channelNum)
{
return ((dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMAEN_MASK) ==
DMA_DMACTL_DMAEN_ENABLE);
}
/**
* @brief Configure the mode for a DMA channel
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] transferMode The transfer mode to set for the channel. Refer to
* the device datasheet to determine which modes are
* supported in the selected channel. One of
* @ref DL_DMA_TRANSFER_MODE.
* @param[in] extendedMode The extended operation mode to set for the
* channel. One of @ref DL_DMA_EXTENDED_MODE.
*
* @sa DL_DMA_configTransfer
*/
__STATIC_INLINE void DL_DMA_configMode(DMA_Regs *dma, uint8_t channelNum,
DL_DMA_TRANSFER_MODE transferMode, DL_DMA_EXTENDED_MODE extendedMode)
{
DL_Common_updateReg(&dma->DMACHAN[channelNum].DMACTL,
(uint32_t) transferMode | (uint32_t) extendedMode,
DMA_DMACTL_DMATM_MASK | DMA_DMACTL_DMAEM_MASK);
}
/**
* @brief Set a DMA channel's transfer mode
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] transferMode The transfer mode to use. Refer to the device
* datasheet to determine which modes are supported
* in the selected channel. One of
* @ref DL_DMA_TRANSFER_MODE.
*
* @sa DL_DMA_configMode
* @sa DL_DMA_configTransfer
*/
__STATIC_INLINE void DL_DMA_setTransferMode(
DMA_Regs *dma, uint8_t channelNum, DL_DMA_TRANSFER_MODE transferMode)
{
DL_Common_updateReg(&dma->DMACHAN[channelNum].DMACTL,
(uint32_t) transferMode, DMA_DMACTL_DMATM_MASK);
}
/**
* @brief Get a DMA channel's transfer mode
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The channel's transfer mode
*
* @retval One of @ref DL_DMA_TRANSFER_MODE
*/
__STATIC_INLINE DL_DMA_TRANSFER_MODE DL_DMA_getTransferMode(
const DMA_Regs *dma, uint8_t channelNum)
{
uint32_t mode = (dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMATM_MASK);
return (DL_DMA_TRANSFER_MODE)(mode);
}
/**
* @brief Set a DMA channel's extended mode
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] extendedMode The transfer mode to use. One of
* @ref DL_DMA_EXTENDED_MODE.
*
* @sa DL_DMA_configMode
* @sa DL_DMA_configTransfer
*/
__STATIC_INLINE void DL_DMA_setExtendedMode(
DMA_Regs *dma, uint8_t channelNum, DL_DMA_EXTENDED_MODE extendedMode)
{
DL_Common_updateReg(&dma->DMACHAN[channelNum].DMACTL,
(uint32_t) extendedMode, DMA_DMACTL_DMAEM_MASK);
}
/**
* @brief Get a DMA channel's extended mode
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The channel's transfer mode
*
* @retval One of @ref DL_DMA_EXTENDED_MODE
*/
__STATIC_INLINE DL_DMA_EXTENDED_MODE DL_DMA_getExtendedMode(
const DMA_Regs *dma, uint8_t channelNum)
{
uint32_t mode = (dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMAEM_MASK);
return (DL_DMA_EXTENDED_MODE)(mode);
}
/**
* @brief Start a DMA transfer using software
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*/
__STATIC_INLINE void DL_DMA_startTransfer(DMA_Regs *dma, uint8_t channelNum)
{
dma->DMACHAN[channelNum].DMACTL |= DMA_DMACTL_DMAREQ_REQUEST;
}
/**
* @brief Set a channel's trigger for a DMA transfer
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] trigger What should trigger a DMA transfer. Refer to the
* datasheet of the device for which DMA trigger
* values map to which events.
* @param[in] triggerType Whether an internal or external DMA channel is
* selected as the DMA trigger. Refer to the datasheet
* for more information on the DMA channels.
*/
__STATIC_INLINE void DL_DMA_setTrigger(DMA_Regs *dma, uint8_t channelNum,
uint8_t trigger, DL_DMA_TRIGGER_TYPE triggerType)
{
DL_Common_updateReg(&dma->DMATRIG[channelNum].DMATCTL,
trigger | (uint32_t) triggerType,
DMA_DMATCTL_DMATSEL_MASK | DMA_DMATCTL_DMATINT_MASK);
}
/**
* @brief Get the current trigger for a DMA channel
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return What is configured to trigger a DMA transfer.
*
* @retval Check the device datasheet for what values are mapped to on
* your device.
*/
__STATIC_INLINE uint32_t DL_DMA_getTrigger(
const DMA_Regs *dma, uint8_t channelNum)
{
return (dma->DMATRIG[channelNum].DMATCTL & DMA_DMATCTL_DMATSEL_MASK);
}
/**
* @brief Get the current trigger type for a DMA channel
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return Whether an internal or external DMA channel is selected as the
* DMA trigger.
*
* @retval One of @ref DL_DMA_TRIGGER_TYPE
*/
__STATIC_INLINE DL_DMA_TRIGGER_TYPE DL_DMA_getTriggerType(
const DMA_Regs *dma, uint8_t channelNum)
{
uint32_t triggerType =
(dma->DMATRIG[channelNum].DMATCTL & DMA_DMATCTL_DMATINT_MASK);
return (DL_DMA_TRIGGER_TYPE)(triggerType);
}
/**
* @brief Set a DMA channel's source address
*
* Set the source address for a DMA channel for transferring data from. This
* address can be automatically incremented/decremented after the completion
* of a transfer by using the @ref DL_DMA_setSrcIncrement function.
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] srcAddr Address to set as the DMA source
*
* @sa DL_DMA_setSrcIncrement
*/
__STATIC_INLINE void DL_DMA_setSrcAddr(
DMA_Regs *dma, uint8_t channelNum, uint32_t srcAddr)
{
dma->DMACHAN[channelNum].DMASA = srcAddr;
}
/**
* @brief Get a DMA channel's source address
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return Source address for the DMA channel
*/
__STATIC_INLINE uint32_t DL_DMA_getSrcAddr(
const DMA_Regs *dma, uint8_t channelNum)
{
return dma->DMACHAN[channelNum].DMASA;
}
/**
* @brief Set a DMA channel's destination address
*
* Set the destination address for a DMA channel for transferring data to.
* This address can be automatically incremented/decremented after the
* completion of a transfer by using the @ref DL_DMA_setDestIncrement
* function.
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] destAddr Address to set as the DMA destination
*
* @sa DL_DMA_setDestIncrement
*/
__STATIC_INLINE void DL_DMA_setDestAddr(
DMA_Regs *dma, uint8_t channelNum, uint32_t destAddr)
{
dma->DMACHAN[channelNum].DMADA = destAddr;
}
/**
* @brief Get a DMA channel's destination address
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return Destination address for the DMA channel
*/
__STATIC_INLINE uint32_t DL_DMA_getDestAddr(
const DMA_Regs *dma, uint8_t channelNum)
{
return dma->DMACHAN[channelNum].DMADA;
}
/**
* @brief Set the size of a block for a DMA transfer
*
* Defines the size of the block of data to transfer.
*
* When the transfer mode @ref DL_DMA_TRANSFER_MODE is a Block transfer mode,
* this is the size of the block of data transferred every trigger.
*
* When in the transfer mode @ref DL_DMA_TRANSFER_MODE is a Single transfer
* mode, this is how many triggers need to occur before the block is considered
* done, which then sets the interrupt status.
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] size The size of the block of data to transfer. Value
* between 0 - 65535.
*/
__STATIC_INLINE void DL_DMA_setTransferSize(
DMA_Regs *dma, uint8_t channelNum, uint16_t size)
{
dma->DMACHAN[channelNum].DMASZ = size;
}
/**
* @brief Get a channel's size of block of data for a DMA transfer
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The channel's size of block of data to transfer
*
* @retval A value between 0 - 65535.
*/
__STATIC_INLINE uint16_t DL_DMA_getTransferSize(
const DMA_Regs *dma, uint8_t channelNum)
{
return (uint16_t)(dma->DMACHAN[channelNum].DMASZ & DMA_DMASZ_SIZE_MASK);
}
/**
* @brief Set a channel's source address increment amount
*
* After each DMA transfer the channel source address, which can be set by
* @ref DL_DMA_setSrcAddr, can be incremented, decremented or remain
* unchanged. This controls if the DMA is copying from a fixed address or a
* block of addresses.
*
* The amount that is incremented/decremented is controlled by the width of
* the source, set by @ref DL_DMA_setSrcWidth.
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] srcIncrement Amount to increment/decrement the DMA source
* address by. One of @ref DL_DMA_INCREMENT.
*
* @sa DL_DMA_configTransfer
* @sa DL_DMA_setSrcAddr
* @sa DL_DMA_setSrcWidth
*/
__STATIC_INLINE void DL_DMA_setSrcIncrement(
DMA_Regs *dma, uint8_t channelNum, DL_DMA_INCREMENT srcIncrement)
{
DL_Common_updateReg(&dma->DMACHAN[channelNum].DMACTL,
(uint32_t) srcIncrement, DMA_DMACTL_DMASRCINCR_MASK);
}
/**
* @brief Return a channel's source address increment amount
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The source address increment amount for selected channel
*
* @retval One of @ref DL_DMA_INCREMENT.
*/
__STATIC_INLINE DL_DMA_INCREMENT DL_DMA_getSrcIncrement(
const DMA_Regs *dma, uint8_t channelNum)
{
uint32_t incrementAmount =
(dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMASRCINCR_MASK);
return (DL_DMA_INCREMENT)(incrementAmount);
}
/**
* @brief Set a channel's destination address increment amount
*
* After each DMA transfer the channel destination address, which can be set by
* @ref DL_DMA_setDestAddr, can be incremented, decremented or remain
* unchanged. This controls if the DMA is copying from a fixed address or a
* block of addresses.
*
* The amount that is incremented/decremented is controlled by the width of
* the destination, set by @ref DL_DMA_setDestWidth.
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] destIncrement Amount to increment/decrement the DMA destination
* address by. One of @ref DL_DMA_INCREMENT.
*
* @sa DL_DMA_configTransfer
* @sa DL_DMA_setDestAddr
* @sa DL_DMA_setDestWidth
*/
__STATIC_INLINE void DL_DMA_setDestIncrement(
DMA_Regs *dma, uint8_t channelNum, DL_DMA_INCREMENT destIncrement)
{
/* Left shifted by 4 so the defines align with bitfield */
DL_Common_updateReg(&dma->DMACHAN[channelNum].DMACTL,
((uint32_t) destIncrement) << 4, DMA_DMACTL_DMADSTINCR_MASK);
}
/**
* @brief Return a channel's destination address increment amount
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The destination address increment amount for selected channel
*
* @retval One of @ref DL_DMA_INCREMENT.
*/
__STATIC_INLINE DL_DMA_INCREMENT DL_DMA_getDestIncrement(
const DMA_Regs *dma, uint8_t channelNum)
{
/* Right shifted by 4 to align with provided defines */
uint32_t incrementAmount =
(dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMADSTINCR_MASK) >> 4;
return (DL_DMA_INCREMENT)(incrementAmount);
}
/**
* @brief Set the width of the DMA source address for a channel
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] srcWidth The width of the DMA source. One of
* @ref DL_DMA_WIDTH.
*
* @sa DL_DMA_configTransfer
*/
__STATIC_INLINE void DL_DMA_setSrcWidth(
DMA_Regs *dma, uint8_t channelNum, DL_DMA_WIDTH srcWidth)
{
DL_Common_updateReg(&dma->DMACHAN[channelNum].DMACTL, (uint32_t) srcWidth,
DMA_DMACTL_DMASRCWDTH_MASK);
}
/**
* @brief Get the width of the DMA source address for a channel
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The width of the DMA source for selected channel
*
* @retval One of @ref DL_DMA_WIDTH.
*/
__STATIC_INLINE DL_DMA_WIDTH DL_DMA_getSrcWidth(
const DMA_Regs *dma, uint8_t channelNum)
{
uint32_t width =
(dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMASRCWDTH_MASK);
return (DL_DMA_WIDTH)(width);
}
/**
* @brief Set the width of the DMA destination address for a channel
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] destWidth The width of the DMA destination. One of
* @ref DL_DMA_WIDTH.
*
* @sa DL_DMA_configTransfer
*/
__STATIC_INLINE void DL_DMA_setDestWidth(
DMA_Regs *dma, uint8_t channelNum, DL_DMA_WIDTH destWidth)
{
/* Left shifted by 4 to align with provided defines */
DL_Common_updateReg(&dma->DMACHAN[channelNum].DMACTL,
((uint32_t) destWidth) << 4, DMA_DMACTL_DMADSTWDTH_MASK);
}
/**
* @brief Get the width of the DMA destination address for a channel
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The width of the DMA destination for selected channel
*
* @retval One of @ref DL_DMA_WIDTH.
*/
__STATIC_INLINE DL_DMA_WIDTH DL_DMA_getDestWidth(
const DMA_Regs *dma, uint8_t channelNum)
{
/* Right shifted by 4 to align with provided defines */
uint32_t width =
(dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMADSTWDTH_MASK) >> 4;
return (DL_DMA_WIDTH)(width);
}
#ifdef DEVICE_HAS_DMA_FULL_CHANNEL
/**
* @brief Set the early interrupt event.
*
* This functionality is available for FULL-channel configuration only. Please
* refer to the device datasheet to map which channels have FULL or BASIC
* capability.
*
* The DMA has the capability to generate an early interrupt with a
* given amount of transfer cycles before the DMA complete-interrupt is issued.
* This allows to start the ISR context switch in parallel with the completion
* of the DMA, and compensates the latency for the task switch into the ISR.
*
* Ideally when the ISR starts to execute and read IIDX, the IIDX will already
* point to the channel-complete interrupt (always higher priority than the
* PRE-IRQ). In this case the latency is minimal and the ISR needs to clear
* the PRE-IRQ interrupt flag (RIS) manually.
* Should for whatever reason the DMA not complete in time, the IIDX will point
* to the PRE-IRQ handler and the handler needs to poll for the DMAEN bit in
* the DMA channel control register (DMACTL) to catch the moment that the DMA
* transfer has completed. Then the handler needs to clear the DMA
* channel-complete IRQ flag manually.
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] channelNum DMA channel to operate on
* @param[in] threshold When to generate the early interrupt. One of
* @ref DL_DMA_EARLY_INTERRUPT_THRESHOLD.
*/
__STATIC_INLINE void DL_DMA_Full_Ch_setEarlyInterruptThreshold(DMA_Regs *dma,
uint8_t channelNum, DL_DMA_EARLY_INTERRUPT_THRESHOLD threshold)
{
DL_Common_updateReg(&dma->DMACHAN[channelNum].DMACTL, (uint32_t) threshold,
DMA_DMACTL_DMAPREIRQ_MASK);
}
/**
* @brief Get the early interrupt event threshold.
*
* This functionality is available for FULL-channel configuration only. Please
* refer to the device datasheet to map which channels have FULL or BASIC
* capability.
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The early interrupt event threshold
*
* @retval One of @ref DL_DMA_EARLY_INTERRUPT_THRESHOLD.
*/
__STATIC_INLINE DL_DMA_EARLY_INTERRUPT_THRESHOLD
DL_DMA_Full_Ch_getEarlyInterruptThreshold(
const DMA_Regs *dma, uint8_t channelNum)
{
uint32_t threshold =
dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMAPREIRQ_MASK;
return (DL_DMA_EARLY_INTERRUPT_THRESHOLD)(threshold);
}
#endif /* DEVICE_HAS_DMA_FULL_CHANNEL */
/**
* @brief Enable DMA interrupts
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] interruptMask Bit mask of interrupts to enable. Bitwise OR of
* @ref DL_DMA_INTERRUPT.
*/
__STATIC_INLINE void DL_DMA_enableInterrupt(
DMA_Regs *dma, uint32_t interruptMask)
{
dma->CPU_INT.IMASK |= interruptMask;
}
/**
* @brief Disable DMA interrupts
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] interruptMask Bit mask of interrupts to disable. Bitwise OR of
* @ref DL_DMA_INTERRUPT.
*/
__STATIC_INLINE void DL_DMA_disableInterrupt(
DMA_Regs *dma, uint32_t interruptMask)
{
dma->CPU_INT.IMASK &= ~(interruptMask);
}
/**
* @brief Check which DMA interrupts are enabled
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] interruptMask Bit mask of interrupts to check. Bitwise OR of
* @ref DL_DMA_INTERRUPT.
*
* @return Which of the requested DMA interrupts are enabled
*
* @retval Bitwise OR of @ref DL_DMA_INTERRUPT values
*/
__STATIC_INLINE uint32_t DL_DMA_getEnabledInterrupts(
const DMA_Regs *dma, uint32_t interruptMask)
{
return (dma->CPU_INT.IMASK & interruptMask);
}
/**
* @brief Check interrupt flag of enabled DMA interrupts
*
* Checks if any of the DMA interrupts that were previously enabled are
* pending.
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] interruptMask Bit mask of interrupts to check. Bitwise OR of
* @ref DL_DMA_INTERRUPT.
*
* @return Which of the requested DMA interrupts are pending
*
* @retval Bitwise OR of @ref DL_DMA_INTERRUPT values
*
* @sa DL_DMA_enableInterrupt
*/
__STATIC_INLINE uint32_t DL_DMA_getEnabledInterruptStatus(
const DMA_Regs *dma, uint32_t interruptMask)
{
return (dma->CPU_INT.MIS & interruptMask);
}
/**
* @brief Check interrupt flag of any DMA interrupt
*
* Checks if any of the DMA interrupts are pending. Interrupts do not have to
* be previously enabled.
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] interruptMask Bit mask of interrupts to check. Bitwise OR of
* @ref DL_DMA_INTERRUPT.
*
* @return Which of the requested DMA interrupts are pending
*
* @retval Bitwise OR of @ref DL_DMA_INTERRUPT values
*/
__STATIC_INLINE uint32_t DL_DMA_getRawInterruptStatus(
const DMA_Regs *dma, uint32_t interruptMask)
{
return (dma->CPU_INT.RIS & interruptMask);
}
/**
* @brief Get highest priority pending DMA interrupt
*
* Checks if any of the DMA interrupts are pending. Interrupts do not have to
* be previously enabled.
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
*
* @return The highest priority pending DMA interrupt
*
* @retval One of @ref DL_DMA_EVENT_IIDX
*/
__STATIC_INLINE DL_DMA_EVENT_IIDX DL_DMA_getPendingInterrupt(
const DMA_Regs *dma)
{
return (DL_DMA_EVENT_IIDX) dma->CPU_INT.IIDX;
}
/**
* @brief Clear pending DMA interrupts
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] interruptMask Bit mask of interrupts to clear. Bitwise OR of
* @ref DL_DMA_INTERRUPT.
*/
__STATIC_INLINE void DL_DMA_clearInterruptStatus(
DMA_Regs *dma, uint32_t interruptMask)
{
dma->CPU_INT.ICLR = interruptMask;
}
/**
* @brief Sets the event publisher channel id
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] index Specifies the register event index to be configured
* @param[in] chanID Channel ID number. Valid range 0-15. If ChanID == 0
* publisher is disconnected.
*/
__STATIC_INLINE void DL_DMA_setPublisherChanID(
DMA_Regs *dma, DL_DMA_PUBLISHER_INDEX index, uint8_t chanID)
{
volatile uint32_t *pReg = &dma->FPUB_1;
*(pReg + (uint32_t) index) = (chanID & DMA_FPUB_1_CHANID_MAXIMUM);
}
/**
* @brief Gets the event publisher channel id
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] index Specifies the register event index to be configured
*
* @return Event publisher channel ID
*
*/
__STATIC_INLINE uint8_t DL_DMA_getPublisherChanID(
DMA_Regs *dma, DL_DMA_PUBLISHER_INDEX index)
{
volatile uint32_t *pReg = &dma->FPUB_1;
return ((uint8_t)(*(pReg + (uint32_t) index) & DMA_FPUB_1_CHANID_MASK));
}
/**
* @brief Sets the event subscriber channel id
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] index Specifies the register event index to be configured
* @param[in] chanID Channel ID number. Valid range 0-15. If ChanID == 0
* subscriber is disconnected.
*/
__STATIC_INLINE void DL_DMA_setSubscriberChanID(
DMA_Regs *dma, DL_DMA_SUBSCRIBER_INDEX index, uint8_t chanID)
{
volatile uint32_t *pReg = &dma->FSUB_0;
*(pReg + (uint32_t) index) = (chanID & DMA_FSUB_0_CHANID_MAXIMUM);
}
/**
* @brief Gets the event subscriber channel id
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] index Specifies the register event index to be configured
*
* @return Event subscriber channel ID
*
*/
__STATIC_INLINE uint8_t DL_DMA_getSubscriberChanID(
DMA_Regs *dma, DL_DMA_SUBSCRIBER_INDEX index)
{
volatile uint32_t *pReg = &dma->FSUB_0;
return ((uint8_t)(*(pReg + (uint32_t) index) & DMA_FSUB_0_CHANID_MASK));
}
/**
* @brief Enable DMA event
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] eventMask Bit mask of events to enable. Bitwise OR of
* @ref DL_DMA_EVENT.
*/
__STATIC_INLINE void DL_DMA_enableEvent(DMA_Regs *dma, uint32_t eventMask)
{
dma->GEN_EVENT.IMASK |= (eventMask);
}
/**
* @brief Disable DMA event
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] eventMask Bit mask of events to enable. Bitwise OR of
* @ref DL_DMA_EVENT.
*/
__STATIC_INLINE void DL_DMA_disableEvent(DMA_Regs *dma, uint32_t eventMask)
{
dma->GEN_EVENT.IMASK &= ~(eventMask);
}
/**
* @brief Check which dma events triggers are enabled
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] eventMask Bit mask of events to check. Bitwise OR of
* @ref DL_DMA_EVENT.
*
* @return Which of the requested dma events are enabled
*
* @retval Bitwise OR of @ref DL_DMA_EVENT values
*/
__STATIC_INLINE uint32_t DL_DMA_getEnabledEvents(
const DMA_Regs *dma, uint32_t eventMask)
{
return (dma->GEN_EVENT.IMASK & eventMask);
}
/**
* @brief Check event flag of enabled dma event
*
* Checks if any of the dma events that were previously enabled are
* pending.
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] eventMask Bit mask of events to check. Bitwise OR of
* @ref DL_DMA_EVENT.
*
* @return Which of the requested dma events are pending
*
* @retval Bitwise OR of @ref DL_DMA_EVENT values
*
* @sa DL_DMA_enableEvent
*/
__STATIC_INLINE uint32_t DL_DMA_getEnabledEventStatus(
const DMA_Regs *dma, uint32_t eventMask)
{
return (dma->GEN_EVENT.MIS & ~(eventMask));
}
/**
* @brief Check event flag of any dma event
*
* Checks if any events are pending. Events do not have to
* be previously enabled.
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] eventMask Bit mask of event to check. Bitwise OR of
* @ref DL_DMA_EVENT.
*
* @return Which of the requested dma event are pending
*
* @retval Bitwise OR of @ref DL_DMA_EVENT values
*/
__STATIC_INLINE uint32_t DL_DMA_getRawEventsStatus(
const DMA_Regs *dma, uint32_t eventMask)
{
return (dma->GEN_EVENT.RIS & ~(eventMask));
}
/**
* @brief Clear pending dma events
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] eventMask Bit mask of events to clear. Bitwise OR of
* @ref DL_DMA_EVENT.
*/
__STATIC_INLINE void DL_DMA_clearEventsStatus(
DMA_Regs *dma, uint32_t eventMask)
{
dma->GEN_EVENT.ICLR |= (eventMask);
}
#ifdef DEVICE_HAS_AUTO_AND_GATHER
/**
* @brief Configure the DMA for auto-enable
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] mode Enable auto-enable for DMA on a specified register write. One of @ref DL_DMA_AUTOEN
* @param[in] channelNum DMA channel to operate on
*/
__STATIC_INLINE void DL_DMA_enableAutoEnable(
DMA_Regs *dma, DL_DMA_AUTOEN mode, uint8_t channelNum)
{
dma->DMACHAN[channelNum].DMACTL |= mode;
}
/**
* @brief Disable auto-enable for DMA
*
* @param[in] dma Pointer to the register overlay for the
* peripheral
* @param[in] channelNum DMA channel to operate on
*/
__STATIC_INLINE void DL_DMA_disableAutoEnable(
DMA_Regs *dma, uint8_t channelNum)
{
dma->DMACHAN[channelNum].DMACTL &= ~(DMA_DMACTL_DMAAUTOEN_MASK);
}
/**
* @brief Check if auto-enable is enabled for the DMA
*
* @param[in] dma Pointer to the register overlay for the peripheral
* @param[in] channelNum DMA channel to operate on
*
* @return The status of auto-enable
*
* @retval true auto-enable is enabled
* @retval false auto-enable is disabled
*/
__STATIC_INLINE bool DL_DMA_isAutoEnableEnabled(
const DMA_Regs *dma, uint8_t channelNum)
{
return ((dma->DMACHAN[channelNum].DMACTL & DMA_DMACTL_DMAAUTOEN_MASK) !=
DMA_DMACTL_DMAAUTOEN_DISABLE);
}
#endif /* DEVICE_HAS_AUTO_AND_GATHER*/
#ifdef __cplusplus
}
#endif
#endif /* ti_dl_dl_m0p_dma__include */
/** @}*/