⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hw_hdmactrl.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
字号:
/****************************************************************
 Copyright (C) 2007 RockChip All Rights Reserved.

File: HDMACtrl.c
Desc: HDMA control
Author:LingZJ
Date: 2007/06/30
note:
$Log: HW_HDMACtrl.c,v $
Revision 1.2  2008/06/19 04:43:31  Administrator
代码整理!

Revision 1.1.1.1  2008/05/07 04:15:08  Administrator
no message

Revision 1.1.1.1  2008/03/06 13:29:05  Lingzhaojun
no message


Revision 1.6  2007/11/10 04:24:48  Huangxinyu
调试修改

Revision 1.5  2007/10/24 07:21:01  Hanjiang
no message

Revision 1.4  2007/10/23 08:23:14  Huangxinyu
调试后修改bug

Revision 1.3  2007/10/15 09:07:59  Huangxinyu
根据RK27提交修改driver

Revision 1.2  2007/10/08 02:38:43  Lingzhaojun
添加版本自动注释脚本

Revision 1.1.1.1  2007/09/27 09:06:00  cvsadmin
no message

Revision 1.4  2007/09/24 04:00:00  Lingzhaojun
提交驱动、FM、打包目录分离相关代码

 1.2007-06-29,LingZJ,创建文件
 2.2007-06-30,LingZJ,整理程序和变量,常量。
 3.2007-08-16, lzy 整理程序和变量
 4.2008-8-30, lzy 整理程序和变量
*****************************************************************/
#include "hw_include.h"
#include "HW_HDMACtrl.h"
#include "HW_I2sCtrl.h"

static DMACallBack DmaCallBack[2] = {NULL, NULL};

/*---------------------------------------------------------
Name  :  DMAIntrHandler
Desc  :  HDMA中断服务程序
Params:
Author:  LingZJ
Date  :  070630
            lzy  modified @ 8-30
-----------------------------------------------------------*/
static void HDMA_isr(void)
{
    unsigned int IntState, channel;
    DMACallBack callback;

    IntState = HW_HdmaGetIntrState();

    WriteReg32(RegHDMA_ISR, ReadReg32(RegHDMA_ISR)&(~(0x3f)));

    for (channel = 0; channel < 0x2; channel++)
    {
        if (IntState&((0x15) << channel))
        {
            if (DmaCallBack[channel])
            {
                callback = DmaCallBack[channel];
                DmaCallBack[channel] = NULL;
                callback();
            }
        }
    }
}

/*---------------------------------------------------------
Name  :  DmaTransmit
Desc  :    启用DMA传送
Params:  SrcAddr:源地址
               DestinAddr:  目的地址,长度
   Mode :传送模式
   CallBack:传输完成回调函数
Return:  状态
Author:  Lzj create, lzy modify
Date  :   070830
Note:     count 为传输的数据大小,对应传输宽度
             burst 为总线burst 的大小,最好和count 为倍数关系
             驱动中自动对burst 进行优化,16倍数的传输效率最高
             最大传输数量为64K * 数据宽度
-----------------------------------------------------------*/
int DmaTransmit(HDMA_Channel_t channel, UINT32 SrcAddr, UINT32 DestinAddr, UINT32 Count, UINT32 Mode, DMACallBack CallBack)
{
    unsigned int mode = 0;    /*通道*/

    if (HW_HdmaGetReadyState() == 0x01)
        return DmaBusy;

    if (HW_HdmaGetDMAState(channel))
        return DmaBusy;

//Set Address and size
    HW_HdmaSourceAddr(channel, TransVAtoPA(SrcAddr));
    HW_HdmaDestinatAddr(channel, TransVAtoPA(DestinAddr));
// HDMA  terminal count is to zero, so must minus 1;
    HW_HdmaSetCount(channel, Count - 1);

    if (CallBack)
    {
        mode |= DmaMode_Interrupt;
        DmaCallBack[channel] = CallBack;
        Intr_Enable(INTC_HDMA);
    }

    //start the DMA transfer
    if (Mode&DmaMode_Hard)
    {
// I2s dam transmit is always burst8
        mode |= Mode & (DmaMode_RequestMask
                        | DmaMode_SrmodeMask
                        | DmaMode_DrmodeMask
                        | DmaMode_WidthMask
                        | DmaMode_HWMask);
        HW_HdmaSliceCount(channel, 7);
        HW_HdmaPageNumber(channel, 1);
        mode |= DmaMode_Slice | DMA_CHN_EN | DmaMode_Hard | DmaMode_Burst8;
        WriteReg32(RegHDMA_CON(channel), mode);
    }
    else
    {
        if ((Count % 16) == 0)
            mode |= DmaMode_Burst16;
        else if ((Count % 8) == 0)
            mode |= DmaMode_Burst8;
        else if ((Count % 4) == 0)
            mode |= DmaMode_Burst4;
        else
            mode |= DmaMode_BurstSignle;

        mode |= Mode & (DmaMode_SrmodeMask
                        | DmaMode_DrmodeMask
                        | DmaMode_WidthMask
                        | DmaMode_HWMask);
        mode |= DmaMode_SoftwareStar | DMA_CHN_EN;
        WriteReg32(RegHDMA_CON(channel), mode);
    }

    return channel;

}


/**************************************************************************
* 函数描述:  HDMA  读通道状态
* 入口参数:  无
* 出口参数:  无
* 返回值:        无
* 注释:             采用查询方式使用DMA  时通过此接口判断传输状态
***************************************************************************/
int HDMA_GetStatus(HDMA_Channel_t channel)
{
    if (ReadReg32(RegHDMA_DSR)&(0x01 << channel))
        return DmaBusy;
    else
        return DmaSuccess;
}

/**************************************************************************
* 函数描述:  HDMA 开机初始化程序
* 入口参数:  无
* 出口参数:  无
* 返回值:        无
* 注释:             启用HDMA 时调用
***************************************************************************/
void HDMA_PowerOnInit(void)
{
    int temp, channel;

    Scu_ClockEnable(HDMA_CLOCK);

    for (channel = 0; channel < HDMA_chnmax; channel++)
    {
        // clear page count number and disable page function
        HW_HdmaClearCPNCNTD(channel);
        // cancel software DMA operation
        temp = ReadReg32(RegHDMA_CON(channel));
        temp = (temp & ~HDMAMode_SwcMask) | HDMAMode_SoftStop;
        WriteReg32(RegHDMA_CON(channel), temp);
        // clear dma config register
        WriteReg32(RegHDMA_CON(channel), 0x00);  //ReadReg32(RegA2A_CON(0))|A2AMode_SoftStop);
    }
    // clear DMA interrupt
    WriteReg32(RegHDMA_ISR, 0x00);

    Intr_RegISR(INTC_HDMA, HDMA_isr);
}

/**************************************************************************
* 函数描述:  HDMA 反初始化函数
* 入口参数:  无
* 出口参数:  无
* 返回值:        无
* 注释:             关闭HDMA 时调用
***************************************************************************/
void HDMA_DeInit(void)
{
    WriteReg32(RegHDMA_ISR, 0x00);

    Intr_RegISR(INTC_HDMA, NULL);
    Intr_Disable(INTC_HDMA);
    Scu_ClockDisable(HDMA_CLOCK);
}

/**************************************************************************
* 函数描述:  HDMA 反初始化函数
* 入口参数:  无
* 出口参数:  无
* 返回值:        无
* 注释:             关闭HDMA 时调用
***************************************************************************/
void HDMA_Stop(HDMA_Channel_t channel)
{
    int temp;
    channel = 0;
    HW_HdmaClearCPNCNTD(channel);
    // cancel software DMA operation
    temp = ReadReg32(RegHDMA_CON(channel));
    temp = (temp & ~HDMAMode_SwcMask) | HDMAMode_SoftStop;
    WriteReg32(RegHDMA_CON(channel), temp);
    // clear dma config register
    WriteReg32(RegHDMA_CON(channel), 0x00);  //ReadReg32(RegA2A_CON(0))|A2AMode_SoftStop);

    WriteReg32(RegHDMA_ISR, 0x00);

//    Intr_RegISR(INTC_HDMA, NULL);
//    Intr_Disable(INTC_HDMA);
}

#if 0
/**************************************************************************
* 函数描述:  HDMA 反初始化函数
* 入口参数:  无
* 出口参数:  无
* 返回值:        无
* 注释:             关闭HDMA 时调用
***************************************************************************/
int DMA_AudioOut(UINT32 SrcAddr, UINT32 bufsize, UINT32 bufnumber, DMACallBack CallBack)
{
    unsigned int mode;
    unsigned int channel = 1;

    HW_HdmaDisable(channel);

    HW_HdmaSourceAddr(channel, TransVAtoPA(SrcAddr));
    HW_HdmaDestinatAddr(channel, TransVAtoPA(RegI2s_TXR));
// HDMA  terminal count is to zero, so must minus 1;
    HW_HdmaSetCount(channel, bufsize - 1);

    HW_HdmaClearCPNCNTD(channel);

    mode = DmaMode_Slice
           | DmaMode_Hard
           | DmaMode_width32Bit
           | DmaMode_DestFix
           | DmaMode_SourceInc
           | DmaMode_Request16
           | DmaMode_Burst16
           | DmaMode_Interrupt;
//
    WriteReg32(RegHDMA_CON(channel), mode);

// slice is half of I2S FIFO size, so there is fixed to 16
    HW_HdmaSliceCount(channel, 16);
    HW_HdmaPageNumber(channel, bufnumber);

// buffer size is byte count, so must *2
//    HW_HdmaSrcBufSize(channel, bufsize*bufnumber*2);

    DmaCallBack[channel] = CallBack;
    Intr_Enable(INTC_HDMA);

    mode |= DmaMode_Enable | DmaMode_HWEnable;
    WriteReg32(RegHDMA_CON(channel), mode);

    return TRUE;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -