#include "DMA.h"
#include <FU68xx_5_DMA.h>


//#define DMALENT 128

unsigned char xdata sg_ucUartDbgData[DMALENT] = {0xaa, 0xbb};
char                sg_cUartDataLen;
unsigned char       sg_ucUartDataSum;

void DMA0_XRAMToUART_Init(void)
{
    /* -----DMACFG2:DMACFG1: DMACFG0-->001  传输方向XRAMToUART----- */
    SetReg(DMA0_CR0, DMAEN | DMACFG2 | DMACFG1 | DMACFG0 | DMAIE, DMACFG0 );  // DMAIE和DMACFG0为1
    DMA0_LEN =  DMALENT;                                                                   // 设置传输长度为7，每传输7字节产生一次中断
    DMA0_BA  =  (uint16)GetAddr_UARTDBG();                                                              // 设置RAM中的首地址
    SetBit(DMA0_CR0, DMAEN);                                                         // 使能DMA1
}

/**
    获取缓存区的地址

    @return  缓存区地址
*/
unsigned char * GetAddr_UARTDBG(void)
{
    return &sg_ucUartDbgData;
}


/**
    配置DMA

    @param DMAx      DMA通道
    @param DMAPipe   DMA管道，可选参数如下
                        UART1_XDATA    UART1-->XDATA
                        XDATA_UART1    UART1<--XDATA
                        I2C_XDATA      I2C  -->XDATA
                        XDATA_I2C      I2C  <--XDATA
                        SPI_XDATA      SPI  -->XDATA
                        XDATA_SPI      SPI  <--XDATA
                        UART2_XDATA    UART2-->XDATA
                        XDATA_UART2    UART2<--XDATA
    @param DMAAddr   传输首地址，可取地址范围：0x0000~0x0317
    @param DMALen    数据包大小(1~64)
*/
void Conf_DMA(uint8 DMAx, uint8 DMAPipe, uint16 DMAAddr, uint8 DMALen)
{
    Wait_DMA(DMAx);                                                   // 等待DMAx传输结束
    ClrBit(*(&DMA0_CR0 + DMAx), DMAEN);                               // 禁止DMAx的传输
    SetReg(*(&DMA0_CR0 + DMAx), DMA_PIPE, DMAPipe);                   // 设置DMAx的传输管道
    *(&DMA0_LEN + DMAx) = DMALen - 1;                                 // 设置DMAx传输数量
    *(&DMA0_BA + DMAx) = DMAAddr & 0x07ff;                           // 设置DMAx传输首地址
}




void SetPipe_DMA0(eType_DMA_PIPE ePipe)
{
    bool bTmp = false;
    
    if (ReadBit(DMA0_CR0, DMAEN))
    {
        bTmp = true;
        
        while (ReadBit(DMA0_CR0, DMABSY));
        
        ClrBit(DMA0_CR0, DMAEN);
    }
    
    SetReg(DMA0_CR0, DMACFG2 | DMACFG1 | DMACFG0, ePipe);
    
    if (bTmp)
    {
        SetBit(DMA0_CR0, DMAEN);
    }
}

void SetPipe_DMA1(eType_DMA_PIPE ePipe)
{
    bool bTmp = false;
    
    if (ReadBit(DMA1_CR0, DMAEN))
    {
        bTmp = true;
        
        while (ReadBit(DMA1_CR0, DMABSY));
        
        ClrBit(DMA1_CR0, DMAEN);
    }
    
    SetReg(DMA1_CR0, DMACFG2 | DMACFG1 | DMACFG0, ePipe);
    
    if (bTmp)
    {
        SetBit(DMA1_CR0, DMAEN);
    }
}

void SetDataPackage_DMA0(unsigned short ulAddr, char cLen)
{
    bool bTmp = false;
    
    if (ReadBit(DMA0_CR0, DMAEN))
    {
        bTmp = true;
        
        while (ReadBit(DMA0_CR0, DMABSY));
        
        ClrBit(DMA0_CR0, DMAEN);
    }
    
    DMA0_LEN =  cLen;
    DMA0_BA  =  ulAddr;
    
    if (bTmp)
    {
        SetBit(DMA0_CR0, DMAEN);
    }
}

void SetDataPackage_DMA1(unsigned short ulAddr, char cLen)
{
    bool bTmp = false;
    
    if (ReadBit(DMA1_CR0, DMAEN))
    {
        bTmp = true;
        
        while (ReadBit(DMA1_CR0, DMABSY));
        
        ClrBit(DMA1_CR0, DMAEN);
    }
    
    DMA1_LEN = cLen;
    DMA1_BA  = ulAddr;
    
    if (bTmp)
    {
        SetBit(DMA1_CR0, DMAEN);
    }
}

void SetEndian_DMA(eType_DMA_Endian eEndian)
{
    bool bTmp = false, bTmp1;
    
    if (ReadBit(DMA0_CR0, DMAEN))
    {
        bTmp = true;
        
        while (ReadBit(DMA0_CR0, DMABSY));
        
        ClrBit(DMA0_CR0, DMAEN);
    }
    
    if (ReadBit(DMA1_CR0, DMAEN))
    {
        bTmp1 = true;
        
        while (ReadBit(DMA1_CR0, DMABSY));
        
        ClrBit(DMA1_CR0, DMAEN);
    }
    
    SetReg(DMA0_CR0, ENDIAN, eEndian);
    
    if (bTmp)
    {
        SetBit(DMA0_CR0, DMAEN);
    }
    
    if (bTmp1)
    {
        SetBit(DMA1_CR0, DMAEN);
    }
}

void SetIRQ_DMA(ebool eIRQ, eType_DMA_IRQ eIP)
{
    SetReg(DMA0_CR0, DMAIE, eIRQ ? DMAIE : 0);
    
    if (!EA)
    {
        EA = 1;
    }
    
    if (eIRQ)
    {
        SetReg(IP1, PDMA1 | PDMA0, eIP);
    }
}

void SetDbgMod_DMA(void)
{
    bool bTmp = false;
    
    if (ReadBit(DMA1_CR0, DMAEN))
    {
        bTmp = true;
        
        while (ReadBit(DMA1_CR0, DMABSY));
        
        ClrBit(DMA1_CR0, DMAEN);
    }
    
    SetBit(DMA1_CR0, DBGEN);
    SetBit(DMA1_CR0, ((eType_DMA_PIPE)DRAM_SPI));
    DMA1_LEN = 4;
    
    if (bTmp)
    {
        SetBit(DMA1_CR0, DMAEN);
    }
}

/**
    设置DMA1的DBG模式

    @param Addr   要DBG输出的地址
*/
uint16 xdata spidebug[4] = { 0 };
void Set_DBG_DMA(uint16 DMAAddr)
{
    //  SPI_Init();
    ClrBit(DMA1_CR0, DMAEN);                                // 禁止DMA1传输
    SetBit(DMA1_CR0, DBGEN | DRAM_SPI);                     // 设置DMA1使用DBG模式，XDATA发送数据到SPI
    
    if (!ReadBit(DMAAddr, 0x4000))
    {
        SetBit(DMA1_CR0, DBGSW);    //根据DMAAddr判断是否在XRAM区，如果是则开启DBGSW
    }
    
    DMA1_LEN = 7;                                           // 设置DMA1发送数量为8
    //      DMA1_BA = (uint16)spidebug & 0x07ff;
    DMA1_BA = DMAAddr & 0x07ff;                             // 设置DMA1发送首地址
    SetBit(*(&DMA0_CR0 + 1), DMAEN | DMABSY);
    //    Switch_DMA(1);                                       // 启动DMA1
}


void SetDbgData_DMA(unsigned short ulAddr)
{
    bool bTmp = false;
    
    if (ReadBit(DMA1_CR0, DMAEN))
    {
        bTmp = true;
        
        while (ReadBit(DMA1_CR0, DMABSY));
        
        ClrBit(DMA1_CR0, DMAEN);
    }
    
    if (ulAddr <= 0xfff)
    {
        ulAddr += 0x70000000;
    }
    
    DMA1_BA = ulAddr;
    
    if (bTmp)
    {
        SetBit(DMA1_CR0, DMAEN);
    }
}

void EnableRun_DMA0(void)
{
    SetBit(DMA0_CR0, DMAEN | DMABSY);
}

void EnableRun_DMA1(void)
{
    SetBit(DMA1_CR0, DMAEN | DMABSY);
}

bool GetStatus_DMA0(eType_DMA_Statu eStatu)
{
    return ReadBit(DMA0_CR0, eStatu);
}

bool GetStatus_DMA1(eType_DMA_Statu eStatu)
{
    return ReadBit(DMA1_CR0, eStatu);
}

