366 lines
14 KiB
C
Executable File
366 lines
14 KiB
C
Executable File
/**
|
|
* @file hal_dma.h
|
|
* @author XRADIO IOT WLAN Team
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. 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.
|
|
*/
|
|
|
|
#ifndef _DRIVER_CHIP_HAL_DMA_H_
|
|
#define _DRIVER_CHIP_HAL_DMA_H_
|
|
|
|
#include "driver/chip/hal_def.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Options of supporting DMA half transfer complete IRQ */
|
|
#ifndef CONFIG_BOOTLOADER
|
|
#define HAL_DMA_OPT_TRANSFER_HALF_IRQ 1
|
|
#else
|
|
#define HAL_DMA_OPT_TRANSFER_HALF_IRQ 0
|
|
#endif
|
|
|
|
/**
|
|
* @brief DMA channel definition
|
|
*/
|
|
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_NUM = 8U,
|
|
DMA_CHANNEL_INVALID = 0xFFU
|
|
} DMA_Channel;
|
|
|
|
/**
|
|
* @brief DMA channel register block structure
|
|
*/
|
|
typedef struct {
|
|
__IO uint32_t CTRL; /* offset: 0x00, DMA channel configuration register */
|
|
__IO uint32_t SRC_ADDR; /* offset: 0x04, DMA channel source address register */
|
|
__IO uint32_t DST_ADDR; /* offset: 0x08, DMA channel destination address register */
|
|
/* NOTE: BYTE_CNT read is 0 before DMA start when set DMA_BYTE_CNT_MODE is 1. */
|
|
__IO uint32_t BYTE_CNT; /* offset: 0x0C, DMA channel byte counter register */
|
|
uint32_t RESERVED0[4];
|
|
} DMA_CHANNEL_T;
|
|
|
|
/**
|
|
* @brief DMA register block structure
|
|
*/
|
|
typedef struct {
|
|
__IO uint32_t IRQ_EN; /* offset: 0x00, DMA IRQ enable register */
|
|
__IO uint32_t IRQ_STATUS; /* offset: 0x04, DMA IRQ status register */
|
|
__IO uint32_t CONFIG; /* offset: 0x08, DMA Auto_Clock_Gating, Priority config register */
|
|
uint32_t RESERVED0[61];
|
|
DMA_CHANNEL_T CHANNEL[DMA_CHANNEL_NUM]; /* offset: 0x100, DMA channels register blocks */
|
|
} DMA_T;
|
|
|
|
#define DMA ((DMA_T *)DMA_BASE) /* address: 0x40001000 */
|
|
|
|
/*
|
|
* Bit field definition of
|
|
* - DMA->IRQ_EN
|
|
* - DMA->IRQ_STATUS
|
|
*/
|
|
#define DMA_IRQ_TYPE_VMASK 0x3U
|
|
typedef enum {
|
|
DMA_IRQ_TYPE_NONE = 0,
|
|
#if HAL_DMA_OPT_TRANSFER_HALF_IRQ
|
|
DMA_IRQ_TYPE_HALF = HAL_BIT(0),
|
|
#endif
|
|
DMA_IRQ_TYPE_END = HAL_BIT(1),
|
|
#if HAL_DMA_OPT_TRANSFER_HALF_IRQ
|
|
DMA_IRQ_TYPE_BOTH = HAL_BIT(0) | HAL_BIT(1),
|
|
#endif
|
|
} DMA_IRQType;
|
|
|
|
/*
|
|
* Bit field definition of DMA->CONFIG
|
|
*/
|
|
#define DMA_AUTO_CLK_GAT_BIT HAL_BIT(16) /* R/W */
|
|
|
|
/*
|
|
* Bit field definition of DMA->CHANNEL[x].CTRL
|
|
*/
|
|
#define DMA_START_BIT HAL_BIT(31) /* R/W */
|
|
#define DMA_BUSY_BIT HAL_BIT(30) /* R */
|
|
|
|
#define DMA_WORK_MODE_SHIFT 29 /* R/W */
|
|
#define DMA_WORK_MODE_VMASK 0x1U
|
|
typedef enum {
|
|
DMA_WORK_MODE_SINGLE = 0U, /* one-shot DMA transfer */
|
|
DMA_WORK_MODE_CIRCULAR = 1U /* repeat DMA transfer */
|
|
} DMA_WorkMode;
|
|
|
|
#define DMA_WAIT_CYCLE_SHIFT 26 /* R/W */
|
|
#define DMA_WAIT_CYCLE_VMASK 0x7U
|
|
typedef enum {
|
|
DMA_WAIT_CYCLE_1 = 0U,
|
|
DMA_WAIT_CYCLE_2 = 1U,
|
|
DMA_WAIT_CYCLE_4 = 2U,
|
|
DMA_WAIT_CYCLE_8 = 3U,
|
|
DMA_WAIT_CYCLE_16 = 4U,
|
|
DMA_WAIT_CYCLE_32 = 5U,
|
|
DMA_WAIT_CYCLE_64 = 6U,
|
|
DMA_WAIT_CYCLE_128 = 7U
|
|
} DMA_WaitCycle; /* waiting cycles between two burst transaction */
|
|
|
|
#define DMA_DATA_WIDTH_VMASK 0x3U
|
|
typedef enum {
|
|
DMA_DATA_WIDTH_8BIT = 0U,
|
|
DMA_DATA_WIDTH_16BIT = 1U,
|
|
DMA_DATA_WIDTH_32BIT = 2U
|
|
} DMA_DataWidth;
|
|
|
|
#define DMA_BURST_LEN_VMASK 0x1U
|
|
typedef enum {
|
|
DMA_BURST_LEN_1 = 0U,
|
|
DMA_BURST_LEN_4 = 1U
|
|
} DMA_BurstLen;
|
|
|
|
#define DMA_ADDR_MODE_VMASK 0x1U
|
|
typedef enum {
|
|
DMA_ADDR_MODE_INC = 0U, /* address is increased when DMA transferring */
|
|
DMA_ADDR_MODE_FIXED = 1U /* address is not changed when DMA transferring */
|
|
} DMA_AddrMode;
|
|
|
|
#define DMA_PERIPH_VMASK 0x1F
|
|
typedef enum {
|
|
DMA_PERIPH_SRAM = 0U,
|
|
DMA_PERIPH_SPI0 = 1U,
|
|
#if (CONFIG_CHIP_ARCH_VER == 2)
|
|
DMA_PERIPH_SPI1 = 2U,
|
|
#endif
|
|
DMA_PERIPH_UART0 = 3U,
|
|
DMA_PERIPH_UART1 = 4U,
|
|
DMA_PERIPH_CE = 5U,
|
|
DMA_PERIPH_DAUDIO = 6U,
|
|
DMA_PERIPH_FLASHC = 7U,
|
|
#if (CONFIG_CHIP_ARCH_VER == 2)
|
|
DMA_PERIPH_DMIC = 8U,
|
|
#endif
|
|
DMA_PERIPH_UART2 = 9U,
|
|
DMA_PERIPH_AUDIO_CODEC = 10U,
|
|
DMA_PERIPH_GPADC = 11U, /* for RX only */
|
|
#if (CONFIG_CHIP_ARCH_VER == 2)
|
|
DMA_PERIPH_PSRAMC = 12U,
|
|
#endif
|
|
} DMA_Periph;
|
|
|
|
#define DMA_BYTE_CNT_MODE_SHIFT 15 /* R/W */
|
|
#define DMA_BYTE_CNT_MODE_VMASK 0x1U
|
|
#define DMA_BYTE_CNT_MODE_MASK (DMA_BYTE_CNT_MODE_VMASK << DMA_BYTE_CNT_MODE_SHIFT)
|
|
typedef enum {
|
|
DMA_BYTE_CNT_MODE_NORMAL = 0U, /* DMA->CHANNEL[x].BYTE_CNT is the data length of the DAM transfer */
|
|
DMA_BYTE_CNT_MODE_REMAIN = 1U /* DMA->CHANNEL[x].BYTE_CNT is the length of the remaining data not transferred */
|
|
} DMA_ByteCntMode;
|
|
|
|
#define DMA_DST_DATA_WIDTH_SHIFT 24 /* R/W */
|
|
#define DMA_DST_BURST_LEN_SHIFT 23 /* R/W */
|
|
#define DMA_DST_ADDR_MODE_SHIFT 21 /* R/W */
|
|
#define DMA_DST_PERIPH_SHIFT 16 /* R/W */
|
|
#define DMA_SRC_DATA_WIDTH_SHIFT 8 /* R/W */
|
|
#define DMA_SRC_BURST_LEN_SHIFT 7 /* R/W */
|
|
#define DMA_SRC_ADDR_MODE_SHIFT 5 /* R/W */
|
|
#define DMA_SRC_PERIPH_SHIFT 0
|
|
|
|
/* DMA->CHANNEL[x].SRC_ADDR */
|
|
|
|
/* DMA->CHANNEL[x].DST_ADDR */
|
|
|
|
/* DMA->CHANNEL[x].BYTE_CNT */
|
|
#define DMA_BYTE_CNT_VMASK 0x3FFFF
|
|
|
|
/* Maximum data length of one DMA transfer */
|
|
#define DMA_DATA_MAX_LEN (128 * 1024U)
|
|
|
|
/******************************************************************************/
|
|
|
|
/** @brief Type define of DMA IRQ callback function */
|
|
typedef void (*DMA_IRQCallback)(void *arg);
|
|
|
|
/**
|
|
* @brief DMA channel initialization parameters
|
|
*/
|
|
typedef struct {
|
|
uint32_t cfg; /* created by HAL_DMA_MakeInitCfg() */
|
|
|
|
DMA_IRQType irqType; /* DMA IRQ type to be enabled */
|
|
DMA_IRQCallback endCallback; /* DMA transfer complete callback fucntion */
|
|
void *endArg; /* argument of DMA transfer complete callback fucntion */
|
|
#if HAL_DMA_OPT_TRANSFER_HALF_IRQ
|
|
DMA_IRQCallback halfCallback; /* DMA half transfer complete callback fucntion */
|
|
void *halfArg; /* argument of DMA half transfer complete callback fucntion */
|
|
#endif
|
|
} DMA_ChannelInitParam;
|
|
|
|
/**
|
|
* @brief Make configuration value for DMA_ChannelInitParam::cfg
|
|
* @param[in] workMode DMA transfer working mode
|
|
* @param[in] waitCycle Waiting cycles between two DMA burst transaction
|
|
* @param[in] byteCntMode DMA byte count mode
|
|
* @arg DMA_BYTE_CNT_MODE_NORMAL In normal mode, DMA->CHANNEL[x].BYTE_CNT is
|
|
* not changed in the whole DMA transfer, and
|
|
* its value is the data length of the DAM
|
|
* transfer.
|
|
* @arg DMA_BYTE_CNT_MODE_REMAIN In remaining mode, DMA->CHANNEL[x].BYTE_CNT
|
|
* is decreased when DMA transferring, and its
|
|
* value is the length of the remaining data
|
|
* not transferred.
|
|
* @param[in] dstDataWidth Destination DMA transaction data width
|
|
* @param[in] dstBurstLen Destination DMA transaction burst length
|
|
* @param[in] dstAddrMode Destination DMA address mode
|
|
* @param[in] dstPeriph Destination DMA peripheral type
|
|
* @param[in] srcDataWidth Source DMA transaction data width
|
|
* @param[in] srcBurstLen Source DMA transaction burst length
|
|
* @param[in] srcAddrMode Source DMA address mode
|
|
* @param[in] srcPeriph Source DMA peripheral type
|
|
* @return configuration value for DMA_ChannelInitParam::cfg
|
|
*
|
|
* @note
|
|
* - A DMA transaction is not interruptible
|
|
* - A DMA transaction data length = data width * burst length
|
|
*/
|
|
__STATIC_INLINE uint32_t HAL_DMA_MakeChannelInitCfg(DMA_WorkMode workMode,
|
|
DMA_WaitCycle waitCycle,
|
|
DMA_ByteCntMode byteCntMode,
|
|
DMA_DataWidth dstDataWidth,
|
|
DMA_BurstLen dstBurstLen,
|
|
DMA_AddrMode dstAddrMode,
|
|
DMA_Periph dstPeriph,
|
|
DMA_DataWidth srcDataWidth,
|
|
DMA_BurstLen srcBurstLen,
|
|
DMA_AddrMode srcAddrMode,
|
|
DMA_Periph srcPeriph)
|
|
{
|
|
return ((((uint32_t)workMode & DMA_WORK_MODE_VMASK) << DMA_WORK_MODE_SHIFT) |
|
|
(((uint32_t)waitCycle & DMA_WAIT_CYCLE_VMASK) << DMA_WAIT_CYCLE_SHIFT) |
|
|
(((uint32_t)byteCntMode & DMA_BYTE_CNT_MODE_VMASK) << DMA_BYTE_CNT_MODE_SHIFT) |
|
|
(((uint32_t)dstDataWidth & DMA_DATA_WIDTH_VMASK) << DMA_DST_DATA_WIDTH_SHIFT) |
|
|
(((uint32_t)dstBurstLen & DMA_BURST_LEN_VMASK) << DMA_DST_BURST_LEN_SHIFT) |
|
|
(((uint32_t)dstAddrMode & DMA_ADDR_MODE_VMASK) << DMA_DST_ADDR_MODE_SHIFT) |
|
|
(((uint32_t)dstPeriph & DMA_PERIPH_VMASK) << DMA_DST_PERIPH_SHIFT) |
|
|
(((uint32_t)srcDataWidth & DMA_DATA_WIDTH_VMASK) << DMA_SRC_DATA_WIDTH_SHIFT) |
|
|
(((uint32_t)srcBurstLen & DMA_BURST_LEN_VMASK) << DMA_SRC_BURST_LEN_SHIFT) |
|
|
(((uint32_t)srcAddrMode & DMA_ADDR_MODE_VMASK) << DMA_SRC_ADDR_MODE_SHIFT) |
|
|
(((uint32_t)srcPeriph & DMA_PERIPH_VMASK) << DMA_SRC_PERIPH_SHIFT));
|
|
}
|
|
|
|
/**
|
|
* @brief Request an available DMA channel
|
|
* @note Before using DMA, an available DMA channel MUST be requested first
|
|
* @retval DMA_Channel, DMA_CHANNEL_INVALID on failed
|
|
*/
|
|
DMA_Channel HAL_DMA_Request(void);
|
|
|
|
/**
|
|
* @brief Request the specified DMA channel if it is available
|
|
* @param[in] chan the specified DMA channel
|
|
* @retval DMA_Channel, DMA_CHANNEL_INVALID on failed
|
|
*/
|
|
DMA_Channel HAL_DMA_RequestSpecified(DMA_Channel chan);
|
|
|
|
/**
|
|
* @brief Release the DMA channel
|
|
* @param[in] chan DMA channel to be released
|
|
* @return None
|
|
*/
|
|
void HAL_DMA_Release(DMA_Channel chan);
|
|
|
|
/**
|
|
* @brief Initialize the DMA channel according to the specified parameters
|
|
* @param[in] chan DMA channel
|
|
* @param[in] param Pointer to DMA_ChannelInitParam structure
|
|
* @retval HAL_Status, HAL_OK on success
|
|
*/
|
|
HAL_Status HAL_DMA_Init(DMA_Channel chan, const DMA_ChannelInitParam *param);
|
|
|
|
/**
|
|
* @brief DeInitialize the specified DMA channel
|
|
* @param[in] chan DMA channel
|
|
* @retval HAL_Status, HAL_OK on success
|
|
*/
|
|
HAL_Status HAL_DMA_DeInit(DMA_Channel chan);
|
|
|
|
/**
|
|
* @brief Start the DMA transfer of the specified DMA channel
|
|
* @param[in] chan DMA channel
|
|
* @param[in] srcAddr The source address of DMA transfer
|
|
* @param[in] dstAddr The destination address of DMA transfer
|
|
* @param[in] datalen The length of data to be transferred from source to destination
|
|
* @retval HAL_Status, HAL_OK on success
|
|
*
|
|
* @note The source/destination address MUST be aligned to the
|
|
* source/destination DMA transaction data width defined by DMA_DataWidth.
|
|
* @note The date length MUST not be more than DMA_DATA_MAX_LEN.
|
|
* @note The srcAddr and dstAddr not spupport reentrant
|
|
Before dma start, clean src address part of dcache to sram;
|
|
After dma end, flush dest address part of dcache.
|
|
*/
|
|
HAL_Status HAL_DMA_Start(DMA_Channel chan, uint32_t srcAddr, uint32_t dstAddr, uint32_t datalen);
|
|
|
|
/**
|
|
* @brief Stop the DMA transfer of the specified DMA channel
|
|
* @param[in] chan DMA channel
|
|
* @retval HAL_Status, HAL_OK on success
|
|
*/
|
|
HAL_Status HAL_DMA_Stop(DMA_Channel chan);
|
|
|
|
/**
|
|
* @brief Check the busy status of the specified DMA channel
|
|
* @param[in] chan DMA channel
|
|
* @return 1 on busy, 0 on idle
|
|
*/
|
|
int HAL_DMA_IsBusy(DMA_Channel chan);
|
|
|
|
/**
|
|
* @brief Get the byte counter of the specified DMA channel
|
|
* @param[in] chan DMA channel
|
|
* @return The byte counter of the specified DMA channel
|
|
* - If DMA byte count mode is DMA_BYTE_CNT_MODE_NORMAL, the return value
|
|
* is the data length set by HAL_DMA_Start().
|
|
* - If DMA byte count mode is DMA_BYTE_CNT_MODE_REMAIN, the return value
|
|
* is the length of the remaining data not transferred.
|
|
*/
|
|
uint32_t HAL_DMA_GetByteCount(DMA_Channel chan);
|
|
|
|
uint32_t HAL_DMA_FlashSbus_Iscoexist(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _DRIVER_CHIP_HAL_DMA_H_ */
|