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.

C6678串口DMA数据传输求助

非DMA方式能正常的发送数据,现在配置成了DMA方式,经反复调试后发现:

1  DMA方式下,我用的数组方式存放要发送的串口数据,开始数组是8位的字节型数据,启动发送后,串口发出的数据全部是零,而我配置的是从0--39的十进制数,后来修改为32位无符号整型的数组,然后就可以正常发送了。DMA配置那边,我配置的FIFO宽度全部是8位宽,但都不起作用,难道6678的DMA对数据源只支持32位结构的数据类型吗?还是是我配置有问题?

2 采用上面的方式,数组配置为32位无符号整型,数组元素为40,然后赋值为0---39,然后启动发送,发现最多只能发送0--F,即只能发送数组里面前16个32位整型数据,后面还有24个死活发不出来,DMA那边我同样是配置了的

3 串口的FIFO深度是14字节还是16字节?UART手册上写的是最大14字节,我单独测试UART,发现FIFO模式下一次可以最大发16字节,从而猜测是16字节才对。 

    上面2中最大只能发16个数,是和UART的FIFO深度是16有关吗?

相关代码如下

DMA配置:

EDMA3CC2Regs->DCHMAPn[0].bit.PAENTRY = 0;//使用PaRAM[0]
EDMA3CC2Regs->DMAQNUMn[5].bit.E1 = 0;//事件E41在队列Q0上,事件E41对应串口发送事件
//EDMA3CC2Regs->QCHMAPn[0].bit.TRWORD = 0;
//EDMA3CC2Regs->QCHMAPn[0].bit.PAENTRY = 0;


//EDMA3CC2Regs->DRAEH0.bit.E41 = 1;
//EDMA3CC2Regs->EERH.bit.E41 = 1;
//EDMA3CC2Regs->EESRH.bit.E41 = 1;

//EDMA3CC2TC0Regs->Read_Rate.bit.RDRATE = 1;//

//EDMA3CC2TC0Regs->SADDR = 10;

EDMA3CC2TC0Regs->SAOPT.bit.FWID = 0;//数据宽度是8位
EDMA3CC2TC0Regs->SAOPT.bit.SAM = 0;//每次传输完成,源地址增一
EDMA3CC2TC0Regs->SAOPT.bit.DAM = 1;//每次传输完成,目标地址不变

EDMA3CC2TC0Regs->DFOPT0.bit.FWID = 0;//数据宽度是8位
EDMA3CC2TC0Regs->DFOPT0.bit.SAM = 0;//
EDMA3CC2TC0Regs->DFOPT0.bit.DAM = 1;//
EDMA3CC2TC0Regs->DFOPT0.bit.PRI = 0;

EDMA3CC2_PaRAMRegs->PaRAM[0].SRC_DST_BIDX.all = 0;
EDMA3CC2_PaRAMRegs->PaRAM[0].LINK_BCNTRLD.all = 0;
EDMA3CC2_PaRAMRegs->PaRAM[0].SRC_DST_CIDX.all = 0;

EDMA3CC2_PaRAMRegs->PaRAM[0].OPT.bit.SAM = 0;//每次传输完成,源地址增一
EDMA3CC2_PaRAMRegs->PaRAM[0].OPT.bit.DAM = 1;//每次传输完成,目标地址不变
EDMA3CC2_PaRAMRegs->PaRAM[0].OPT.bit.SYNCDIM = 0;
EDMA3CC2_PaRAMRegs->PaRAM[0].OPT.bit.STATCI = 0;
EDMA3CC2_PaRAMRegs->PaRAM[0].OPT.bit.FWID = 2;
EDMA3CC2_PaRAMRegs->PaRAM[0].OPT.bit.TCCMODE = 0;
EDMA3CC2_PaRAMRegs->PaRAM[0].OPT.bit.PRIV = 0;

EDMA3CC2_PaRAMRegs->PaRAM[0].SRC = 0;
EDMA3CC2_PaRAMRegs->PaRAM[0].DST = 0x02540000;//目标地址是串口发送THR的物理地址

EDMA3CC2_PaRAMRegs->PaRAM[0].SRC_DST_BIDX.bit.SRCBIDX = 0;//
EDMA3CC2_PaRAMRegs->PaRAM[0].SRC_DST_BIDX.bit.DSTBIDX = 0;

EDMA3CC2_PaRAMRegs->PaRAM[0].SRC_DST_CIDX.bit.SRCCIDX = 0;
EDMA3CC2_PaRAMRegs->PaRAM[0].SRC_DST_CIDX.bit.DSTCIDX = 0;


EDMA3CC2_PaRAMRegs->PaRAM[0].A_B_CNT.bit.ACNT = 160; //ACNT = 4*40,每次发送40个32位数据
EDMA3CC2_PaRAMRegs->PaRAM[0].A_B_CNT.bit.BCNT = 1; //一行
EDMA3CC2_PaRAMRegs->PaRAM[0].C_CNT.bit.CCNT = 1; //一列

DMA启动发送:

Uint32 TxData[40];
//unsigned char TxData[40];
Uint32 i;

EDMA3CC2_PaRAMRegs->PaRAM[0].SRC = (Uint32)(&TxData[0]);
EDMA3CC2Regs->ESRH.bit.E41 = 1; //手动启动DMA
while(EDMA3CC2Regs->ERH.bit.E41 == 0);//等待标志位
EDMA3CC2Regs->ECRH.bit.E41 = 1; //标志位清零

  • EDMA3CC2TC0Regs->SAOPT.bit.FWID = 0;//数据宽度是8位
    是不是FIFO WIDTH 设置的不对?设置成128bit看看。
    这个帖子看一下。
    e2echina.ti.com/.../100468
    UART FIFO是16字节。
    The UART transmitter section includes a transmitter hold register (THR) and a transmitter shift register (TSR). When the UART is in the FIFO mode, THR is a 16-byte FIFO.
    The UART receiver section includes a receiver shift register (RSR) and a receiver buffer register (RBR). When the UART is in the FIFO mode, RBR is a 16-byte FIFO.
  • 试了,把FIFO设置成128位宽,结果发出来的数据就全错了。串口是8位的发送THR,如果我的数组是32位结构,至少还能正常发出40个字节的前16个,对应数据刚好是0--16,我把数组改成8位的数据类型,发出的就是全部为零了,这个咋回事啊,上面1中我提到过的
  • 嗯,我没说准确,正确的现象是这样的,数组元素是40个,发送的数组我采用8位的char类型时,我给数组元素赋值是从0--39,发送时只发送了16个元素,有24个元素发不出来,且对应的值分别是0 4 8 C 10 14 18 1C 20 24 28 2C 30 34 38 3C ,很明显DMA没有发送数组元素 1 2 5 6 9 A ......,这是否说明DMA不支持8位数据模式,但文档里明确说了FIFO可以配置成8位数据宽度,这个不知道怎么回事,代码里面各种情况我都配置过,基本都是如此。唯有将数组数据格式写为32位整型,然后给每个元素赋值0---39,发出的数据才是0 1 2 3 4 5 6 7......一直到F。
    现在我把代码做了如下的特殊处理:
    Uint32 TxData[251];

    for(i=0;i<251;i++)
    {
    TxData[i] = i;
    }


    EDMA3CC2_PaRAMRegs->PaRAM[0].A_B_CNT.bit.ACNT = 64;//ACNT = 4*16,每次发送16个32位数据
    for(i=0;i<15;i++)//先发送前240个字节
    {
    EDMA3CC2_PaRAMRegs->PaRAM[0].SRC = (Uint32)(&TxData[16*i]);
    EDMA3CC2Regs->ESRH.bit.E41 = 1; //手动启动DMA
    while(EDMA3CC2Regs->ERH.bit.E41 == 0);//等待标志位
    EDMA3CC2Regs->ECRH.bit.E41 = 1; //标志位清零
    }


    EDMA3CC2_PaRAMRegs->PaRAM[0].A_B_CNT.bit.ACNT = 44;//ACNT = 4*11,每次发送11个32位数据
    EDMA3CC2_PaRAMRegs->PaRAM[0].SRC = (Uint32)(&TxData[240]);//发送余下的11个字节
    EDMA3CC2Regs->ESRH.bit.E41 = 1; //手动启动DMA
    while(EDMA3CC2Regs->ERH.bit.E41 == 0);//等待标志位
    EDMA3CC2Regs->ECRH.bit.E41 = 1; //标志位清零

    串口助手接收到的数据如下:

    [21:35:57.146]收←◆00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA

    运行了一段时间,没有问题,串口助手那边表面上看起来没有时间差,都是同时打印到助手的显示区域的。但实际在每16个字节之间会不会有很大的时间间隔,板子上的IO口不方便接仪器测量,没法直接测量到这个时间间隔有多大。目前主要目的还是要把DMA这块搞扎实点,给后面做核间通信打好基础。
  • SAM, DAM, FWID这些都是无效的, 如果要地址不变,应该通过index=0来实现,不能配置SAM, DAM.

    如果用了UART的FIFO, 则ACNT要跟FIFO threshold一致, 否则只能设为1个element. 这里UART一个数据为8bit, 则ACNT=1.

    UART的FIFO深度是16byte, 只是threshold设置最大为14byte

    https://www.ti.com/lit/ug/sprugp1/sprugp1.pdf

  • 那你所说的索index指的是PaRam set 中的吧,如下:
    EDMACC0_PaRAMRegs->PaRAM[0].SRC_DST_BIDX.bit.SRCBIDX = 1;//
    EDMACC0_PaRAMRegs->PaRAM[0].SRC_DST_BIDX.bit.DSTBIDX = 0;

    EDMACC0_PaRAMRegs->PaRAM[0].SRC_DST_CIDX.bit.SRCCIDX = 0;
    EDMACC0_PaRAMRegs->PaRAM[0].SRC_DST_CIDX.bit.DSTCIDX = 0;