I'm using the LPC4370 with HSADC and DMA. I've configured the sampling rate for 80MHz, but the actual measured rate is only around 15MHz.
How can I achieve the expected 80MHz sampling rate?
I've attached my code below. Any insights would be greatly appreciated!
void ADCHS_DMA_init(void)
{
////////////////////////////////// ADCHS ///// //////////////////////////////// ///////// /*80M*/
Chip_USB0_Init();
Chip_Clock_SetDivider(CLK_IDIV_A,CLKIN_USBPLL,2);
Chip_Clock_SetDivider(CLK_IDIV_B,CLKIN_IDIVA,3);
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 ///// /////////////////////////////////////// /////////
Chip_RGU_TriggerReset(RGU_ADCHS_RST);
while (Chip_RGU_InReset(RGU_ADCHS_RST)){}
LPC_ADCHS-> POWER_DOWN = 0;
LPC_ADCHS-> FIFO_CFG =(8 << 1);
LPC_ADCHS-> DSCR_STS = (1 << 1)| 0;
LPC_ADCHS->DESCRIPTOR[0][0] = (1 << 24)
| (0 << 22)
| (0 <<
| (1 << 6) ;
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)
| (1 << 24)
| (0 << 22)
| (0 <<
| (0x01 << 6) ;
descrip1 =LPC_ADCHS->DESCRIPTOR[0][1] ;
LPC_ADCHS-> CONFIG =(0x90 << 6)
| (0 << 5)
| (0x01);
LPC_ADCHS-> ADC_SPEED =(DGEC << 20)
| (DGEC << 16)
| (DGEC << 12)
| (DGEC <<
| (DGEC << 4)
| (DGEC);
LPC_ADCHS->POWER_CONTROL =(1 << 18)/* BGAP */
|(1 << 17)
|(0 << 4)
|(0 << 10)
|(1 << 16)
|(0x4);
LPC_ADCHS-> FLUSH = 1;
////////////////////////////////////////////////////// DMA ///////////////////////////////////////////
NVIC_DisableIRQ(DMA_IRQn);
LPC_GPDMA-> CH [DMA_CH] .CONFIG |=0;
LPC_GPDMA->INTTCCLEAR |= ((1UL <<DMA_CH ) & 0xFF);
LPC_GPDMA->INTERRCLR |= ((1UL <<DMA_CH ) & 0xFF);
LPC_GPDMA-> CONFIG = 0x01;
while(!(LPC_GPDMA-> CONFIG&0x01));
LPC_GPDMA-> CH[DMA_CH].SRCADDR =(uint32_t)&LPC_ADCHS-> FIFO_OUTPUT [0];
LPC_GPDMA-> CH[DMA_CH].DESTADDR =((uint32_t)&sample);
LPC_GPDMA-> CH[DMA_CH].CONTROL =(DMA_TRANSFER_SIZE)
| (0x0 << 12)
| (0x0 << 15)
| (0x2 << 18)
| (0x2 << 21)
| (0x1 << 24)
| (0x0 << 25)
| (0x0 << 26)
| (0x1 << 27)
| (0x1 << 31);
LPC_GPDMA->CH[DMA_CH].CONFIG = (HSADC_DMA_READ << 1)
| (0x0 << 6)
| (0x6 << 11)
| (0x1 << 14);
//| (0x1 << 15);
LPC_CREG->DMAMUX=3<<16; //select HSADC read for DMAMUXPER8
LPC_GPDMA-> CH [DMA_CH] .LLI = 0;
config =LPC_GPDMA-> CH [DMA_CH] .CONFIG;
NVIC_SetPriority(DMA_IRQn,0x00);
NVIC_ClearPendingIRQ(DMA_IRQn);
NVIC_EnableIRQ(DMA_IRQn);
__asm("cpsie i");
}
Hello @uaShark,
LPCOpen provides an example project that demonstrates how to use the HSADC. I highly recommend reviewing this example to better understand how the HSADC is configured.
Additionally, this community post suggests linking your code to RAM instead of Flash, as Flash memory typically has higher latency compared to SRAM, which can impact performance.
Finally, this other community post includes an ADC performance test for the LPC4300 series, which might also be helpful.
Hope it helps.
BR
Habib
Hello, @Habib_MS
Thanks for your help, but some questions remain. The HSADC example project in LPCOpen is configured for 12MHz interrupt sampling, but I now need to use 40MHz DMA sampling. My code references the project files provided by xiangjun_rong in this post: community post , but I cannot achieve the target sampling rate.
Moreover, my code is already linked to RAM. Additionally, the second community post you mentioned is about the 10-bit ADC, while I am using the 12-bit HSADC.
Awaiting your response.
uaShark
Hello @uaShark,
I have successfully configured the HSADC to operate at 40 MHz by setting the divider to 6, as illustrated in the image below:
In order to support you better, could you please share how you are calculating the sampling rate on your end?
BR
Habib
Hello, @Habib_MS
Actually, I also successfully configured freqHSADC=80MHz by setting the frequency divider to 3. This value is configured correctly. I also configured DGEC=0xE and CRS=0x4 according to the user manual, but the actual sampling rate doesn't match this value.
Here's how I calculated the sampling rate: During actual measurements, I input a square wave signal with a period of 25us to the HSADC and found that only 850 samples were collected in 25us, giving an actual sampling rate of 34MHz, which doesn't match the freqHSADC setting.
Additionally, I have a question: the current actual sampling rate was achieved after I configured PACKED_READ=1. Before this configuration, the actual sampling rate was only 17MHz. Is it reasonable that this configuration doubles the sampling rate? I'm not sure about this.
Looking forward to your reply!
uaShark
Hi @uaShark,
Sorry for the later reply.
Thank you for showing us the post by xiangjun_rong.
However, since this code is not fully tested, I highly recommend referring to the open-source projects below. both the software and hardware are open source:
• DroidOscillo: https://github.com/aroerina/DroidOscilloFirmaware/tree/master/USB_Scope_M4/src/src
• labtool: https://github.com/embeddedartists/labtool/blob/master/fw/program/source/capture_vadc.c
These codes are a good starting point for the implementation you are aiming for.
Hope it helps.
Habib.
Hello @uaShark. Sorry for the long reply,
I asked internally in order to know more information about the ADCHS functionality, and the code provided by Xiangjun Rong. I appreciate your patience and will get back to you as soon as I get an answer.
BR
Habib.