基于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中。