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.

CC1110 的DMA 采用16bit字模式,源为SFR时会出现高低字节反序的BUG,而源为SRAM时则正常

Other Parts Discussed in Thread: CC2540, CC2510

CC1110 的DMA 采用16bit字模式,源为SFR时会出现高低字节反序,而源为SRAM时则正常


本身想利用 DMA 高速读取ADC,满64次后再进行ADPCM压缩。

ADC结果寄存器是小端排列符合IAR EW8051小端要求,刚刚好

却发现 使用 DMA_WORDSIZE_WORD 16bit字模式时 ,ADC结果在目标SRAM会出现高低字节反序,需要自己手动反序才能进行ADPCM运算 ,晕死。

如果改成字节模式,那就每次只能读2个字节(1次ADC结果),用DMA的意义跟0差不多。

寄存器测试, 结果是高低字节反序

#define X_ADCL XREG( 0xDFBA )
#define X_ADCH XREG( 0xDFBB )
#define X_RNDL XREG( 0xDFBC )
#define X_RNDH XREG( 0xDFBD )
#define X_U0DBUF XREG( 0xDFC1 )
#define X_U0BAUD XREG( 0xDFC2 )

SRCADDR 指向 0xDFBA(X_ADCL) 那么 SRAM_BUF的结果是 ADCH1,ADCL1 ADCH2,ADCL2
SRCADDR 指向 0xDFBB(X_ADCH) 那么 SRAM_BUF的结果是 RNDL, ADCH1, RNDL, ADCH2
SRCADDR 指向 0xDFBC(X_RNDL) 那么 SRAM_BUF的结果是 RNDH, RNDL, RNDH, RNDL
// 对应 CC2540协议栈
SRCADDR 指向 0xDFBC(X_U0DBUF) 那么 SRAM_BUF的结果是 U0BAUD,U0DBUF, U0BAUD,U0DBUF,

===================

SRAM测试 ,结果是不改变字节顺序

SRAM_SRC 数据是 0x11,0x22
SRCADDR 指向 SRAM_SRC 那么 SRAM_BUF的结果 是 0x11,0x22, 0x11,0x22

===========================================

我能找到官方的唯一一个 ADC DMA例子,却是字节模式, 每次只能读取1次结果的DMA (wtf?)

adc_cont_dma_seq.c // SWRC117 - cc1110_cc2510_Basic Software_Examples
里面的设置是

DMA_WORDSIZE_BYTE , 字节模式

LEN=2 , ADC结果是16bit,所以是2字节

DMA_SRCINC_1 源地址每次+1

DMA_DESTINC_1 目标地址每次+1

DMA_TMODE_BLOCK 每次传输1块(就是前面的2字节)

5个DMA通道对应5个ADC通道,只能读一次结果, 再启动就重复刷新目标缓冲区。

简直就是没卵用啊

===============================

网上唯一关于 DMA_WORDSIZE_WORD 的讨论就是 CC2540协议栈高速串口通信解决(UART的DMA方式)

官方代码 是同时读取 X_U0DBUF 和 X_U0BAUD (字模式,源地址指向X_U0DBUF )
#define X_U0DBUF XREG( 0xDFC1 )
#define X_U0BAUD XREG( 0xDFC2 )
例子中 U0BAUD = 0xD8

外部发送的数据是 0x01,0x02,0x03,0x04
而SRAM_BUF的排列却是 0xD8,0x01,0xD8,0x02,0xD8,0x03,0xD8,0x04

很明显是 源高地址U0BAUD的值 却被传输到 目标的低地址 上


===============================

有其他用户使用过字模式的DMA传输么?
能否确认 TI 8051核的DMA存在这个特殊BUG?

(翻了好多CC11xx CC24xx CC25xx 的规格书都找不到相关描述 ,网上也找不到16bit DMA的应用 )

迟点再看看DMA写入寄存器是否存在相同的反序现象

@AZ 

  • DMA 16bit字写入的情况一样, 目标为SFR高低字节反序, 目标为SRAM则正常

    一个有趣的组合是 源和目标都是SFR,那么反转再反转还是正确字节序 

  • 既然是BUG,只好变通了

    128个ADC数据采样
    2个数组缓存,3次DMA操作

    一个是ADC的DMA缓存数组 Buff_1[256], 这个数据会循环刷新,不建议直接取用。

    一个是处理用的缓存数组 Buff_2[257],多留1个字节或字

    实际数据类型是 16bit x 128,但用 8bit x 256 格式好描述

    第1次DMA 就是 ADC触发的,2Bx128次 Buff_1[]获得字节反序的数据
    Buff_1[]的数据排列是 1H,1L,2H,2L (大端格式 KEIL C51使用)


    第二次 DMA 是 &Buff_1[0] --->&Buff_2[1](目标地址首地址地址偏移1B) , 256Bytes
    Buff_2[] 的数据排列是 x,1H,1L,2H,2L


    第三次 DMA 是搬移Buff_2[]单数地址的数据往前2字节的位置, 利用了DMA有每次传输后地址+2的能力。 共128Bytes
    [2]-->[0],[4]->[2],,,[128]->[126]

    Buff_2[] 的数据排列是 1L,1H,2L,2H, (小端格式 ,IAR EW8051使用 ,也跟寄存器序一样)


    ******

    为了让处理数组拿到正确字节序的数据,还需要第3次DMA ,IO测量这2/3次DMA总耗时 20us多吧,

    等于多了一次消耗10us不到的DMA操作,也是可以接受的


    ==============================================
    不过到了后来

    我发现在ADPCM压缩/解压程序里面做技巧,也可以完成字节序反转,不花费额外指令和时间。 唉

  • 我也遇到了大小端问题,你是怎么解决的?