PeripheralDriver_Flagchip_F.../Inc/module_driver_dma.h

517 lines
18 KiB
C

/**
* @file module_driver_dma.h
* @author flagchip
* @brief DMA driver type definition and API
* @version 2.0.0
* @date 2024-08-20
*
* SDK Version: 2.6.0
*
* @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd.
*
*/
/* ********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2023-12-15 Flagchip073 N/A First version for FC7300
* 2.0.0 2024-10-12 Flagchip073 N/A Change version and release
******************************************************************************** */
#ifndef _DRIVER_MODULE_DRIVER_DMA_H_
#define _DRIVER_MODULE_DRIVER_DMA_H_
#include "HwA_dma.h"
#if DMA_INSTANCE_COUNT > 0U
#include "HwA_dmamux.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @addtogroup module_driver_dma
* @{
*/
#define DMA_CHANNEL_INVALID (0xFFU)
/**
* @brief DMA transfer complete callback function prototype
*
*/
typedef void (*DMA_TransferCompleteCallbackType)(void *arg);
/**
* @brief DMA transfer error callback function prototype
*
*/
typedef void (*DMA_TransferErrorCallbackType)(void *arg);
/**
* @brief Available DMA Instances
*
*/
typedef enum
{
DMA_INSTANCE_0 = 0U,
DMA_INSTANCE_1 = 1U,
DMA_INSTANCE_MAX = DMA_INSTANCE_COUNT
} DMA_InstanceType;
/**
* @brief Available DMA channels
*
*/
typedef enum
{
DMA_CHANNEL_0 = 0U,
DMA_CHANNEL_1 = 1U,
DMA_CHANNEL_2 = 2U,
DMA_CHANNEL_3 = 3U,
DMA_CHANNEL_4 = 4U,
DMA_CHANNEL_5 = 5U,
DMA_CHANNEL_6 = 6U,
DMA_CHANNEL_7 = 7U,
DMA_CHANNEL_8 = 8U,
DMA_CHANNEL_9 = 9U,
DMA_CHANNEL_10 = 10U,
DMA_CHANNEL_11 = 11U,
DMA_CHANNEL_12 = 12U,
DMA_CHANNEL_13 = 13U,
DMA_CHANNEL_14 = 14U,
DMA_CHANNEL_15 = 15U,
DMA_CHANNEL_16 = 16U,
DMA_CHANNEL_17 = 17U,
DMA_CHANNEL_18 = 18U,
DMA_CHANNEL_19 = 19U,
DMA_CHANNEL_20 = 20U,
DMA_CHANNEL_21 = 21U,
DMA_CHANNEL_22 = 22U,
DMA_CHANNEL_23 = 23U,
DMA_CHANNEL_24 = 24U,
DMA_CHANNEL_25 = 25U,
DMA_CHANNEL_26 = 26U,
DMA_CHANNEL_27 = 27U,
DMA_CHANNEL_28 = 28U,
DMA_CHANNEL_29 = 29U,
DMA_CHANNEL_30 = 30U,
DMA_CHANNEL_31 = 31U,
DMA_CHANNEL_MAX = DMA_CFG_COUNT
} DMA_ChannelType;
/**
* @brief DMA operation return values
*
*/
typedef enum
{
DMA_STATUS_SUCCESS = 0x00U, /*!< The DMA operation is succeeded */
DMA_STATUS_ERROR = 0x01U, /*!< The DMA operation is failed */
DMA_STATUS_BUSY = 0x02U, /*!< The DMA operation is failed because DMA engine is busy */
DMA_STATUS_TIMEOUT = 0x03U, /*!< The DMA operation is failed because operation time out */
DMA_STATUS_UNSUPPORTED = 0x04U, /*!< The DMA configuration parameter is unsupported */
DMA_STATUS_INVALID_ADDRESS = 0x05U, /*!< The DMA source/destination address is invalid */
DMA_STATUS_NO_RESOURCE = 0x06U /*!< The DMA operation is failed because there is no resource */
} DMA_StatusType;
/**
* @brief DMA data increment size
*
* Specify the data increment size after DMA engine transferred a datum
*
*/
typedef enum
{
DMA_INCREMENT_DISABLE = 0x0U, /*!< The data address not increase */
DMA_INCREMENT_DATA_SIZE = 0x1U, /*!< The data address increase by the data size */
DMA_INCREMENT_DATA_SIZE_4BYTE_ALIGNED = 0x2U /*!< The data address increase by the data size,
and is 4 byte aligned */
} DMA_IncrementModeType;
/**
* @brief The size of the circular buffer
*
* @note The start address of the circular buffer should be aligned by the circular
* buffer size
*
*/
typedef enum
{
DMA_CIRCULAR_BUFFER_SIZE_1B = 0x1U,
DMA_CIRCULAR_BUFFER_SIZE_2B = 0x2U,
DMA_CIRCULAR_BUFFER_SIZE_4B = 0x4U,
DMA_CIRCULAR_BUFFER_SIZE_8B = 0x8U,
DMA_CIRCULAR_BUFFER_SIZE_16B = 0x10U,
DMA_CIRCULAR_BUFFER_SIZE_32B = 0x20U,
DMA_CIRCULAR_BUFFER_SIZE_64B = 0x40U,
DMA_CIRCULAR_BUFFER_SIZE_128B = 0x80U,
DMA_CIRCULAR_BUFFER_SIZE_256B = 0x100U,
DMA_CIRCULAR_BUFFER_SIZE_512B = 0x200U,
DMA_CIRCULAR_BUFFER_SIZE_1KB = 0x400U,
DMA_CIRCULAR_BUFFER_SIZE_2KB = 0x800U,
DMA_CIRCULAR_BUFFER_SIZE_4KB = 0x1000U,
DMA_CIRCULAR_BUFFER_SIZE_8KB = 0x2000U,
DMA_CIRCULAR_BUFFER_SIZE_16KB = 0x4000U,
DMA_CIRCULAR_BUFFER_SIZE_32KB = 0x8000U,
DMA_CIRCULAR_BUFFER_SIZE_64KB = 0x10000U,
DMA_CIRCULAR_BUFFER_SIZE_128KB = 0x20000U,
DMA_CIRCULAR_BUFFER_SIZE_256KB = 0x40000U,
DMA_CIRCULAR_BUFFER_SIZE_512KB = 0x80000U,
DMA_CIRCULAR_BUFFER_SIZE_1MB = 0x100000U,
DMA_CIRCULAR_BUFFER_SIZE_2MB = 0x200000U,
DMA_CIRCULAR_BUFFER_SIZE_4MB = 0x400000U,
DMA_CIRCULAR_BUFFER_SIZE_8MB = 0x800000U,
DMA_CIRCULAR_BUFFER_SIZE_16MB = 0x1000000U,
DMA_CIRCULAR_BUFFER_SIZE_32MB = 0x2000000U,
DMA_CIRCULAR_BUFFER_SIZE_64MB = 0x4000000U,
DMA_CIRCULAR_BUFFER_SIZE_128MB = 0x8000000U,
DMA_CIRCULAR_BUFFER_SIZE_256MB = 0x10000000U,
DMA_CIRCULAR_BUFFER_SIZE_512MB = 0x20000000U,
DMA_CIRCULAR_BUFFER_SIZE_1GB = 0x40000000U,
DMA_CIRCULAR_BUFFER_SIZE_2GB = 0x80000000U,
} DMA_CircularBufferSizeType;
/**
* @brief The eBufferRole of the circular buffer
*
*/
typedef enum
{
DMA_CIRCULAR_BUFFEER_ROLE_SOURCE = 0x0U, /*!< The circular buffer is used as the data source */
DMA_CIRCULAR_BUFFEER_ROLE_DESTINATION = 0x1U /*!< The circular buffer is used as the data destination */
} DMA_CircularBufferRoleType;
/**
* @name DMA API Service IDs
*
* @{
*/
#define DMA_INIT_ID 0U
#define DMA_INIT_CHANNEL_ID 1U
#define DMA_DEINIT_CHANNEL_ID 2U
#define DMA_INIT_CHANNEL_INT_ID 3U
#define DMA_CONFIG_CHAINED_TRANS_ID 4U
#define DMA_CONFIG_MODIFY_ADDR_ID 5U
#define DMA_CONFIG_START_CH_ID 6U
#define DMA_CONFIG_STOP_CH_ID 7U
#define DMA_CONFIG_GET_CH_REQ_SOURCE_ID 8U
#define DMA_CONFIG_GET_CH_STATUS_ID 9U
#define DMA_CONFIG_GET_MON_ID 10U
#define DMA_CONFIG_GET_STATUS_ID 11U
#define DMA_CONFIG_CLEAR_MON_ID 12U
#define DMA_CONFIG_DISABLE_MON_ID 13U
#define DMA_CONFIG_EN_MON_ID 14U
#define DMA_CONFIG_CANCEL_TRANS_ID 15U
/** @}*/
/**
* @name DMA Dev Error Code
* @brief Error Code of calling DMA apis
*
* @{
*/
#define DMA_E_PARAM_CHCFG 0x01U
#define DMA_E_PARAM_BLOCKCNT 0x02U
#define DMA_E_PARAM_BLOCKSIZE 0x03U
#define DMA_E_PARAM_DESTCIRCULARBUFSIZE 0x04U
#define DMA_E_PARAM_SRCCIRCULARBUFSIZE 0x05U
#define DMA_E_PARAM_INTERRUPTCFG 0x06U
#define DMA_E_PARAM_CHANNEL 0x07U
#define DMA_E_PARAM_INSTANCE 0x08U
#define DMA_E_PARAM_INITCFG 0x09U
#define DMA_E_PARAM_BLOCKSIZE_DATASIZE 0x0AU
/** @}*/
/**
* @brief The configuration parameters of the DMA engine
*
*/
typedef struct
{
DMA_ArbitrationAlgorithmType eArbitrationAlgorithm; /*!< Channel Arbitration Algorithm */
bool bHaltOnError; /*!< Whether DMA halts when error occured */
bool bGRP0HighPriority; /*!< Whether the priority of DMA group 0 channel is higher than group 1 channel*/
} DMA_InitType;
/**
* @brief The structure of the DMA processing handle
*
*/
typedef struct
{
struct
{
/* tStatus can not be set by user */
uint8_t u8DmaDumoUsedStatus[DMA_UMO_COUNT];
} tStatus;
struct
{
uint8_t u8Instance; /*!< DMA Channel*/
void (*pTransferErrorCallback[DMA_CFG_COUNT])(void *arg); /*!< fault interrupt callback */
void *errdata[DMA_CFG_COUNT];
} tSettings;
} DMA_InstanceHandleType;
typedef struct _DMA_HandleType
{
struct
{
uint8_t u8Channel; /*!< DMA Channel*/
DMA_InstanceHandleType *pInstance;
struct
{
void *completedata;
void (*pTransferCompleteCallback)(void *arg); /*!< channel interrupt callback */
} callback;
} tSettings;
} DMA_HandleType;
/**
* @brief The configutation parameters of the DMA channel
*
* @note The u8ChannelPriority must be unique for different channels, the default is the channel number.
* The u16BlockCount must be greater than 0.
* @note When Circular buffer is enabled, the data address should be power of 2 aligned to the buffer size.
* For example, if the circular buffer size is 32 byte, the data address should be 32 byte aligned. If the
* circular buffer size is 40 byte, then the data address should be 64 byte aligned.
*
*/
typedef struct
{
const volatile void *pSrcBuffer; /*!< the source address of the data */
volatile void *pDestBuffer; /*!< the destination address of the data */
void *completedata;
void *errdata;
uint32_t u32BlockSize; /*!< the data size of one block in byte */
uint16_t u16BlockCount; /*!< the number of data blocks in one transfer */
uint8_t u8ChannelPriority; /*!< channel priority, greater number means higher priority */
DMA_TransferSizeType eSrcDataSize; /*!< source data size */
DMA_TransferSizeType eDestDataSize; /*!< destination data size */
DMA_IncrementModeType eSrcIncMode; /*!< source data address increment mode */
DMA_IncrementModeType eDestIncMode; /*!< destination data address increment mode */
bool bSrcBlockOffsetEn; /*!< whether to add a block offset to the source address after
a block transfer */
bool bDestBlockOffsetEn; /*!< whether to add a block offset to the destination address after
a block transfer */
int32_t s32BlockOffset; /*!< the signed address offset applied to the src/dest address
after a block transfer */
bool bSrcAddrLoopbackEn; /*!< whether the source address return to the set value after transfer */
bool bDestAddrLoopbackEn; /*!< whether the destination address return to the set value after transfer */
bool bAutoStop; /*!< whether the DMA channel transfer automatically stops after one
transfer finishes when the channel is triggered by hardware */
bool bSrcCircularBufferEn; /*!< the source buffer of the DMA channel is a circular buffer */
uint32_t u32SrcCircBufferSize; /*!< the source circular buffer size in byte, the buffer size is suggested
to be power of 2 aligned */
bool bDestCircularBufferEn; /*!< the destination buffer of the DMA channel is a circular buffer */
uint32_t u32DestCircBufferSize; /*!< the destination circular buffer size in byte, the buffer size is suggested
to be power of 2 aligned */
bool bInnerChannelChain;
DMA_RequestSourceType eTriggerSrc; /*!< Select the DMA channel trigger source, if the trigger source is
DMA_REQ_DISABLED, the channel is triggered by software */
bool bTransferCompleteIntEn; /*!< Enable interrupt after transfer complete */
DMA_TransferCompleteCallbackType pTransferCompleteNotify; /*!< transfer complete notification */
bool bTransferErrorIntEn; /*!< Enable interrupt when transfer error occured */
DMA_TransferErrorCallbackType pTransferErrorNotify; /*!< transfer error notification */
} DMA_ChannelCfgType;
/**
* @brief The parameters to configure the DMA channel as a circular buffer engine
*
*/
typedef struct
{
DMA_CircularBufferRoleType eBufferRole; /*!< the source or the destination address is a circular buffer */
DMA_CircularBufferSizeType eBufferSize; /*!< the circular buffer size */
bool bCircularBufferEn; /*!< enable the DMA channel as a circular buffer engine */
} DMA_CircularBufferType;
/**
* @brief The paarameters to configure the DMA chainned transfer
*
*/
typedef struct
{
bool bChanelChainEn; /*!< Whether to start the chained channel when the current completed */
uint8_t u8ChainedChannel; /*!< The chained channel */
} DMA_ChainTransferType;
/**
* @brief Initialize the DMA instance
*
* @param pDmaInstanceHandle DMA handle
* @param pInitCfg the configuration of the DMA instance
*/
void DMA_Init(DMA_InstanceHandleType *pDmaInstanceHandle, const DMA_InitType *const pInitCfg);
/**
* @brief De-initialize the DMA instance
*
* Disable the DMA and restore its configure values to default
*
* @param pDmaInstanceHandle DMA handle
*/
void DMA_DeInit(DMA_InstanceHandleType *pDmaInstanceHandle);
/**
* @brief Initialize the DMA channel
*
* @param pDmaHandle the DMA channel to initialize
* @param pChnCfg the configuration of the channel
* @return DMA_StatusType whether the channel is initiallized successfully
*/
DMA_StatusType DMA_InitChannel(DMA_HandleType *pDmaHandle, const DMA_ChannelCfgType *const pChnCfg);
/**
* @brief De-initialize the DMA channel
*
* @param pDmaHandle the DMA channel to de-initialize
*/
void DMA_DeinitChannel(DMA_HandleType *pDmaHandle);
/**
* @brief Initialize the DMA channel interrupt
*
* @param pDmaHandle the DMA channel to use
* @param pChnCfg the configuration of the DMA channel
*/
void DMA_InitChannelInterrupt(DMA_HandleType *pDmaHandle, const DMA_ChannelCfgType *const pChnCfg);
/**
* @brief Config the DMA channel chained transfer
*
* @param pDmaHandle the DMA channel to use
* @param pChainTransferCfg the parameters of the chained channel
*/
void DMA_ConfigChainedTransfer(DMA_HandleType *pDmaHandle,
const DMA_ChainTransferType *const pChainTransferCfg);
/**
* @brief Modify the source and destination address of the DMA channel
*
* @note This function should be called when the DMA channel is not actively transferring
*
* @param pDmaHandle the channel to modify
* @param pSrcBuffer the new source address of data, set NULL to remain unmodified
* @param pDestBuffer the new destination address of data, set NULL to remain unmodified
* @return DMA_StatusType whether the address is successfully modified
*/
DMA_StatusType DMA_ModifyAddress(DMA_HandleType *pDmaHandle, const volatile void *pSrcBuffer,
const volatile void *pDestBuffer);
/**
* @brief Start the DMA channel transfer
*
* If the trigger source for the DMA channel is DMA_REQ_DISABLED, the channel will start
* immediately after called this function. Otherwise, the channel will start when the
* trigger source is generated on the channel.
*
* @param pDmaHandle the DMA channel to start
*/
void DMA_StartChannel(DMA_HandleType *pDmaHandle);
/**
* @brief Stop the DMA channel transfer
*
* If the trigger source for the DMA channel is DMA_REQ_DISABLED, the channel will stop
* automatically after the transfer completed. Otherwise, you should call this function
* manually if you do not want the DMA to be triggered when hardware request is generated.
*
* @note If there is ongoing transfer on the channel, the channel will be stopped after the
* transfer completed.
*
* @param pDmaHandle the DMA channel to stop
*/
void DMA_StopChannel(DMA_HandleType *pDmaHandle);
/**
* @brief Cancel the ongoing DMA transfer
*
* @param pDmaInstanceHandle DMA handle
* @param bGenerateErr whether an error will be generated on the transferring channel
* @return DMA_StatusType whether the transfer is stopped successfully
*/
DMA_StatusType DMA_CancelTransfer(DMA_InstanceHandleType *pDmaInstanceHandle, bool bGenerateErr);
#ifdef DMA_HAVE_MONCHK
/**
* @brief Enable DMA Error Monitor checker function.
*
* @param u8Dma_Instance The selected DMA instance number.
*/
void DMA_EnableMonitorChecker(DMA_InstanceHandleType *pDmaInstanceHandle);
/**
* @brief Disable DMA Error Monitor checker function.
*
* @param u8Dma_Instance The selected DMA instance number.
*/
void DMA_DisableMonitorChecker(DMA_InstanceHandleType *pDmaInstanceHandle);
/**
* @brief Clear all DMA Error Monitor checker error bits.
*
* @param u8Dma_Instance The selected DMA instance number.
*/
void DMA_ClearMonitorCheckerAllError(DMA_InstanceHandleType *pDmaInstanceHandle);
/**
* @brief Get DMA Monitor checker error status.
*
* @param u8Dma_Instance The selected DMA instance number.
* @return uint32_t the error status for monitor checker.
*/
uint32_t DMA_GetMonitorCheckerErrStatus(DMA_InstanceHandleType *pDmaInstanceHandle);
#endif
/**
* @brief Get the request source of the selected channel
*
* @param pDmaHandle the DMA channel to get the request source
* @return DMA_RequestSourceType the request source of the selected channel
*/
DMA_RequestSourceType DMA_GetChannelRequestSrc(DMA_HandleType *pDmaHandle);
/**
* @brief Get the status of the DMA engine
*
* @return DMA_RunningStatusType the status of the DMA engine
*/
DMA_RunningStatusType DMA_GetStatus(DMA_InstanceHandleType *pDmaInstanceHandle);
/**
* @brief Get the status of the DMA channel
*
* @param pDmaHandle the DMA channel to get the status
* @return DMA_RunningStatusType the status of the DMA channel
*/
DMA_RunningStatusType DMA_GetChannelStatus(DMA_HandleType *pDmaHandle);
/**
* @brief The internal interrupt handler for DMA transfer complete
*
* @param pDmaHandle the handle of the DMA complete interrpt
*/
void DMA_Transfer_Complete_IRQHandler(DMA_HandleType *pDmaHandle);
/**
* @brief The internal interrupt handler for DMA error complete
*
* @param pDmaInstanceHandle the handle of the DMA complete interrpt
*/
void DMA_ProcessErrorInterrupt(DMA_InstanceHandleType *pDmaInstanceHandle);
/** @}*/ /* module_driver_dma */
#if defined(__cplusplus)
}
#endif
#endif /* #if DMA_INSTANCE_COUNT > 0U */
#endif