Why can't I set the transfer size of DMA

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why can't I set the transfer size of DMA

1,016 Views
ALOONG
Contributor I

I learned to combine HSADC and DMA for data transmission, I tried to modify the DMA transmission data size, but has not been successful, the transmission of data has been 4095, which is why, if you know, I am here to thank you first, the followingWhy can't I set the transfer size of DMA my code:

 

void ADCHS_DMA_init(void)
{
////////////////////////////////// ADCHS采样频率设置///// ///////////////////////////////////////////////////// ///////// /*80M*/
Chip_USB0_Init();/*将USB0 PLL初始化为480 MHz */
Chip_Clock_SetDivider(CLK_IDIV_A,CLKIN_USBPLL,2); /*来自USB0PLL的DIV_A源,并将分频器设置为2(支持的最大div值为4)[IN 480 MHz;输出240 MHz */
Chip_Clock_SetDivider(CLK_IDIV_B,CLKIN_IDIVA,3); /*来自DIV_A的源DIV_B,[IN 240 MHz;输出80 MHz */
Chip_Clock_SetBaseClock(CLK_BASE_ADCHS, CLKIN_IDIVB, true, false); /* Source ADHCS base clock from DIV_B */
freqHSADC = Chip_HSADC_GetBaseClockRate(LPC_ADCHS);
Chip_Clock_EnableOpts(CLK_MX_ADCHS, true, true, 1);/*启用寄存器时钟*/
Chip_Clock_Enable(CLK_ADCHS); /*启用时钟*/


////////////////////////////////// HSADC设置///// ///////////////////////////////////////////////////// /////////
// /* 中断设置 */
// LPC_ADCHS-> INTS [0] .CLR_EN = 0x7F; //禁用中断0
// LPC_ADCHS-> INTS [0] .CLR_STAT = 0x7F; //清除中断状态
// while(LPC_ADCHS-> INTS [0] .STATUS&0x7D); //等待状态清除,必须排除FIFO_EMPTY
// LPC_ADCHS-> INTS [1] .CLR_EN = 0x7F;
// LPC_ADCHS-> INTS [1] .CLR_STAT = 0x7F;
// while(LPC_ADCHS-> INTS [1] .STATUS&0x1E);

/*初始化HSADC */
Chip_RGU_TriggerReset(RGU_ADCHS_RST);//复位HADC
while (Chip_RGU_InReset(RGU_ADCHS_RST)){}

LPC_ADCHS-> POWER_DOWN = 0; //禁用电源关闭模式

/* FIFO 中断 1, 无 打包模式 */
//Chip_HSADC_SetupFIFO(LPC_ADCHS, 1, false);

LPC_ADCHS-> FIFO_CFG =(1 << 1); /* FIFO_LEVEL大小PACKED_READ 数据保存在FIFO的方式,0=在一个32位读周期中封装一个样本,1=表示两个采样数据打包存放 */
//当FIFO包含多于或等于FIFO_LEVEL的样本时,中断标志FIFO_FULL中断将被设置,DMA_Read_Req将被引发。可编程的最大阈值是15个单词。注意FIFO最多可以包含16个字。
LPC_ADCHS-> DSCR_STS = (0 << 1)| 0; //设置活动的描述符表与描述符(表1)

/* 设置描述符表0中的描述符0*/
LPC_ADCHS->DESCRIPTOR[0][0] = (1 << 31)
| (1 << 24) /* RESET_TIMER 复位定时器*/
| (0 << 22) /* THRESH 未添加比较器*/
| (0x95 << /* MATCH 描述符计时器值等于MATC时,转换描述符*/
| (1 << 6) /* BRANCH to First 转换完成后跳转到该表第一个描述符*/;
descrip0 =LPC_ADCHS->DESCRIPTOR[0][0] ;
// /* Set descriptor 1 to take a measurement after 0x9A clocks and branch to first descriptor*/
// LPC_ADCHS->DESCRIPTOR[0][1] =(1 << 31) /* UPDATE TABLE*/ //最高位配置不上
// | (1 << 24) /* RESET_TIMER*/
// | (0 << 22) /* THRESH*/
// | (1 << /* MATCH*/
// | (0x01 << 6) /* BRANCH to first*/;
// //| (0x01 << 5);
// descrip1 =LPC_ADCHS->DESCRIPTOR[0][1] ;
LPC_ADCHS-> CONFIG =(0x90 << 6)/*ADC断电后恢复时间,建议值*/
| (0 << 5)/* CHANNEL_ID_EN ,0表示不将通道ID输入到FIFO中*/
| (0x01)/* TRIGGER_MASK 01 表示仅使用软件触发*/;

/* CRS设置为0x4,所以SPEED所有DGEC应该被设置为0xE(80MHz) */
LPC_ADCHS-> ADC_SPEED =(0xE << 20)
| (0xE << 16)
| (0xE << 12)
| (0xE <<
| (0xE << 4)
| (0xE);

//未设置阈值寄存器,因为未使用它们
LPC_ADCHS->POWER_CONTROL =(1 << 18)/* BGAP 带隙基准*/
|(1 << 17)/*电源 ADC保持供电*/
|(1 << 4) /* DCINNEG在ADC0 No dc bias 当 DCINNEG 设置为 0 时,提供 ADCHS_NEG 引脚上的电压(ADCHS 用于真差分模式):*/
|(0 << 10)/* DC在ADC0中 No dc bias*/
|(1 << 16)/* 1 =以TWOS输出-0 =以Offset Binary输出*/
|(0x4)/* CRS ,设置ADC速度 0x0->20M 0x1->30M 0x2->50M 0x3->65M 0x4->80M*/;

LPC_ADCHS-> FLUSH = 1; //FIFO刷新


///////////////////////////////////////////////////// //// DMA设置///////////////////////////////////////////// ///////////////////////
NVIC_DisableIRQ(DMA_IRQn);
Chip_GPDMA_Init(LPC_GPDMA);

//LPC_GPDMA-> CH [7] .CONFIG &=~(0x01<<0); //启用位,1启用,0禁用
/* Clear all DMA interrupt and error flag */
LPC_GPDMA->INTTCCLEAR |= ((1UL <<7 ) & 0xFF);//clears the corresponding channel terminal count interrupt.清除相应的通道终端计数中断。
LPC_GPDMA->INTERRCLR |= ((1UL <<7 ) & 0xFF);//clears the corresponding channel error interrupt.清除相应的通道错误中断。

LPC_GPDMA-> CONFIG = 0x01;// DMA Controller enable.DMA控制器启用。
while(!(LPC_GPDMA-> CONFIG&0x01)); //使能

/* 描述符寄存器的值仅能通过DMA通道7传递 */
LPC_GPDMA-> CH[7].SRCADDR =(uint32_t)&LPC_ADCHS-> FIFO_OUTPUT [0];//DMA源地址
//LPC_GPDMA-> CH[7].SRCADDR = (uint32_t)&LPC_ADCHS->LAST_SAMPLE[0];
LPC_GPDMA-> CH[7].DESTADDR =((uint32_t)&sample);//DMA目标地址

LPC_GPDMA->CH[7].CONFIG = (0x1 << 0)
| (8 << 1)// src外设:设置为8-HSADC
| (0x0 << 6)// dst外设:无设置-内存
| (0x6 << 11)//流控制:外设-存储器(外设控制)
| (0x1 << 14); // IE-中断错误掩码
//| (0x1 << 15);
// ITC-终端计数中断屏蔽
//| (0x1 << 0);// enable bit: 1 enable, 0 disable
//| (0x0 << 16)//锁定:置位时,此位启用锁定传输
//| (0x1 << 18); //进一步忽略src DMA req
config =LPC_GPDMA-> CH [7] .CONFIG;

LPC_GPDMA-> CH[7].CONTROL =(32)//传输大小
| (0x0 << 12)// src突发大小
| (0x0 << 15)// dst突发大小
| (0x2 << 18)// src传输宽度,0x2表示以字的形式传输
| (0x2 << 21)// dst传输宽度,0x2表示以字的形式传输
| (0x1 << 24)// src AHB主选择
| (0x0 << 25)// dst AHB主选择
| (0x0 << 26)// src增量:0,每次传输后src地址不递增
| (0x1 << 27)// dst增量:1,每次传输后的dst地址增量
| (0x1 << 31); //终端计数中断使能位:1,使能

LPC_GPDMA-> CH [7] .LLI = 0;

LPC_CREG->DMAMUX=3<<16; //select HSADC read for DMAMUXPER8. Select DMA to peripheral connection for DMA peripheral 8.
// LPC_GPDMA-> CH [7] .LLI = 0;
// NVIC_EnableIRQ(DMA_IRQn);
// config =LPC_GPDMA-> CH [7] .CONFIG;
// LPC_GPDMA-> CH [7].CONFIG |= (0x1 << 0);//启用位,1启用,0禁用
Chip_HSADC_SWTrigger(LPC_ADCHS);//启动ADCHS软件触发

//不配置就无法读取到数据,但会覆盖之前的配置
NVIC_SetPriority(DMA_IRQn,0x00);//优先级
NVIC_ClearPendingIRQ(DMA_IRQn);//清中断
NVIC_EnableIRQ(DMA_IRQn);//使能中断

__asm("cpsie i");
}

Labels (1)
0 Kudos
Reply
6 Replies

988 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello @ALOONG 

There is an HSADC+DMA demo. I recommend that you refer to it first. Please see Xiangjun Rong's reply in the following thread:

https://community.nxp.com/t5/LPC-Microcontrollers/LPC43XX-HSADC-DMA-how-to/m-p/1938925 

 

BR

Alice

0 Kudos
Reply

976 Views
ALOONG
Contributor I

Thank you very much Alice_Yang,I have referred to his code, but it is still not solved after testing.

0 Kudos
Reply

958 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello @ALOONG 

Does the code on that thread can works well on your side?

What is the main issue that your project is confronted with now?

BR

Alice

0 Kudos
Reply

911 Views
ALOONG
Contributor I

hello Alice_Yang

At present, it can work normally, but there are new problems, I don't know how to determine whether my collection rate has reached the set 80MHZ.

Do you have any good suggestions, thank you.

BR

Alice

0 Kudos
Reply

909 Views
ALOONG
Contributor I

If I test by pulling the pin up and down, I pull the pin up before enabling DMA, pull the pin down when DMA is interrupted, and measure this period of time to determine whether the acquisition rate is reliable?

0 Kudos
Reply

896 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello @ALOONG 

This method can only be used for rough testing and is not accurate, because the GPIO toggle cannot be synchronized with the start and end of ADC sampling. Alternatively, you can input a signal with a constant frequency into the ADC and then compare the output signal of the ADC with the input signal.

 

BR

Alice

0 Kudos
Reply