void tone(uint32_t ulPin, uint32_t frequency, int32_t duration) { const uint32_t rc = VARIANT_MCK / 256 / frequency; tone_pin = ulPin; toggle_count = 0; // strange wipe out previous duration if (duration > 0 ) toggle_count = 2 * frequency * duration / 1000; else toggle_count = -1; if (!TCChanEnabled) { pmc_set_writeprotect(false); pmc_enable_periph_clk((uint32_t)TONE_IRQ); TC_Configure(chTC, chNo, TC_CMR_TCCLKS_TIMER_CLOCK4 | TC_CMR_WAVE | // Waveform mode TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC chTC->TC_CHANNEL[chNo].TC_IER=TC_IER_CPCS; // RC compare interrupt chTC->TC_CHANNEL[chNo].TC_IDR=~TC_IER_CPCS; NVIC_EnableIRQ(TONE_IRQ); TCChanEnabled = 1; } if (!pinEnabled[ulPin]) { pinMode(ulPin, OUTPUT); pinEnabled[ulPin] = 1; } TC_Stop(chTC, chNo); TC_SetRC(chTC, chNo, rc); // set frequency TC_Start(chTC, chNo); }
// Set the frequency (in Hz) DueTimer DueTimer::setFrequency(long frequency){ Timer t = Timers[timer]; uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above TC_SetRA(t.tc, t.channel, rc/2); //50% high, 50% low TC_SetRC(t.tc, t.channel, rc); TC_Start(t.tc, t.channel); t.tc->TC_CHANNEL[t.channel].TC_IER=TC_IER_CPCS; t.tc->TC_CHANNEL[t.channel].TC_IDR=~TC_IER_CPCS; return *this; }
DueTimer& DueTimer::setFrequency(double frequency){ /* Set the timer frequency (in Hz) */ // Prevent negative frequencies if(frequency <= 0) { frequency = 1; } // Remember the frequency — see below how the exact frequency is reported instead //_frequency[timer] = frequency; // Get current timer configuration Timer t = Timers[timer]; uint32_t rc = 0; uint8_t clock; // Tell the Power Management Controller to disable // the write protection of the (Timer/Counter) registers: pmc_set_writeprotect(false); // Enable clock for the timer pmc_enable_periph_clk((uint32_t)t.irq); // Find the best clock for the wanted frequency clock = bestClock(frequency, rc); switch (clock) { case TC_CMR_TCCLKS_TIMER_CLOCK1: _frequency[timer] = (double)VARIANT_MCK / 2.0 / (double)rc; break; case TC_CMR_TCCLKS_TIMER_CLOCK2: _frequency[timer] = (double)VARIANT_MCK / 8.0 / (double)rc; break; case TC_CMR_TCCLKS_TIMER_CLOCK3: _frequency[timer] = (double)VARIANT_MCK / 32.0 / (double)rc; break; default: // TC_CMR_TCCLKS_TIMER_CLOCK4 _frequency[timer] = (double)VARIANT_MCK / 128.0 / (double)rc; break; } // Set up the Timer in waveform mode which creates a PWM // in UP mode with automatic trigger on RC Compare // and sets it up with the determined internal clock as clock input. TC_Configure(t.tc, t.channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | clock); // Reset counter and fire interrupt when RC value is matched: TC_SetRC(t.tc, t.channel, rc); // Enable the RC Compare Interrupt... t.tc->TC_CHANNEL[t.channel].TC_IER=TC_IER_CPCS; // ... and disable all others. t.tc->TC_CHANNEL[t.channel].TC_IDR=~TC_IER_CPCS; return *this; }
void BaseDMD::begin() { beginNoTimer(); // Do any generic setup NVIC_DisableIRQ(TC7_IRQn); register_running_dmd(this); pmc_set_writeprotect(false); pmc_enable_periph_clk(TC7_IRQn); // Timer 7 is TC2, channel 1 TC_Configure(TC2, 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); // counter up, /128 divisor TC_SetRC(TC2, 1, 2500); // approx 4ms at /128 divisor TC2->TC_CHANNEL[1].TC_IER=TC_IER_CPCS; NVIC_ClearPendingIRQ(TC7_IRQn); NVIC_EnableIRQ(TC7_IRQn); TC_Start(TC2, 1); }
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { Tc *tc = TimerConfig[timer_num].pTimerRegs; IRQn_Type irq = TimerConfig[timer_num].IRQ_Id; uint32_t channel = TimerConfig[timer_num].channel; pmc_set_writeprotect(false); pmc_enable_periph_clk((uint32_t)irq); NVIC_SetPriority(irq, TimerConfig [timer_num].priority); TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); TC_SetRC(tc, channel, VARIANT_MCK / 2 / frequency); TC_Start(tc, channel); // enable interrupt on RC compare tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPCS; NVIC_EnableIRQ(irq); }
/*------------------------------------------------------------------------------ Name: startTimer parameters: tc - timer counter channel - timer channel irq - isr request frequency - frequency of inetrrupts description: initializes timer for periodic interrupt generation ------------------------------------------------------------------------------*/ void BldcControl::configureTimerInterrupt(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) { pmc_set_writeprotect(false); pmc_enable_periph_clk((uint32_t)irq); TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected //TIMER_CLOCK4 above TC_SetRA(tc, channel, rc/2); //50% high, 50% low TC_SetRC(tc, channel, rc); TC_Start(tc, channel); tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS; tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS; NVIC_EnableIRQ(irq); }
// Set up all timer interrupts void HAL::setupTimer() { uint32_t tc_count, tc_clock; pmc_set_writeprotect(false); // set 3 bits for interrupt group priority, 1 bits for sub-priority //NVIC_SetPriorityGrouping(4); #if USE_ADVANCE // Timer for extruder control pmc_enable_periph_clk(EXTRUDER_TIMER_IRQ); // enable power to timer //NVIC_SetPriority((IRQn_Type)EXTRUDER_TIMER_IRQ, NVIC_EncodePriority(4, 4, 1)); NVIC_SetPriority((IRQn_Type)EXTRUDER_TIMER_IRQ, 6); // count up to value in RC register using given clock TC_Configure(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK3); TC_SetRC(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL, (F_CPU_TRUE / 32) / EXTRUDER_CLOCK_FREQ); // set frequency 43 for 60000Hz TC_Start(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL); // start timer running // enable RC compare interrupt EXTRUDER_TIMER->TC_CHANNEL[EXTRUDER_TIMER_CHANNEL].TC_IER = TC_IER_CPCS; // clear the "disable RC compare" interrupt EXTRUDER_TIMER->TC_CHANNEL[EXTRUDER_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS; // allow interrupts on timer NVIC_EnableIRQ((IRQn_Type)EXTRUDER_TIMER_IRQ); #endif // Regular interrupts for heater control etc pmc_enable_periph_clk(PWM_TIMER_IRQ); //NVIC_SetPriority((IRQn_Type)PWM_TIMER_IRQ, NVIC_EncodePriority(4, 6, 0)); NVIC_SetPriority((IRQn_Type)PWM_TIMER_IRQ, 15); TC_FindMckDivisor(PWM_CLOCK_FREQ, F_CPU_TRUE, &tc_count, &tc_clock, F_CPU_TRUE); TC_Configure(PWM_TIMER, PWM_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | tc_clock); TC_SetRC(PWM_TIMER, PWM_TIMER_CHANNEL, (F_CPU_TRUE / tc_count) / PWM_CLOCK_FREQ); TC_Start(PWM_TIMER, PWM_TIMER_CHANNEL); PWM_TIMER->TC_CHANNEL[PWM_TIMER_CHANNEL].TC_IER = TC_IER_CPCS; PWM_TIMER->TC_CHANNEL[PWM_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS; NVIC_EnableIRQ((IRQn_Type)PWM_TIMER_IRQ); // Timer for stepper motor control pmc_enable_periph_clk(TIMER1_TIMER_IRQ ); //NVIC_SetPriority((IRQn_Type)TIMER1_TIMER_IRQ, NVIC_EncodePriority(4, 7, 1)); // highest priority - no surprises here wanted NVIC_SetPriority((IRQn_Type)TIMER1_TIMER_IRQ,2); // highest priority - no surprises here wanted TC_Configure(TIMER1_TIMER, TIMER1_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1); TC_SetRC(TIMER1_TIMER, TIMER1_TIMER_CHANNEL, (F_CPU_TRUE / TIMER1_PRESCALE) / TIMER1_CLOCK_FREQ); TC_Start(TIMER1_TIMER, TIMER1_TIMER_CHANNEL); TIMER1_TIMER->TC_CHANNEL[TIMER1_TIMER_CHANNEL].TC_IER = TC_IER_CPCS; TIMER1_TIMER->TC_CHANNEL[TIMER1_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS; NVIC_EnableIRQ((IRQn_Type)TIMER1_TIMER_IRQ); // Servo control #if FEATURE_SERVO #if SERVO0_PIN > -1 SET_OUTPUT(SERVO0_PIN); WRITE(SERVO0_PIN, LOW); #endif #if SERVO1_PIN > -1 SET_OUTPUT(SERVO1_PIN); WRITE(SERVO1_PIN, LOW); #endif #if SERVO2_PIN > -1 SET_OUTPUT(SERVO2_PIN); WRITE(SERVO2_PIN, LOW); #endif #if SERVO3_PIN > -1 SET_OUTPUT(SERVO3_PIN); WRITE(SERVO3_PIN, LOW); #endif pmc_enable_periph_clk(SERVO_TIMER_IRQ ); //NVIC_SetPriority((IRQn_Type)SERVO_TIMER_IRQ, NVIC_EncodePriority(4, 5, 0)); NVIC_SetPriority((IRQn_Type)SERVO_TIMER_IRQ,4); TC_Configure(SERVO_TIMER, SERVO_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1); TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL, (F_CPU_TRUE / SERVO_PRESCALE) / SERVO_CLOCK_FREQ); TC_Start(SERVO_TIMER, SERVO_TIMER_CHANNEL); SERVO_TIMER->TC_CHANNEL[SERVO_TIMER_CHANNEL].TC_IER = TC_IER_CPCS; SERVO_TIMER->TC_CHANNEL[SERVO_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS; NVIC_EnableIRQ((IRQn_Type)SERVO_TIMER_IRQ); #endif }
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) { uint8_t prescalarbits = 0b001; long toggle_count = 0; uint32_t ocr = 0; int8_t _timer; _timer = toneBegin(_pin); if (_timer >= 0) { // Set the pinMode as OUTPUT pinMode(_pin, OUTPUT); // if we are using an 8 bit timer, scan through prescalars to find the best fit if (_timer == 0 || _timer == 2) { ocr = F_CPU / frequency / 2 - 1; prescalarbits = 0b001; // ck/1: same for both timers if (ocr > 255) { ocr = F_CPU / frequency / 2 / 8 - 1; prescalarbits = 0b010; // ck/8: same for both timers if (_timer == 2 && ocr > 255) { ocr = F_CPU / frequency / 2 / 32 - 1; prescalarbits = 0b011; } if (ocr > 255) { ocr = F_CPU / frequency / 2 / 64 - 1; prescalarbits = _timer == 0 ? 0b011 : 0b100; if (_timer == 2 && ocr > 255) { ocr = F_CPU / frequency / 2 / 128 - 1; prescalarbits = 0b101; } if (ocr > 255) { ocr = F_CPU / frequency / 2 / 256 - 1; prescalarbits = _timer == 0 ? 0b100 : 0b110; if (ocr > 255) { // can't do any better than /1024 ocr = F_CPU / frequency / 2 / 1024 - 1; prescalarbits = _timer == 0 ? 0b101 : 0b111; } } } } #if defined(TCCR0B) if (_timer == 0) { TCCR0B = prescalarbits; } else #endif #if defined(TCCR2B) { TCCR2B = prescalarbits; } #else { // dummy place holder to make the above ifdefs work } #endif } else { // two choices for the 16 bit timers: ck/1 or ck/64 ocr = F_CPU / frequency / 2 - 1; prescalarbits = 0b001; if (ocr > 0xffff) { ocr = F_CPU / frequency / 2 / 64 - 1; prescalarbits = 0b011; } if (_timer == 1) { #if defined(TCCR1B) TCCR1B = (TCCR1B & 0b11111000) | prescalarbits; #endif } #if defined(TCCR3B) else if (_timer == 3) TCCR3B = (TCCR3B & 0b11111000) | prescalarbits; #endif #if defined(TCCR4B) else if (_timer == 4) TCCR4B = (TCCR4B & 0b11111000) | prescalarbits; #endif #if defined(TCCR5B) else if (_timer == 5) TCCR5B = (TCCR5B & 0b11111000) | prescalarbits; #endif } // Calculate the toggle count if (duration > 0) { toggle_count = 2 * frequency * duration / 1000; } else { toggle_count = -1; } // Set the OCR for the given timer, // set the toggle count, // then turn on the interrupts switch (_timer) { #if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A) case 0: OCR0A = ocr; timer0_toggle_count = toggle_count; bitWrite(TIMSK0, OCIE0A, 1); break; #endif case 1: #if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A) OCR1A = ocr; timer1_toggle_count = toggle_count; bitWrite(TIMSK1, OCIE1A, 1); #elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A) // this combination is for at least the ATmega32 OCR1A = ocr; timer1_toggle_count = toggle_count; bitWrite(TIMSK, OCIE1A, 1); #endif break; #if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A) case 2: OCR2A = ocr; timer2_toggle_count = toggle_count; bitWrite(TIMSK2, OCIE2A, 1); break; #endif #if defined(TIMSK3) case 3: OCR3A = ocr; timer3_toggle_count = toggle_count; bitWrite(TIMSK3, OCIE3A, 1); break; #endif #if defined(TIMSK4) case 4: OCR4A = ocr; timer4_toggle_count = toggle_count; bitWrite(TIMSK4, OCIE4A, 1); break; #endif #if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A) case 5: OCR5A = ocr; timer5_toggle_count = toggle_count; bitWrite(TIMSK5, OCIE5A, 1); break; #endif #if defined(TC0) && defined(TC1) && defined(TC2) case 6: ocr = VARIANT_MCK / 256 / frequency; TC_Stop(TC1, 0); TC_SetRC(TC1, 0, ocr); TC_Start(TC1, 0); timer6_toggle_count = toggle_count; break; #endif } } }
void HAL_timer_set_count(const uint8_t timer_num, const uint32_t count) { const tTimerConfig *pConfig = &TimerConfig[timer_num]; TC_SetRC(pConfig->pTimerRegs, pConfig->channel, count); }
void DACClass::begin(uint32_t period) { // Enable clock for DAC pmc_enable_periph_clk(dacId); dacc_reset(dac); // Set transfer mode to double word dacc_set_transfer_mode(dac, 1); // Power save: // sleep mode - 0 (disabled) // fast wakeup - 0 (disabled) dacc_set_power_save(dac, 0, 0); // DAC refresh/startup timings: // refresh - 0x08 (1024*8 dacc clocks) // max speed mode - 0 (disabled) // startup time - 0x10 (1024 dacc clocks) dacc_set_timing(dac, 0x08, 0, DACC_MR_STARTUP_1024); // Flexible channel selection with tags dacc_enable_flexible_selection(dac); // Set up analog current dacc_set_analog_control(dac, DACC_ACR_IBCTLCH0(0x02) | DACC_ACR_IBCTLCH1(0x02) | DACC_ACR_IBCTLDACCORE(0x01)); // Enable output channels dacc_enable_channel(dac, 0); dacc_enable_channel(dac, 1); // Configure Timer Counter to trigger DAC // -------------------------------------- pmc_enable_periph_clk(ID_TC1); TC_Configure(TC0, 1, TC_CMR_TCCLKS_TIMER_CLOCK2 | // Clock at MCR/8 TC_CMR_WAVE | // Waveform mode TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR); const uint32_t TC = period / 8; TC_SetRA(TC0, 1, TC / 2); TC_SetRC(TC0, 1, TC); TC_Start(TC0, 1); // Configure clock source for DAC (2 = TC0 Output Chan. 1) dacc_set_trigger(dac, 2); // Configure pins PIO_Configure(g_APinDescription[DAC0].pPort, g_APinDescription[DAC0].ulPinType, g_APinDescription[DAC0].ulPin, g_APinDescription[DAC0].ulPinConfiguration); PIO_Configure(g_APinDescription[DAC1].pPort, g_APinDescription[DAC1].ulPinType, g_APinDescription[DAC1].ulPin, g_APinDescription[DAC1].ulPinConfiguration); // Enable interrupt controller for DAC dacc_disable_interrupt(dac, 0xFFFFFFFF); NVIC_DisableIRQ(isrId); NVIC_ClearPendingIRQ(isrId); NVIC_SetPriority(isrId, 0); NVIC_EnableIRQ(isrId); }
void ADCSampler::begin(unsigned int samplingRate) { this->sampleingRate = sampleingRate; // Turning devices Timer on. pmc_enable_periph_clk(ID_TC0); // Configure timer TC_Configure(TC0, 0, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET | TC_CMR_ASWTRG_CLEAR | TC_CMR_TCCLKS_TIMER_CLOCK1); // It is good to have the timer 0 on PIN2, good for Debugging //int result = PIO_Configure( PIOB, PIO_PERIPH_B, PIO_PB25B_TIOA0, PIO_DEFAULT); // Configure ADC pin A7 // the below code is taken from adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST); ADC->ADC_CR = ADC_CR_SWRST; // Reset the controller. ADC->ADC_MR = 0; // Reset Mode Register. ADC->ADC_PTCR = (ADC_PTCR_RXTDIS | ADC_PTCR_TXTDIS); // Reset PDC transfer. ADC->ADC_MR |= ADC_MR_PRESCAL(3); // ADC clock = MSCK/((PRESCAL+1)*2), 13 -> 750000 Sps ADC->ADC_MR |= ADC_MR_STARTUP_SUT0; // What is this by the way? ADC->ADC_MR |= ADC_MR_TRACKTIM(15); ADC->ADC_MR |= ADC_MR_TRANSFER(1); ADC->ADC_MR |= ADC_MR_TRGEN_EN; // Hardware trigger selected by TRGSEL field is enabled. Включен аппаратный триггер, выбранный по полю TRGSEL. ADC->ADC_MR |= ADC_MR_TRGSEL_ADC_TRIG1; // selecting TIOA0 as trigger. ADC->ADC_MR |= ADC_MR_LOWRES_BITS_12; // brief (ADC_MR) 12-bit resolution //ADC->ADC_ACR |= ADC_ACR_TSON; // Включить датчик температуры ADC->ADC_CHER = ADC_CHANNELS; // Записать контролируемые входа ADC->ADC_CHDR = ADC_CHANNELS_DIS; // Отключить не используемые входа ADC->ADC_EMR = ADC_EMR_CMPMODE_IN // Генерирует событие, когда преобразованные данные пересекают окно сравнения. // | ADC_EMR_CMPSEL(4) // Compare channel 4 = A3 | ADC_EMR_CMPALL // Compare ALL channel | ADC_EMR_CMPFILTER(0); // Количество последовательных событий сравнения, необходимых для повышения флага = CMPFILTER + 1 // При запрограммированном значении 0 флаг увеличивается, как только происходит событие. ADC->ADC_CWR = ADC_CWR_LOWTHRES(_compare_Low) | ADC_CWR_HIGHTHRES(_compare_High); // Установить высокий и низкий порог компаратора АЦП //ADC->ADC_SEQR1 = 0x01234567; // использовать A0 до A7 в порядке в массив //ADC->ADC_SEQR2 = 0x00dcba00; // использовать для А8 А11 следующие действия по порядку в массив /* Interupts */ ADC->ADC_IDR = ~ADC_IDR_ENDRX; // сбросить регистры прерывания по готовности данных. ADC->ADC_IDR = ~ADC_IDR_COMPE; // сбросить регистры копаратора. ADC->ADC_IER = ADC_IER_ENDRX; // Включить прерывание по готовности данных. // ADC->ADC_IER = ADC_IER_COMPE; // Прерывание по совпадению сравнения компаратором ADC->ADC_ISR = ~ADC_ISR_COMPE; // ADC Interrupt Status Register Обнулить ошибку сравнения с момента последнего чтения ADC_ISR. /* Waiting for ENDRX as end of the transfer is set when the current DMA transfer is done (RCR = 0), i.e. it doesn't include the next DMA transfer. If we trigger on RXBUFF This flag is set if there is no more DMA transfer in progress (RCR = RNCR = 0). Hence we may miss samples. Ожидание окончания ENDRX в конце передачи когда выполняется текущая передача DMA (RCR = 0), то есть она не включает следующая передача DMA. Если мы запускаем RXBUFF, этот флаг устанавливается, если больше нет передачи DMA в прогресс (RCR = RNCR = 0). Следовательно, мы можем пропустить образцы. */ unsigned int cycles = 42000000 / samplingRate; /* timing of ADC */ TC_SetRC(TC0, 0, cycles); // TIOA0 goes HIGH on RC. TC_SetRA(TC0, 0, cycles / 2); // TIOA0 goes LOW on RA. // We have to reinitalise just in case the Sampler is stopped and restarted... // Мы должны приступить к реинициализировать на случай, если Sampler остановлен и перезапущен ... dataReady = false; dataHigh = false; // Признак срабатывания компаратора adcDMAIndex = 0; adcTransferIndex = 0; for (int i = 0; i < NUMBER_OF_BUFFERS; i++) { memset((void *)adcBuffer[i], 0, BUFFER_SIZE); } ADC->ADC_RPR = (unsigned long) adcBuffer[adcDMAIndex]; // DMA buffer ADC->ADC_RCR = (unsigned int) BUFFER_SIZE; // ADC works in half-word mode. ADC->ADC_RNPR = (unsigned long) adcBuffer[(adcDMAIndex + 1)]; // next DMA buffer ADC->ADC_RNCR = (unsigned int) BUFFER_SIZE; // Enable interrupts NVIC_SetPriorityGrouping(NVIC_PriorityGroup_1); NVIC_DisableIRQ(ADC_IRQn); NVIC_ClearPendingIRQ(ADC_IRQn); NVIC_SetPriority(ADC_IRQn, 6); NVIC_EnableIRQ(ADC_IRQn); ADC->ADC_PTCR = ADC_PTCR_RXTEN; // Enable receiving data. ADC->ADC_CR |= ADC_CR_START; // start waiting for trigger. // Start timer TC0->TC_CHANNEL[0].TC_SR; TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN; TC_Start(TC0, 0); }