This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320C6748:uart1上的 EDMA 不工作

Guru**** 2589280 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/639623/tms320c6748-edma-on-uart1-not-working

器件型号:TMS320C6748

您好!

我正在使用 C6748 lcdk 套件。 我已经尝试了具有用于 UART EDMA 的 C6748 Starterware 程序的编程板。 它成功地工作了。 该程序适用于 UART2。 现在、我要对 UART1执行它。 但该程序不起作用。 下面给出了程序。 我将 RBR 寄存器的基地址和 UART 的相应通道编号从2更改为1。 程序仍然不起作用。 请帮助我找到错误。

/**
*\file uartEcho.c
*
*\brief 这是调用某些 API 的示例应用文件
*来自 EDMA3器件抽象层以及 UART
用于执行配置的*器件抽象层、和
*由在 UART 和 CPU RAM 之间传输数据
* EDMA3的使用
*

/*
*版权所有(C) 2012德州仪器(TI)公司- http://www.ti.com/
*
*以源代码和二进制形式重新分发和使用、有无
*如果满足以下条件、则允许进行修改
符合*:
*
*源代码的重新分发必须保留上述版权
*注意、此条件列表和以下免责声明。
*
*二进制形式的再发行必须复制上述版权
*请注意、中的此条件列表和以下免责声明
*随提供的文档和/或其他材料
*分发。
*
*德州仪器公司的名称和名称均不相同
*其贡献者可用于认可或推广衍生产品
*未经特定的事先书面许可。
*
*本软件由版权所有者和贡献者提供
*"按原样"以及任何明示或暗示的保证、包括但不包括
*仅限于对适销性和适用性的暗示保证
*一项特定目的不予承认。 在任何情况下、版权均不得
*所有者或贡献者应对任何直接、间接、偶然或
*特殊、惩戒性或后果性损害(包括但不包括)
*仅限于采购替代货物或服务;丧失使用、
*数据或利润;或业务中断)
*责任理论、无论是合同责任、严格责任还是侵权行为
*(包括疏忽或其他)因使用而以任何方式产生
*、即使被告知可能会发生此类损坏。
*

#include "psc.h"
#include "UART.h"
#include "edma.h"
#include "string.h"
#include "hw_types.h"
#include "uartStdio.h"
#include "lcdkC6748.h"
#include "interrupt.h"
#include "edma_event.h"
#include "SoC_C6748.h"
#include "HW_PSC_C6748.h"

/ /
/*内部宏定义*/
/ /
#define UART_RBR_THR_REG ((0x01D0C000u)+(0U))

#define MAX_ACNT 1
#define MAX_CCNT 1

#define RX_buffer_size 20

/* EDMA3事件队列编号。 *
#define EVT_queue_NUM 0

/ /
/*本地函数原型*/
/ /
静态空 UartTransmitData (unsigned int tccNum、unsigned int chNum、
volatile char * buffer、unsigned int buffLength);

/*回调函数声明*/
静态空(* CB_Fxn[EDMA3_NUM_TCC])(无符号 int TCC、无符号 int 状态);
静态空 UartReceiveData (unsigned int tccNum、unsigned int chNum、
volatile char * buffer);
静态空回调(unsigned int tccNum、unsigned int status);
静态空配置 IntEDMA3 (空);
静态空 Edma3ComplHandlerIsr (空);
静态空 Edma3CCErrHandlerIsr (空);
静态空 EDMA3初始化(空);
static void SetupInt (void);

/ /
/*全局变量*/
/ /
volatile unsigned int flag = 0;

/ /
/*本地函数定义*/
/ /

/*
**主函数。
*

int main (空)

volatile char enter[]="\r\n 请从键盘输入20个字节\r\n";
// volatile char enter[]="\r\n\r\n";
volatile char buffer[RX_buffer_size];
无符号 buffint 长度= 0;

/*初始化 EDMA3控制器*/
EDMA3初始化();

/*初始化 UART */
UARTStdioInit();

/*请求 DMA 通道和 TCC 以进行 UART 传输*/
EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、
EDMA3_CHA_UART1_TX、EDMA3_CHA_UART1_TX、
evt_queue_NUM);

/*为 TX*/注册回调函数
CB_Fxn[EDMA3_CHA_UART1_TX]=回调(&B);

/*请求 DMA 通道和 TCC 以进行 UART 接收*/
EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、
EDMA3_CHA_UART1_RX、EDMA3_CHA_UART1_RX、
evt_queue_NUM);

/*为 RX*/注册回叫功能
CB_Fxn[EDMA3_CHA_UART1_RX]=回调(&B);

/*用于 bcnt */
buffLength = strlen ((const char *) enter);

/*输入消息的发送数据*/
UartTransmitData (EDMA3_CHA_UART1_TX、EDMA3_CHA_UART1_TX、
Enter、buffLength);

/*在 DMA 模式下启用 UART */
UARTDMAEnable (SOC_UART_1_regs、UART_RX_TRIG_LEVEL_1 |\
UART_DMAMODE |\
UART_FIFO_MODE );

/*等待回调函数的控制权返回*/
while (0 =标志);
标志= 0;

/*接收输入数据*/
UartReceiveData (EDMA3_CHA_UART1_RX、EDMA3_CHA_UART1_RX、缓冲器);


/*在 DMA 模式下启用 UART */
UARTDMAEnable (SOC_UART_1_regs、UART_RX_TRIG_LEVEL_1 |\
UART_DMAMODE |\
UART_FIFO_MODE );

/*等待回调返回*/
while (0 =标志);
标志= 0;

/*为输入的值传输数据*/
UartTransmitData (EDMA3_CHA_UART1_TX、EDMA3_CHA_UART1_TX、
缓冲器、RX_buffer_size);

/*在 DMA 模式下启用 UART */
UARTDMAEnable (SOC_UART_1_regs、UART_RX_TRIG_LEVEL_1 |\
UART_DMAMODE |\
UART_FIFO_MODE );

/*等待回调返回*/
while (0 =标志);
标志= 0;

//针对 TX 和 RX 提供免费的 EDMA3通道*/
EDMA3 FreeChannel (SOC_EDMA30CC_0_reg、EDMA3_CHANNEL_TYPE_DMA、
EDMA3_CHA_UART1_TX、EDMA3_TRIG_MODE_EVENT、
EDMA3_CHA_UART1_TX、EVT_queue_NUM);

EDMA3 FreeChannel (SOC_EDMA30CC_0_reg、EDMA3_CHANNEL_TYPE_DMA、
EDMA3_CHA_UART1_RX、EDMA3_TRIG_MODE_EVENT、
EDMA3_CHA_UART1_RX、EVT_queue_NUM);

while (1);

/*
**此函数用于设置传输通道的 EDMA3中的参数条目
UART 的**。 在该 API 中也会调用 EDMA3使能传输。
*

静态空 UartTransmitData (unsigned int tccNum、unsigned int chNum、
volatile char * buffer、unsigned int buffLength)

EDMA3CCPaRAMEntry 参数集;

/*用传输特定信息填充参数集*/
ParamSet.srcAddr =(unsigned int)缓冲区;
paramSet.destAddr = UART_RBR_THR_REG;
ParamSet.aCnt = MAX_ACNT;
ParamSet.bCnt =(无符号短整型) buffLength;
ParamSet.ccnt = MAX_CCNT;

/*每个被传输的字节的 src 索引都应递增。 *
ParamSet.srcBIdx =(短) 1U;

/*由于 dst 索引是 h/w 寄存器*/,因此 dst 索引不应递增
paramSet.destBIdx =(简版) 0U;

/*同步传输模式*/
ParamSet.srcCIdx =(短整型) 0U;
paramSet.destCIdx =(简版) 0U;
ParamSet.linkAddr =(无符号短整型) 0xFFFFFFU;
ParamSet.bCntReload =(无符号短整型) 0U;
ParamSet.opt = 0x000000000000u;
ParamSet.opt |=(EDMA3CC_opt_DAM );
ParamSet.opt |=((tccNum << EDMA3CC_OPT_TCC_SHIFT)和 EDMA3CC_OPT_TCC);
ParamSet.opt |=(1 << EDMA3CC_opt_TCINTEN 位移);

/*现在写入参数集*/
EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、chNum、&ParamSet);

/*启用 EDMA 传输*/
EDMA3 EnableTransfer (SOC_EDMA30CC_0_regs、chNum、EDMA3_TRIG_MODE_EVENT);

/*
**此函数用于为接收通道设置 EDMA3的参数集
UART 的**。 在该 API 中也会调用 EDMA3使能传输。
*

静态空 UartReceiveData (unsigned int tccNum、unsigned int chNum、
volatile char *缓冲区)

EDMA3CCPaRAMEntry 参数集;

/*用传输特定信息填充参数集*/
ParamSet.srcAddr = UART_RBR_THR_REG;
paramSet.destAddr =(unsigned int)缓冲区;
ParamSet.aCnt = MAX_ACNT;
ParamSet.bCnt = RX_buffer_size;
ParamSet.ccnt = MAX_CCNT;

/* src 索引不应递增,因为它是一个 h/w 寄存器*/
ParamSet.srcBIdx = 0;
/* dest 索引应针对每个字节递增*/
paramSet.destBIdx = 1;

/*同步传输模式*/
ParamSet.srcCIdx = 0;
paramSet.destCIdx = 0;
ParamSet.linkAddr =(无符号短整型) 0xFFFFFFU;
ParamSet.bCntReload = 0;
ParamSet.opt = 0x000000000000u;
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 位移);

/*现在写入参数集*/
EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、chNum、&ParamSet);

/*启用 EDMA 传输*/
EDMA3 EnableTransfer (SOC_EDMA30CC_0_regs、chNum、EDMA3_TRIG_MODE_EVENT);

用于初始化 EDMA3的/*函数*/
静态空 EDMA3初始化(空)

/*为 EDMA3CC_0启用 PSC。*/
PSCModuleControl (SOC_PSC_0_regs、HW_PSC_cC0、PSC_POWERDOMAIN_AYS_ON、
PSC_MDCTL_NEW_ENABLE);

/*为 EDMA3TC_0启用 PSC。*/
PSCModuleControl (SOC_PSC_0_regs、HW_PSC_TC0、PSC_POWERDOMAIN_AYST_ON、
PSC_MDCTL_NEW_ENABLE);

/* EDMA3初始化*/
EDMA3Init (SOC_EDMA30CC_0_regs、EVT_queue_NUM);

/*
**启用 AINTC 以处理中断。 还在中启用 IRQ 中断
** ARM 处理器。
*
SetupInt();

/*寄存器 EDMA3中断*/
配置 IntEDMA3();

用于设置 ARM 中断控制器的/*函数*/
静态空 SetupInt (空)

#ifdef _TMS320C6x
//初始化 DSP 中断控制器
IntDSPINTCMINIT();

//全局启用 DSP 中断
IntGlobalEnable();
其他
/*初始化 ARM 中断控制器(AINTC)。 *
IntAINTCInit();

/*在 CPSR 中启用 IRQ。*/
IntMasterIRQEnable();

/*在 AINTC 的 GER 中启用中断。*/
IntGlobalEnable();

/*在 AINTC 的 HIER 中启用中断。*/
IntIRQEnable();
#endif

/* EDMA3完成处理程序*/
静态空 edma3ComplHandler (unsigned int baseAdd、unsigned int regionNum)

volatile unsigned int pendingIrqs;
volatile unsigned int isIPR = 0;

unsigned int indexl;
unsigned int cnt = 0;
分度值= 1;

#ifdef _TMS320C6x
IntEventClear (SYS_INT_EDMA3_0_cC0_INT1);
其他
IntSystemStatusClear (SYS_INT_CCINT0);
#endif
isIPR = HWREG (baseAdd + EDMA3CC_S_IPR (regionNum));
if (isIPR)

while (((cnt < EDMA3CC_compl_handler_retry_count)&&(indexl!= 0U))

分度= 0U;
pendingIrqs = HWREG (baseADD + EDMA3CC_S_IPR (regionNum));
while (pendingIrq)

if ((pendingIrqs & 1U)=true)

/**
*如果用户没有提供任何回调函数
请求 TCC 时、其 TCC 特定位
不会清除 IPR 寄存器中的*。
*
//此处写入 ICR 以清除相应的 IPR 位*/
HWREG (baseAdd + EDMA3CC_S_ICR (regionNum))=(1U <<索引);

(* CB_Fxn[indexl])(indexl、EDMA3_Xfer_COMPLETE);

++indexl;
pendingIrqs >=1U;

CNT++;


静态空 Edma3ComplHandlerIsr (空)

#ifdef _TMS320C6x
//调用完成处理程序 ISR
edma3ComplHandler (SOC_EDMA30CC_0_regs、1);
其他
/*调用完成处理程序 ISR */
edma3ComplHandler (SOC_EDMA30CC_0_regs、0);
#endif

/* EDMA3错误处理程序*/
静态空 edma3CCErrHandler (unsigned int baseAdd)

volatile unsigned int pendingIrqs = 0;
unsigned int regionNum = 0;
unsigned int evtqueNum = 0;
unsigned int index = 1;
unsigned int cnt = 0;

#ifdef _TMS320C6x
IntEventClear (SYS_INT_EDMA3_0_cC0_ERRINT);
其他
IntSystemStatusClear (SYS_INT_CCERRINT);
#endif

if ((HWREG (baseAdd + EDMA3CC_EMR)!= 0)||\
(HWREG (baseAdd + EDMA3CC_QEMR)!= 0)||\
(HWREG (baseADD + EDMA3CC_CCERR)!= 0))

/* EDMA3CC_ERR_handler_retry_count 的循环时间、间隔数
未找到暂挂中断时*/
while ((cnt < EDMA3CC_ERR_handler _retry_count)&&(索引!= 0U))

索引= 0U;
pendingIrqs = HWREG (baseADD + EDMA3CC_EMR);
while (pendingIrq)

/*处理所有挂起的中断*/
if ((pendingIrqs & 1U)=true)

/*写入 EMMR 以清除相应的 EMR 位。*/
HWREG (baseAdd + EDMA3CC_EMMR)=(1U<<index);
/*清除所有 SER */
HWREG (baseAdd + EDMA3CC_S_Secr (regionNum))=(1U<<index);

++索引;
pendingIrqs >=1U;

索引= 0U;
pendingIrqs = HWREG (baseADD + EDMA3CC_QEMR);
while (pendingIrq)

/*处理所有挂起的中断*/
if ((pendingIrqs & 1U)=true)

/*此处写入 QEMMR 以清除相应的 QEMR 位*/
HWREG (baseAdd + EDMA3CC_QEMMR)=(1U<<index);
/*清除任何 QSER*/
HWREG (baseAdd + EDMA3CC_S_QSECR (0))=(1U<<index);

++索引;
pendingIrqs >=1U;

索引= 0U;
pendingIrqs = HWREG (baseADD + EDMA3CC_CCERR);
if (挂起 Irqs!= 0U)

/*处理所有挂起的 CC 错误中断。 *
/*不同事件队列的队列阈值错误。*/
对于(evtqueNum = 0U;evtqueNum < EDMA3_0_NUM_EVTQUE;evtqueNum++)

if ((pendingIrqs &(1U <<evtqueNum))!= 0U)

/*清除错误中断。 *
HWREG (baseAdd + EDMA3CC_CCERRCLR)=(1U << evqueNum);

/*传输完成代码错误。 *
if ((pendingIrqs &(1 << EDMA3CC_CCERR_TCCERR_SHIFT))!= 0U)

HWREG (baseAdd + EDMA3CC_CCERRCLR)=\
(0x01u << EDMA3CC_CCERR_TCCERR_SHIFT);

++索引;

CNT++;


静态空 Edma3CCErrHandlerIsr()

/*调用 CC 错误处理程序 ISR */
edma3CCErrHandler (SOC_EDMA30CC_0_regs);

/*注册 EDMA3中断的函数*/
静态空配置 IntEDMA3 (空)

/*在此处注册中断*/

#ifdef _TMS320C6x
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);
其他
IntRegister (SYS_INT_CCINT0、Edma3ComplHandlerIsr);

IntChannelSet (SYS_INT_CCINT0、2);

IntSystemEnable (SYS_INT_CCINT0);

内部寄存器(SYS_INT_CCERRINT、Edma3CCErrHandlerIsr);

IntChannelSet (SYS_INT_CCERRINT、2);

IntSystemEnable (SYS_INT_CCERRINT);
#endif


/*
**此函数用作 EDMA3完成处理程序的回调。
**在 DMA 模式下禁用 UART。
*
静态空回调(unsigned int tccNum、unsigned int status)

UARTDMADisable (SOC_UART_1_regs、(UART_RX_TRIG_LEVEL_1 | UART_FIFO_MODE);
FLAG = 1;

/********* 文件结尾******** /

提前感谢

Shalini K

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我已将您的疑问转发给软件专家。 他们的反馈应发布在此处。

    BR
    Tsvetolin Shulev
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    可能需要更改时钟和引脚多路复用器。 请参阅

    platform\lcdkC6748\uartConsole.c
    #define UART_stdio_instance (2)
    #define UART_console_base (SoC_UART_2_regs)
    

    您将需要重新编译平台库以对 uartConsole.c 进行更改