|  | 
| 复制代码/****************************************************************************/
/*                                                                          */
/*              通用异步串口2测试(EDMA3 方式)                             */
/*                                                                          */
/*              2014年10月24日                                              */
/*                                                                          */
/****************************************************************************/
// 注意:DSP ports, Shared RAM, UART0, EDMA, SPI0, MMC/SDs,
//       VPIF, LCDC, SATA, uPP, DDR2/mDDR (bus ports), USB2.0, HPI, PRU
//       这些外设使用的时钟来源为 PLL0_SYSCLK2 默认频率为 CPU 频率的二分之一
//       但是,ECAPs, UART1/2, Timer64P2/3, eHRPWMs,McBSPs, McASP0, SPI1
//       这些外设的时钟来源可以在 PLL0_SYSCLK2 和 PLL1_SYSCLK2 中选择
//       通过修改 System Configuration (SYSCFG) Module
//       寄存器 Chip Configuration 3 Register (CFGCHIP3) 第四位 ASYNC3_CLKSRC
//       配置时钟来源
//       (默认值) 0 来源于 PLL0_SYSCLK2
//                  1 来源于 PLL1_SYSCLK2
//       如果不是为了降低功耗,不建议修改这个值,它会影响所有相关外设的时钟频率
// 修改为连续收发模式 2015/11/19
#include "TL6748.h"                 // 创龙 DSP6748 开发板相关声明
#include "hw_types.h"               // 宏命令
#include "hw_syscfg0_C6748.h"       // 系统配置模块寄存器
#include "soc_C6748.h"              // DSP C6748 外设寄存器
#include "psc.h"                    // 电源与睡眠控制宏及设备抽象层函数声明
#include "gpio.h"                   // 通用输入输出口宏及设备抽象层函数声明
#include "uart.h"                   // 通用异步串口宏及设备抽象层函数声明
#include "interrupt.h"              // DSP C6748 中断相关应用程序接口函数声明及系统事件号定义
#include "edma.h"                   // 直接内存访问宏及设备抽象层函数声明
#include "edma_event.h"             // 直接内存访问事件
#include "uartStdio.h"              // 串口标准输入输出终端函数声明
#include "string.h"
/****************************************************************************/
/*                                                                          */
/*              宏定义                                                      */
/*                                                                          */
/****************************************************************************/
// 软件断点
#define SW_BREAKPOINT     asm(" SWBP 0 ");
// EDMA3 参数
#define MAX_ACNT           1
#define MAX_CCNT           1
#define RX_BUFFER_SIZE     1
// EDMA3 通道
#define EVT_QUEUE_NUM          0
/****************************************************************************/
/*                                                                          */
/*              全局变量                                                    */
/*                                                                          */
/****************************************************************************/
volatile unsigned int flag = 0;
/****************************************************************************/
/*                                                                          */
/*              函数声明                                                    */
/*                                                                          */
/****************************************************************************/
// 外设使能配置
void PSCInit(void);
// DSP 中断初始化
void InterruptInit(void);
// EDMA3 中断初始化
void EDMA3InterruptInit(void);
// 串口发送数据
void UartTransmitData(unsigned int tccNum, unsigned int chNum,
                        volatile char *buffer, unsigned int buffLength);
// 串口接收数据
void UartReceiveData(unsigned int tccNum, unsigned int chNum,
                       volatile char *buffer);
// 回调函数
void (*cb_Fxn[EDMA3_NUM_TCC]) (unsigned int tcc, unsigned int status);
void callback(unsigned int tccNum, unsigned int status);
// UART EDMA3 初始化
void EDMA3UARTInit();
// EDMA3 初始化
void EDMA3Initialize(void);
// EDMA3 中断服务函数
void Edma3ComplHandlerIsr(void);
void Edma3CCErrHandlerIsr(void);
/****************************************************************************/
/*                                                                          */
/*              主函数                                                      */
/*                                                                          */
/****************************************************************************/
int main(void)
{
        // 外设使能配置
        PSCInit();
        // DSP 中断初始化
        InterruptInit();
        // EDMA3 中断初始化
        EDMA3InterruptInit();
        // EDMA3 初始化
        EDMA3UARTInit();
    // 初始化串口终端 使用串口2
    UARTStdioInit();
    // 申请串口 EDMA3 发送通道
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                          EDMA3_CHA_UART2_TX, EDMA3_CHA_UART2_TX,
                          EVT_QUEUE_NUM);
    // 注册回调函数
    cb_Fxn[EDMA3_CHA_UART2_TX] = &callback;
    // 申请串口 EDMA3 接收通道
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
                          EDMA3_CHA_UART2_RX, EDMA3_CHA_UART2_RX,
                          EVT_QUEUE_NUM);
    // 注册回调函数
    cb_Fxn[EDMA3_CHA_UART2_RX] = &callback;
    volatile char enter[] = "Tronlong UART2 EDMA3 Application......\n\rPlease Enter 20 bytes from keyboard\r\n";
    volatile char buffer[RX_BUFFER_SIZE];
    unsigned int buffLength = 0;
    // 发送数据
    buffLength = strlen((const char *)enter);
    UartTransmitData(EDMA3_CHA_UART2_TX, EDMA3_CHA_UART2_TX, enter, buffLength);
    // 使能串口 DMA 模式
    UARTDMAEnable(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1 |  \
                                     UART_DMAMODE |         \
                                     UART_FIFO_MODE );
    // 等待从回调函数返回
    while(flag == 0);
    flag = 0;
//    // 释放 EDMA3 通道
//    EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
//                       EDMA3_CHA_UART2_TX, EDMA3_TRIG_MODE_EVENT,
//                       EDMA3_CHA_UART2_TX, EVT_QUEUE_NUM);
//
//    EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
//                       EDMA3_CHA_UART2_RX, EDMA3_TRIG_MODE_EVENT,
//                       EDMA3_CHA_UART2_RX, EVT_QUEUE_NUM);
        // 主循环
        for(;;)
        {
            // 接收数据
            UartReceiveData(EDMA3_CHA_UART2_RX, EDMA3_CHA_UART2_RX, buffer);
            // 使能串口 DMA 模式
            UARTDMAEnable(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1 | \
                                             UART_DMAMODE |        \
                                             UART_FIFO_MODE );
            // 等待从回调函数返回
            while(flag == 0);
            flag = 0;
            // 发送数据
            UartTransmitData(EDMA3_CHA_UART2_TX, EDMA3_CHA_UART2_TX, buffer, RX_BUFFER_SIZE);
            // 使能串口 DMA 模式
            UARTDMAEnable(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1 |  \
                                             UART_DMAMODE |         \
                                             UART_FIFO_MODE );
            // 等待从回调函数返回
            while(flag == 0);
            flag = 0;
        }
}
/****************************************************************************/
/*                                                                          */
/*              PSC 初始化                                                  */
/*                                                                          */
/****************************************************************************/
void PSCInit(void)
{
        // 对相应外设模块的使能也可以在 BootLoader 中完成
        // 使能 EDMA3CC_0
    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
    // 使能 EDMA3TC_0
    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
}
/****************************************************************************/
/*                                                                          */
/*              DSP 中断初始化                                              */
/*                                                                          */
/****************************************************************************/
void InterruptInit(void)
{
        // 初始化 DSP 中断控制器
        IntDSPINTCInit();
        // 使能 DSP 全局中断
        IntGlobalEnable();
}
/****************************************************************************/
/*                                                                          */
/*              EDMA3 初始化                                                */
/*                                                                          */
/****************************************************************************/
void EDMA3UARTInit(void)
{
        EDMA3Init(SOC_EDMA30CC_0_REGS, EVT_QUEUE_NUM);
}
/****************************************************************************/
/*                                                                          */
/*              EDMA3 中断初始化                                            */
/*                                                                          */
/****************************************************************************/
void EDMA3InterruptInit(void)
{
        IntRegister(C674X_MASK_INT4, Edma3ComplHandlerIsr);
        IntRegister(C674X_MASK_INT5, Edma3CCErrHandlerIsr);
        IntEventMap(C674X_MASK_INT4, SYS_INT_EDMA3_0_CC0_INT1);
        IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_0_CC0_ERRINT);
        IntEnable(C674X_MASK_INT4);
        IntEnable(C674X_MASK_INT5);
}
/****************************************************************************/
/*                                                                          */
/*              EDMA3 中断服务函数                                          */
/*                                                                          */
/****************************************************************************/
void Edma3ComplHandlerIsr(void)
{
    volatile unsigned int pendingIrqs;
    volatile unsigned int isIPR = 0;
    unsigned int indexl;
    unsigned int Cnt = 0;
    indexl = 1;
    IntEventClear(SYS_INT_EDMA3_0_CC0_INT1);
    isIPR = HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_S_IPR(1));
    if(isIPR)
    {
        while((Cnt < EDMA3CC_COMPL_HANDLER_RETRY_COUNT)&& (indexl != 0u))
        {
            indexl = 0u;
            pendingIrqs = HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_S_IPR(1));
            while(pendingIrqs)
            {
                if((pendingIrqs & 1u) == TRUE)
                {
                    HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_S_ICR(1)) = (1u << indexl);
                    (*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE);
                }
                ++indexl;
                pendingIrqs >>= 1u;
            }
            Cnt++;
        }
    }
}
void Edma3CCErrHandlerIsr()
{
    volatile unsigned int pendingIrqs = 0;
    unsigned int regionNum = 0;
    unsigned int evtqueNum = 0;
    unsigned int index = 1;
    unsigned int Cnt = 0;
    IntEventClear(SYS_INT_EDMA3_0_CC0_ERRINT);
    if((HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_EMR) != 0 ) || \
       (HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_QEMR) != 0) || \
       (HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_CCERR) != 0))
    {
        while((Cnt < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (index != 0u))
        {
            index = 0u;
            pendingIrqs = HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_EMR);
            while(pendingIrqs)
            {
                if((pendingIrqs & 1u) == TRUE)
                {
                    HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_EMCR) = (1u<<index);
                    HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_S_SECR(regionNum)) = (1u<<index);
                }
                ++index;
                pendingIrqs >>= 1u;
            }
            index = 0u;
            pendingIrqs = HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_QEMR);
            while(pendingIrqs)
            {
                if((pendingIrqs & 1u)==TRUE)
                {
                    HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_QEMCR) = (1u<<index);
                    HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_S_QSECR(0)) = (1u<<index);
                }
                ++index;
                pendingIrqs >>= 1u;
            }
            index = 0u;
            pendingIrqs = HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_CCERR);
                        if(pendingIrqs != 0u)
                        {
                                for(evtqueNum = 0u; evtqueNum < EDMA3_0_NUM_EVTQUE; evtqueNum++)
                                {
                                        if((pendingIrqs & (1u << evtqueNum)) != 0u)
                                        {
                                                HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_CCERRCLR) = (1u << evtqueNum);
                                        }
                                 }
                                 if ((pendingIrqs & (1 << EDMA3CC_CCERR_TCCERR_SHIFT)) != 0u)
                                 {
                                         HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_CCERRCLR) = \
                                                  (0x01u << EDMA3CC_CCERR_TCCERR_SHIFT);
                                 }
                                 ++index;
                        }
                        Cnt++;
        }
    }
}
/****************************************************************************/
/*                                                                          */
/*              发送数据                                                    */
/*                                                                          */
/****************************************************************************/
void UartTransmitData(unsigned int tccNum, unsigned int chNum,
                         volatile char *buffer, unsigned int buffLength)
{
    EDMA3CCPaRAMEntry paramSet;
    // 配置参数 RAM
    paramSet.srcAddr = (unsigned int)buffer;
    // 接收缓存寄存器 / 发送保持寄存器 地址
    paramSet.destAddr = SOC_UART_2_REGS + 0;
    paramSet.aCnt = MAX_ACNT;
    paramSet.bCnt = (unsigned short)buffLength;
    paramSet.cCnt = MAX_CCNT;
    // 源索引自增系数 1 即一个字节
    paramSet.srcBIdx = (short)1u;
    // 目标索引自增系数
    paramSet.destBIdx = (short)0u;
    // 异步传输模式
    paramSet.srcCIdx = (short)0u;
    paramSet.destCIdx = (short)0u;
    paramSet.linkAddr = (unsigned short)0xFFFFu;
    paramSet.bCntReload = (unsigned short)0u;
    paramSet.opt = 0x00000000u;
    paramSet.opt |= (EDMA3CC_OPT_DAM );
    paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
    paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
    // 写参数 RAM
    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, ¶mSet);
    // 使能 EDMA3 通道
    EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_EVENT);
}
/****************************************************************************/
/*                                                                          */
/*              接收数据                                                    */
/*                                                                          */
/****************************************************************************/
void UartReceiveData(unsigned int tccNum, unsigned int chNum,
                            volatile char *buffer)
{
    EDMA3CCPaRAMEntry paramSet;
    // 配置参数 RAM
    // 接收缓存寄存器 / 发送保持寄存器 地址
    paramSet.srcAddr = SOC_UART_2_REGS + 0;
    paramSet.destAddr = (unsigned int)buffer;
    paramSet.aCnt = MAX_ACNT;
    paramSet.bCnt = RX_BUFFER_SIZE;
    paramSet.cCnt = MAX_CCNT;
    // 源索引自增系数
    paramSet.srcBIdx = 0;
    // 目标索引自增系数 1 即一个字节
    paramSet.destBIdx = 1;
    // 异步模式
    paramSet.srcCIdx = 0;
    paramSet.destCIdx = 0;
    paramSet.linkAddr = (unsigned short)0xFFFFu;
    paramSet.bCntReload = 0;
    paramSet.opt = 0x00000000u;
    paramSet.opt |= ((EDMA3CC_OPT_SAM) << EDMA3CC_OPT_SAM_SHIFT);
    paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
    paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
    // 写参数 RAM
    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, ¶mSet);
    // 使能 EDMA3 通道
    EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_EVENT);
}
/****************************************************************************/
/*                                                                          */
/*              回调函数                                                    */
/*                                                                          */
/****************************************************************************/
void callback(unsigned int tccNum, unsigned int status)
{
    UARTDMADisable(SOC_UART_2_REGS, (UART_RX_TRIG_LEVEL_1 | UART_FIFO_MODE));
    flag = 1;
}
 
 | 
 |