📄 lh79524_dma_driver.c
字号:
/***********************************************************************
* $Workfile: lh79524_dma_driver.c $
* $Revision: 1.0 $
* $Author: ZhangJ $
* $Date: Oct 20 2004 09:48:54 $
*
* Project: LH79520 DMA driver
*
* Description:
* This file contains driver support for the DMA module on the
* LH79520
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh79524/source/lh79524_dma_driver.c-arc $
*
* Rev 1.0 Oct 20 2004 09:48:54 ZhangJ
* Initial revision.
*
* Rev 1.0 Jul 07 2003 16:39:58 LiJ
* Initial revision.
*
* SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
* OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
* AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES,
* SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
*
* SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY
* FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A
* SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
* FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
*
* COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
*
***********************************************************************/
#include "lh79524_iocon.h"
#include "lh79524_rcpc.h"
#include "lh79524_dma_driver.h"
/***********************************************************************
* DMA driver private data
**********************************************************************/
/* DMA device configuration structure */
STATIC DMA_CFG_T dmacfg;
/* DMA external channel, 0 for DREQ0, 1 for DREQ1 */
INT_32 dma_ext_channel = 0;
/***********************************************************************
* DMA driver public functions
**********************************************************************/
/***********************************************************************
*
* Function: dma_open
*
* Purpose: Open the DMA controller
*
* Processing:
* If init is not FALSE, return 0x00000000 to the caller. Otherwise,
* return a pointer to the DMA config structure to the caller.
*
* Parameters:
* ipbase: DMA descriptor device address
* arg : Not used
*
* Outputs: None
*
* Returns: The pointer to a DMA config structure or 0
*
* Notes: None
*
**********************************************************************/
INT_32 dma_open(void *ipbase, INT_32 arg)
{
INT_32 status = 0;
if (dmacfg.init == FALSE)
{
/* Device is valid and not previously initialized */
dmacfg.init = TRUE;
/* Save and return address of peripheral block */
dmacfg.regptr = (DMAC_REGS_T *) ipbase;
/* Enable DMA clock in RCPC */
RCPC->ahbclkctrl &= ~RCPC_AHBCLKCTRL_DMA_DISABLE;
/* Default state of DMA is disabled */
dmacfg.regptr->stream0.ctrl = 0x0;
dmacfg.regptr->stream1.ctrl = 0x0;
dmacfg.regptr->stream2.ctrl = 0x0;
dmacfg.regptr->stream3.ctrl = 0x0;
/* Return pointer to DMA configuration structure */
status = (INT_32) &dmacfg;
}
return status;
}
/***********************************************************************
*
* Function: dma_close
*
* Purpose: Close the DMA controller
*
* Processing:
* If init is not TRUE, then return _ERROR to the caller as the
* device was not previously opened. Otherwise, check the status of
* the freeze and enable bits. If they are set, then return
* SMA_CANT_STOP to the caller as the device can no longer be
* stopped. Otherwise, disable the DMA, set init to
* FALSE, and return _NO_ERROR to the caller.
*
* Parameters:
* devid: Pointer to DMA config structure
*
* Outputs: None
*
* Returns: The status of the close operation
*
* Notes: None
*
**********************************************************************/
STATUS dma_close(INT_32 devid)
{
DMA_CFG_T *dmacfgptr = (DMA_CFG_T *) devid;
STATUS status = _ERROR;
if (dmacfgptr->init == TRUE)
{
status = _NO_ERROR;
dmacfgptr->init = FALSE;
/* Disable DMA controller */
dmacfg.regptr->stream0.ctrl = 0;
dmacfg.regptr->stream0.sourcelo = 0;
dmacfg.regptr->stream0.sourcehi = 0;
dmacfg.regptr->stream0.destlo = 0;
dmacfg.regptr->stream0.desthi = 0;
dmacfg.regptr->stream0.max = 0;
dmacfg.regptr->stream1.ctrl = 0;
dmacfg.regptr->stream1.sourcelo = 0;
dmacfg.regptr->stream1.sourcehi = 0;
dmacfg.regptr->stream1.destlo = 0;
dmacfg.regptr->stream1.desthi = 0;
dmacfg.regptr->stream1.max = 0;
dmacfg.regptr->stream2.ctrl = 0;
dmacfg.regptr->stream2.sourcelo = 0;
dmacfg.regptr->stream2.sourcehi = 0;
dmacfg.regptr->stream2.destlo = 0;
dmacfg.regptr->stream2.desthi = 0;
dmacfg.regptr->stream2.max = 0;
dmacfg.regptr->stream3.ctrl = 0;
dmacfg.regptr->stream3.sourcelo = 0;
dmacfg.regptr->stream3.sourcehi = 0;
dmacfg.regptr->stream3.destlo = 0;
dmacfg.regptr->stream3.desthi = 0;
dmacfg.regptr->stream3.max = 0;
dmacfg.regptr->mask = 0;
dmacfg.regptr->clear = DMAC_ALL_FLAGS;
}
return status;
}
/***********************************************************************
*
* Function: dma_ioctl
*
* Purpose: DMA configuration block
*
* Processing:
* This function is a large case block. Based on the passed function
* and option values, set or get the appropriate DMA
* parameter.
*
* Parameters:
* devid: Pointer to DMA config structure
* cmd: ioctl command
* arg: ioctl argument
*
* Outputs: None
*
* Returns: The status of the ioctl operation
*
* Notes: DMA status -
* DMAC_EOT0
* DMAC_EOT1
* DMAC_EOT2
* DMAC_EOT3
* DMAC_ERROR0
* DMAC_ERROR1
* DMAC_ERROR2
* DMAC_ERROR3
* DMAC_ACTIVE0
* DMAC_ACTIVE1
* DMAC_ACTIVE2
* DMAC_ACTIVE3
*
*
**********************************************************************/
STATUS dma_ioctl(INT_32 devid,
INT_32 cmd,
INT_32 arg)
{
DMAC_REGS_T *dma;
DMA_CFG_T *dmacfgptr = (DMA_CFG_T *) devid;
STATUS status = _ERROR;
INT_32 temp;
if (dmacfgptr->init == TRUE)
{
status = _NO_ERROR;
dma = dmacfgptr->regptr;
switch (cmd)
{
/* Clear DMA status, used in DMA interrupt status clear */
case DMA_CLEAR_STATUS:
/* arg is the status mask must be one of followings -
DMAC_EOT0
DMAC_EOT1
DMAC_EOT2
DMAC_EOT3
DMAC_ERROR0
DMAC_ERROR1
DMAC_ERROR2
DMAC_ERROR3
DMAC_ALL_FLAGS
*/
DMAC->clear = arg;
break;
/* Enable the interrupt for DMA */
case DMA_ENABLE_INT:
/* arg is the int mask must be one of followings -
DMAC_EOT0
DMAC_EOT1
DMAC_EOT2
DMAC_EOT3
DMAC_ERROR0
DMAC_ERROR1
DMAC_ERROR2
DMAC_ERROR3
DMAC_ALL_FLAGS
*/
DMAC->mask |= arg;
break;
case DMA_DISABLE_INT:
/* arg is the int mask must be one of followings -
DMAC_EOT0
DMAC_EOT1
DMAC_EOT2
DMAC_EOT3
DMAC_ERROR0
DMAC_ERROR1
DMAC_ERROR2
DMAC_ERROR3
DMAC_ALL_FLAGS
*/
DMAC->mask &= ~arg;
break;
/* DMA memory to memory set source address, arg is address */
case DMA_SET_M2M_SRC:
DMAC->stream3.sourcelo = arg & _BITMASK(16);
DMAC->stream3.sourcehi = (arg >> 16) & _BITMASK(16);
break;
/* DMA memory to memory set destination address, arg is
address */
case DMA_SET_M2M_DEST:
DMAC->stream3.destlo = arg & _BITMASK(16);
DMAC->stream3.desthi = (arg >> 16) & _BITMASK(16);
break;
/* The number of bytes to transfer; nbytes / src_width
must be less than 65536 and greater than 0 or this
function will return failure. DMA_SET_M2M_SRC_WIDTH must
be executed before this function call */
case DMA_SET_M2M_BYTES:
temp = DMAC->stream3.ctrl;
temp &= (_BIT(3)|_BIT(4));
if (temp == DMAC_CTRL_SOSIZE_1BYTE)
temp = 1;
else if (temp == DMAC_CTRL_SOSIZE_2BYTE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -