PeripheralDriver_Flagchip_F.../Inc/fc7xxx_driver_dma.h

369 lines
15 KiB
C

/**
* @file fc7xxx_driver_dma.h
* @author Flagchip0126
* @brief FC7xxx DMA driver type definition and API
* @version 0.1.0
* @date 2024-01-15
*
* @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd.
*
*/
/* ********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC240
******************************************************************************** */
#ifndef _DRIVER_FC4XXX_DRIVER_DMA_H_
#define _DRIVER_FC4XXX_DRIVER_DMA_H_
#include "device_header.h"
#include "HwA_dma.h"
#include "HwA_dmamux.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* @addtogroup fc7xxx_driver_dma
* @{
*/
/**
* @brief DMA transfer complete callback function prototype
*
*/
typedef void (*DMA_TransferCompleteCallbackType)(void);
/**
* @brief DMA transfer error callback function prototype
*
*/
typedef void (*DMA_TransferErrorCallbackType)(void);
/**
* @brief Available DMA Instances
*
*/
typedef enum
{
DMA_INSTANCE_0 = 0U,
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_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 = (int32)0x1U,
DMA_CIRCULAR_BUFFER_SIZE_2B = (int32)0x2U,
DMA_CIRCULAR_BUFFER_SIZE_4B = (int32)0x4U,
DMA_CIRCULAR_BUFFER_SIZE_8B = (int32)0x8U,
DMA_CIRCULAR_BUFFER_SIZE_16B = (int32)0x10U,
DMA_CIRCULAR_BUFFER_SIZE_32B = (int32)0x20U,
DMA_CIRCULAR_BUFFER_SIZE_64B = (int32)0x40U,
DMA_CIRCULAR_BUFFER_SIZE_128B = (int32)0x80U,
DMA_CIRCULAR_BUFFER_SIZE_256B = (int32)0x100U,
DMA_CIRCULAR_BUFFER_SIZE_512B = (int32)0x200U,
DMA_CIRCULAR_BUFFER_SIZE_1KB = (int32)0x400U,
DMA_CIRCULAR_BUFFER_SIZE_2KB = (int32)0x800U,
DMA_CIRCULAR_BUFFER_SIZE_4KB = (int32)0x1000U,
DMA_CIRCULAR_BUFFER_SIZE_8KB = (int32)0x2000U,
DMA_CIRCULAR_BUFFER_SIZE_16KB = (int32)0x4000U,
DMA_CIRCULAR_BUFFER_SIZE_32KB = (int32)0x8000U,
DMA_CIRCULAR_BUFFER_SIZE_64KB = (int32)0x10000U,
DMA_CIRCULAR_BUFFER_SIZE_128KB = (int32)0x20000U,
DMA_CIRCULAR_BUFFER_SIZE_256KB = (int32)0x40000U,
DMA_CIRCULAR_BUFFER_SIZE_512KB = (int32)0x80000U,
DMA_CIRCULAR_BUFFER_SIZE_1MB = (int32)0x100000U,
DMA_CIRCULAR_BUFFER_SIZE_2MB = (int32)0x200000U,
DMA_CIRCULAR_BUFFER_SIZE_4MB = (int32)0x400000U,
DMA_CIRCULAR_BUFFER_SIZE_8MB = (int32)0x800000U,
DMA_CIRCULAR_BUFFER_SIZE_16MB = (int32)0x1000000U,
DMA_CIRCULAR_BUFFER_SIZE_32MB = (int32)0x2000000U,
DMA_CIRCULAR_BUFFER_SIZE_64MB = (int32)0x4000000U,
DMA_CIRCULAR_BUFFER_SIZE_128MB = (int32)0x8000000U,
DMA_CIRCULAR_BUFFER_SIZE_256MB = (int32)0x10000000U,
DMA_CIRCULAR_BUFFER_SIZE_512MB = (int32)0x20000000U,
DMA_CIRCULAR_BUFFER_SIZE_1GB = (int32)0x40000000U,
DMA_CIRCULAR_BUFFER_SIZE_2GB = (int32)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;
/**
* @brief The configuration parameters of the DMA engine
*
*/
typedef struct
{
DMA_ArbitrationAlgorithmType eArbitrationAlgorithm; /*!< Channel Arbitration Algorithm */
bool bHaltOnError; /*!< Whether DMA halts when error occured */
} DMA_InitType;
/**
* @brief The interrupt configurations of the DMA channel
*
*/
typedef struct
{
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_InterruptCfgType;
/**
* @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 */
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 */
} DMA_ChannelCfgType;
/**
* @brief The parameters to configure the DMA channel as a circular buffer engine
*
*/
typedef struct
{
bool bCircularBufferEn; /*!< enable the DMA channel as a circular buffer engine */
DMA_CircularBufferRoleType eBufferRole; /*!< the source or the destination address is a circular buffer */
DMA_CircularBufferSizeType eBufferSize; /*!< the circular buffer size */
} 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 pInitCfg the configuration of the DMA instance
*/
void DMA_Init(const DMA_InstanceType eDma_Instance, const DMA_InitType *const pInitCfg);
/**
* @brief De-initialize the DMA instance
*
* Disable the DMA and restore its configure values to default
*
*/
void DMA_DeInit(const DMA_InstanceType eDma_Instance);
/**
* @brief Initialize the DMA channel
*
* @param u8Channel 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(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel, const DMA_ChannelCfgType *const pChnCfg);
/**
* @brief De-initialize the DMA channel
*
* @param u8Channel the DMA channel to de-initialize
*/
void DMA_DeinitChannel(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel);
/**
* @brief Initialize the DMA channel interrupt
*
* @param u8Channel the DMA channel to use
* @param pInterruptCfg the interrupt configuration of the DMA channel
*/
void DMA_InitChannelInterrupt(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel, const DMA_InterruptCfgType *const pInterruptCfg);
/**
* @brief Config the DMA channel chained transfer
*
* @param u8Channel the DMA channel to use
* @param pChainTransferCfg the parameters of the chained channel
*/
void DMA_ConfigChainedTransfer(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel,
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 u8Channel 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(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel,
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 u8Channel the DMA channel to start
*/
void DMA_StartChannel(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel);
/**
* @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 u8Channel the DMA channel to stop
*/
void DMA_StopChannel(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel);
/**
* @brief Cancel the ongoing DMA transfer
*
* @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(const DMA_InstanceType eDma_Instance, bool bGenerateErr);
/**
* @brief Get the request source of the selected channel
*
* @param u8Channel the DMA channel to get the request source
* @return DMA_RequestSourceType the request source of the selected channel
*/
DMA_RequestSourceType DMA_GetChannelRequestSrc(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel);
/**
* @brief Get the status of the DMA engine
*
* @return DMA_RunningStatusType the status of the DMA engine
*/
DMA_RunningStatusType DMA_GetStatus(const DMA_InstanceType eDma_Instance);
/**
* @brief Get the status of the DMA channel
*
* @param u8Channel the DMA channel to get the status
* @return DMA_RunningStatusType the status of the DMA channel
*/
DMA_RunningStatusType DMA_GetChannelStatus(const DMA_InstanceType eDma_Instance, const DMA_ChannelType eChannel);
/** @}*/ /* fc7xxx_driver_dma */
#if defined(__cplusplus)
}
#endif
#endif