基于dma的sequence ADC 出问题
大家好,我正在写4个channel 的sequence ADC,采样率1k, 然后用4个dma channel读出来。 我根据网上代码写了dma函数。 并且关闭了stack里面的dma和aes_dma 。 但是一再simpleblepheriphalInit()里运行我得init, 蓝牙就出问题了,只广播了一个包。注释掉init一切正常。 以下是我的代码 :
/******************************************************************************
************************** DMA structures / macros *************************
*******************************************************************************
The macros and structs in this section simplify setup and usage of DMA.
******************************************************************************/
#ifndef _adcdma_H_
#define _adcdma_H_
#include <ioCC2540.h>
#include <hal_types.h>
// Place the bitfield members from the most significant bit to the least significant bit.
#pragma bitfields=reversed
typedef struct {
uint8 SRCADDRH;
uint8 SRCADDRL;
uint8 DESTADDRH;
uint8 DESTADDRL;
uint8 VLEN : 3;
uint8 LENH : 5;
uint8 LENL : 8;
uint8 WORDSIZE : 1;
uint8 TMODE : 2;
uint8 TRIG : 5;
uint8 SRCINC : 2;
uint8 DESTINC : 2;
uint8 IRQMASK : 1;
uint8 M8 : 1;
uint8 PRIORITY : 2;
} DMA_DESC;
#pragma bitfields=default
// DMA descriptor n -> DMA channel n.
static __xdata DMA_DESC dma_channel[4];
/*******************************************************************************
* FUNCTIONS
*/
void initDmaa(uint16 __xdata *ADCresult_adr);
void startADCDma(void);
void dma_channel_init ( DMA_DESC __xdata *dma_p,
uint16 __xdata *dest_adr,
uint8 lenl,
uint8 trig );
#endif
/***********************************************************************************
File name: adcDma.c
***********************************************************************************/
#include "adcdma.h"
void initDmaa(uint16 __xdata *ADCresult_adr){
/****************************************************************************
* I/O-Port configuration
* PIN0_0 to P0_3 is configured as ADC input pins.
* APCFG[7:0] select P0.7–P0.0 as analog I/O.
*/
APCFG = 0x0F;
// Set the DMA channel 0 configuration address registers.
DMA0CFGL = ((uint16)&dma_channel[0]) & 0x00FF;
DMA0CFGH = ((uint16)&dma_channel[0] >> 8);
// Set the DMA channel 1-4 configuration address registers.
DMA1CFGL = ((uint16)&dma_channel[1]) & 0x00FF;
DMA1CFGH = ((uint16)&dma_channel[1] >> 8);
/****************************************************************************
* DMA configuration:
* Set up DMA channel 1 and 2 for transfer from ADCL and ADCH to
* the ADC result table. The ADC will generate the DMA trigger
* on end of conversion.
*/
// Configure DMA channel 0.
dma_channel_init(&dma_channel[0], ADCresult_adr, 1, 21); //ch 0 21
// Configure DMA channel 1.
dma_channel_init(&dma_channel[1], &ADCresult_adr[1], 1, 22); // ch 1 22 .. 23 34
// Configure DMA channel 2.
dma_channel_init(&dma_channel[2], &ADCresult_adr[2], 1, 23);
// Configure DMA channel 3.
dma_channel_init(&dma_channel[3], &ADCresult_adr[3], 1, 24);
}
void startADCDma(void)
{
// Arm DMA channels, takes 36 clock cycles.
DMAARM = 0x0F;
ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP; // 9 NOPs
ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP; // 9 NOPs
ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP; // 9 NOPs
ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP;ASM_NOP; // 9 NOPs
/****************************************************************************
* ADC configuration :
* - Continous mode
* - Single-ended sequence conversion
* - Reference Voltage is VDD on the AVDD pin
* - 9 bit resolution (128 dec rate)
*/
/* ADC conversion :
* reference voltage ACDD5 10
* 9 bits ENOB settings 01
* SCH from channel AIN0 to AIN3 0011
*/
ADCCON2 = 0x93;
// FULL SPEED continous ADC
ADCCON1 = 0x13;
/*
* Await all data transfers being completed. from dma channel 0 to 3
*/
while( DMAIRQ != 0x0F );
// reset the interrupt
DMAIRQ = 0x00;
// unarm
DMAARM = 0x00;
// Stop continuous mode.(ADC)
ADCCON1 |= 0x40;
}
void dma_channel_init ( DMA_DESC __xdata *dma_p,
uint16 __xdata *dest_adr,
uint8 lenl,
uint8 trig )
{
// Setup DMA configuration.-
dma_p->SRCADDRH = (uint16)(&X_ADCL) >> 8;
dma_p->SRCADDRL = (uint16)(&X_ADCL) & 0x00FF;
dma_p->DESTADDRH = ((uint16)dest_adr) >> 8;
dma_p->DESTADDRL = ((uint16)dest_adr);
dma_p->VLEN = 0x00;
dma_p->LENH = 0;
dma_p->LENL = lenl; // Tranfer Count
dma_p->WORDSIZE = 0x00;
dma_p->TMODE = 0x01;
dma_p->TRIG = trig; // Channel trigger
dma_p->SRCINC = 0x01;
dma_p->DESTINC = 0x01;
dma_p->IRQMASK = 0x00;
dma_p->M8 = 0x01;
dma_p->PRIORITY = 0x02;
}
请问ti的工作人员这是为什么?折腾了好久都没找到原因所在
我看到你在英文论坛上发的帖子了。
我在做的东西不需要用到uart,所以有两个dma通道可用,但是根据手册,dma channel 1-4的配置结构体必须是连续的,我在找前两个被用在AES上的结构体在哪里。。
不知道你那儿做的如何了?
你可以先单独测试一下你这个AD的DMA 配置 看正确不 ,就是单独建一个简单的工程 没有协议栈 跟OS的 ,看看 能成不。
能成的话 估计是你的这个初始化跟协议栈的硬件初始化 有冲突了
我这都做完了。 dma chaennel 1-4连续是指 你要一块定义,他们在memory中的地址是要连续的。TI的代码在dma_init 中就定义了所有的dmachannel, 所以你只要把它的地址弄出来 然后写入就行。 相当于往某一个memory中写值。你再搜搜我的帖子,我记得有完整的配置的,包括得到地址
下午把dma channel的init搞定了,不过还没有测试。
我发现你做的东西和我挺像的啊,我是做一个通道的1kHz的12bit采样,然后发送。想问问你最后做出来的结果,四个通道1kHz/8bit的话BLE的速度够用么?
作为非软件相关专业出身从未正式学过任何一门语言刚接触BLE一个多礼拜的某菜鸟,表示从你的帖子里学到了许多,不然的话我连有这么一个官方的adc/dma例程的存在都不知道。
现在正在努力阅读你后面的几个英文post中。
