I have the LPC-link2 that I am using as a development board and using HSADC0. I am using USB0 PLL to generate the 80MHz sampling rate and the base clocks are running at 204MHz. When programming the descriptor tables, I am setting the match value to to '1'. I intend to capture data at 80MHz. It seems like the match value of '1' divides the 80MHz clock by 2. I do not see any overflow interrupts. Setting the match value to '0' causes a descriptor error interrupt as soon as I enable the HSADC interrupts without even updating the descriptor table. My code snippet is pasted below. The match value is set to '1' in it. When I set the value to '0', as soon as the execution comes to the line
"NVIC_EnableIRQ(ADCHS_IRQn)", it goes in to the ADC interrupt handler next. Please advise.
static void initHSADC() {
// Setup FIFO trip points for interrupt/DMA to 8 samples, packing
Chip_HSADC_SetupFIFO(LPC_ADCHS, 8, true);
// Software trigger only, 0x90 recovery clocks, do not add channel Info to FIFO entry
Chip_HSADC_ConfigureTrigger(LPC_ADCHS, HSADC_CONFIG_TRIGGER_SW,
HSADC_CONFIG_TRIGGER_RISEEXT, HSADC_CONFIG_TRIGGER_NOEXTSYNC,
HSADC_CHANNEL_ID_EN_NONE, 0x90);
// Enable negative pin bias and disable ADCHS 0 bias
Chip_HSADC_SetACDCBias(LPC_ADCHS, 0, HSADC_CHANNEL_DCBIAS,
HSADC_CHANNEL_NODCBIAS);
// Setup data format for 2's complement and set power and speed values for the set fADC
Chip_HSADC_SetPowerSpeed(LPC_ADCHS, true);
// Enable HSADC power
Chip_HSADC_EnablePower(LPC_ADCHS);
// table 0 : mapped to input 0, match time to 1, reset timer, branch to next descriptor, no threshold detection
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 0, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 1, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 2, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 3, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 4, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 5, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 6, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 7, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_FIRST |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
// Setup HSADC interrupts on group 0 - FIFO trip (full), FIFO overrun error, and descriptor status error
Chip_HSADC_EnableInts(LPC_ADCHS, 0, (HSADC_INT0_FIFO_FULL | HSADC_INT0_DSCR_ERROR | HSADC_INT0_FIFO_OVERFLOW));
// Enable HSADC interrupts in NVIC
NVIC_DisableIRQ(ADCHS_IRQn);
NVIC_SetPriority(ADCHS_IRQn, 0x2);
NVIC_EnableIRQ(ADCHS_IRQn);
// Update descriptor tables
Chip_HSADC_UpdateDescTable(LPC_ADCHS, 0);
}
Hi ravi thakur,
Thank you jeremy for the reply. I am trying to use the LPC-link2 as a development board for the LPC4370. I need to run the HSADC at 80 MHz sampling rate. Currently I have the following set up, the system base clock is 204 MHz, HSADC base clock is 204 MHz and the sampling clock is 80 MHz. In the code snippet above, I have the descriptor table setup shown and I have the match counter as '1'. I believe this will cause the sampling rate to be 40 MHz effective because the counter starts from '0'. Am I correct about that?
I changed the match value to '0' and when I am stepping through the function I posted, as soon as I enable the HSADC IRq, I see it fire and the execution goes in to the interrupt handler. Even though I am enabling on the fifo fill level interrupt, descriptor error interrupt and fifo overflow interrupt. Is a match value of '0' illegal? If it is, then how can I get 80 MHz sampling rate. If a match value of '0' is allowed, then what is causing this firing of the interrupt? Please advise
Hi ravi thakur,
Thanks for your reply.
The rate of ADC conversation is determined by the fADC , a conversation will take one clock cycle and you can use the BASE_ADCHS_CLK register to configure it.
However the Match value likes time stamp, the ADC will start convert the input signal when the descriptor timer equals field Match value.
Hope this is clear.
Thank you for the explanation. Is a match value of '0' legal? Can you recommend the clock and HSADC descriptor table values to get samples at 80 MHz rate. I am unable to do so currently.
Hi Ravi thakur,
Thanks your reply.
You can follow this steps to achieve your goal.
1. Setup up the BASE_ADCHS_CLK: 80 MHz in ADCHS initialization.
2. Descriptors setting:
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 0, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 1, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 2, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 3, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 4, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 5, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 6, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_NEXT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 7, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_FIRST |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE|
HSADC_DESC_RESET_TIMER));
3 Trigger the HSADC to get it start.
Hope this is clear.
Thank you for the reply. But won't the match value set to '1' effectively divide the fADC by 2, giving you samples at 40MHz instead of 80MHz?
Hi ravi thakur,
Thanks for your.
1 But won't the match value set to '1' effectively divide the fADC by 2, giving you samples at 40MHz instead of 80MHz?
No, I don't think so, as the HSADC will convert the input signal when descriptor timer value equals 1, and descriptor timer also operates at the HSADC cloc kfrequency (fADC).
Hope this is clear.
I was able to get 80 MHz sampling by following the code in the following link
labtool/capture_vadc.c at master · embeddedartists/labtool · GitHub
Line 656 adds a descriptor to table 1, this is to prevent the automatic start when the match value is set to 0. The comment talks about a "Appendix A Errata" which I was unable to find.
Hi ravi thakur,
Thanks for your sharing.
If the reset value for the match counter is 0 and it has to count to 1 to convert a sample. That is dividing the fADC in half. In the following forum post, a user says that he set the match counter to 0 to get his desired sampling rate
https://community.nxp.com/thread/429528
When I set it to 0, the execution of the code is not as expected. Is there a "issue" with setting match counter to 0?
The match number must be 0 to achieve the 80msps. However, there is a problem setting the match number to 0 in the initial descriptor, so the initial descriptor must have a match number other than 0.
in the thread How to achieve 80MHz using DMA from LPC4370's HSADC? I put a sample of the descriptors to do this.
Here is the sample.
/* Select Table 0 desccriptor 1 */
LPC_ADCHS->DSCR_STS = (1 << 1)| 0;
/* Set descriptor 0 to take a measurement at every clock and branch to itself*/
LPC_ADCHS->DESCRIPTOR[0][0] = (1 << 24) /* RESET_TIMER*/ | (0 << 22) /* THRESH*/ | (0x00 << 8) /* MATCH*/ | (1 << 6) /* BRANCH to First*/;
/* 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*/ | (0x9A << 8) /* MATCH*/ | (0x01 << 6) /* BRANCH to first*/;