Hi,
My first intention was to clock the adc in such way that it has a sample every 1ms. If it where possible i could have the dma controller handle the whole data aquisition without having to look at it.
and not waste cpu at all.
Due to the factor 65 (clock cycles/conversion) using clocking the adc isn't an option as you cannot get a 65fold by dividing the cpu clock of 96MHz or 100Mhz.
So I resorted to a timer interrupt which periodically sets up a single dma transfer for a number of adc channels. The result is near xtal timing (inter sample timing is nearly perfect). This way i only have a single interrupt to handle (the dma handles the adc interrupt for me).
By decimating the data adaptively I can also vary the sample time during the data aquisition as needed (our measurement consists of two periods each of which must have a certain amout of samples at regular intervals so we can integrate the signal later).
Switching to a real-time OS is a big step for this project (however tempting) and my experiences with it (and solving/preventing deadlocks) date back to my university years some 30 years back now. Furthermore, as the mBed is tighly controller by a PC app, there is not much need for concurreny of tasks.
BUT i will download scmRTOS and play with it (for old time sake ;-), so thanks for mentioning it.
regards
Wim
Hi,
I'm puzzled about how to hardware trigger the ADC (in burst mode) from a Timer1 Match.
I tried Andy's DMA which worked like charm but has drawbacks on getting nice intervals as the conversion time is 65 cycles and the clock is derived from 96Mhz you cannot get an exact int number of ms for timing.
So my next bet is either Timer1 or the Repetitive Timer.
So the question: how do i connect this code to trigger the ADC in burst mode (need to convert two channels). I know I can software trigger from inside the timer interrupt routine but I would like to remove the timer interrupt handler al together and have the adc triggered by hardware.
Got the following code (ripped from a larger program) that I wrote to verify timer1 timing. I verified that it does have a nearly exact 10ms interval I want.
//------------------------------------------------------------------------------ //----TIMER1. //------------------------------------------------------------------------------ volatile unsigned int timer1hits = 0; //timer1 stops when timer1hits==imer1loop unsigned long match = 10000-1; //10ms (1Mhz/10000) unsigned int timer1loop = 1000; //nosamples unsigned long prescaler = 96-1; //96Mhz/96 = 1Mhz //Resulting timing 1000 hits 9999.99900 ms. //Ideal 10000.00000 ms ie a -0,001 % deviation Timer match_timing; //DigitalOut cap_led(LED2); void Timer1_IRQHandler(void) { LPC_TIM1->MR0 = match; LPC_TIM1->IR = 1; //cap_led=!cap_led; timer1hits++; //TODO Debug Code (stop after timer1loop samples)... if (timer1hits==timer1loop) { match_timing.stop(); LPC_TIM1->TCR = 0; // Disable Timer } }This is called from a modified piece of code found on this forum:
// Enable the ISR vector NVIC_SetVector (TIMER1_IRQn, (uint32_t)&Timer1_IRQHandler); NVIC_EnableIRQ(TIMER1_IRQn); // Set PCLK_TIMER1 // PCLK_TIMER1 = CCLK/1 96M/1 = 96MHz LPC_SC->PCLKSEL0 &= ~(3UL << 4); //clear bits LPC_SC->PCLKSEL0 |= (1UL << 4); //set bit //Reset Test Variable. timer1hits = 0; LPC_SC->PCONP |= 1 << 2; // Power on Timer 1 LPC_TIM1->TCR = 0x2UL; // Reset and set to timer mode LPC_TIM1->CTCR = 0x0; // Connect to prescaler LPC_TIM1->PR = prescaler; // Prescale -> 1Mhz LPC_TIM1->MR0 = match; // Match count for 10mS LPC_TIM1->MCR = 3; // Interrupt and Reset on Match LPC_TIM1->TCR = 0x1UL; // Enable Timer match_timing.start(); //Pause 10 seconds. while (LPC_TIM1->TCR==1) { // wait(0.1); } //Moved code to interrupt routine. //LPC_TIM1->TCR = 0; // Disable Timer //match_timing.stop(); printf("%d hits\r\n", timer1hits); printf("%f ms\r\n", 0.001*match_timing.read_us()); match_timing.reset(); }