void sam_timer_early_init(void) { #if 0 pmc_enable_periph_clk(ID_TC0); uint32_t ul_div; uint32_t ul_tcclks; uint32_t ul_sysclk = MCLK; // sysclk_get_cpu_hz(); tc_find_mck_divisor(100, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk); tc_init(TC0, 0, TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_CPCTRG); tc_write_rc(TC0, 0, (ul_sysclk / ul_div) / 4); tc_find_mck_divisor(100, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk); tc_init(TC0, 0, TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_CPCTRG); tc_write_rc(TC0, 0, 0xffff); // slowest we can run /* Configure and enable interrupt on RC compare */ NVIC_SetPriority(ID_TC0, arm_cm_highest_priority()); NVIC_EnableIRQ((IRQn_Type) ID_TC0); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); #endif tc_start(TC0, 0); arm_cm_systick_init(MCLK); }
void rtimer_arch_schedule(rtimer_clock_t t) { #if DEBUG printf("DEBUG: rtimer_arch_schedule time %llu\r\n", /*((uint32_t*)&t)+1,*/(uint64_t)t); #endif next_rtimer_time = t; rtimer_clock_t now = rtimer_arch_now(); rtimer_clock_t clock_to_wait = t - now; if(clock_to_wait <= 0x100000000){ // We must set now the Timer Compare Register. // Set the auxiliary timer (TC0,1) at the write time interrupt // [clock_to_wait] TODO Check the standard drift and perhaps remove it from the waiting time tc_write_rc(TC0,1,(uint32_t)(t-rtimer_arch_now())); // Set and enable interrupt on RC compare tc_enable_interrupt(TC0,1,TC_IER_CPCS); // Start the auxiliary timer tc_start(TC0,1); #if DEBUG now = rtimer_arch_now(); printf("DEBUG: Timer started on time %llu.\n",now); #endif } // else compare register will be set at overflow interrupt closer to the rtimer event. }
void vInitialiseTimerForIntQueueTest( void ) { uint32_t ulDivider, ulTCCLKS; /* Configure PMC for TC0. */ pmc_enable_periph_clk( ID_TC0 ); /* Configure TC0 channel 0 for interrupts at tmrTIMER_0_FREQUENCY. */ tc_find_mck_divisor( tmrTIMER_0_FREQUENCY, configCPU_CLOCK_HZ, &ulDivider, &ulTCCLKS, configCPU_CLOCK_HZ ); tc_init( TC0, 0, ulTCCLKS | TC_CMR_CPCTRG ); ulDivider <<= 1UL; tc_write_rc( TC0, 0, ( configCPU_CLOCK_HZ / ulDivider ) / tmrTIMER_0_FREQUENCY ); tc_enable_interrupt( TC0, 0, TC_IER_CPCS ); /* Configure and enable interrupts for both TC0 and TC1, as TC1 interrupts are manually pended from within the TC0 interrupt handler (see the notes at the top of this file). */ NVIC_ClearPendingIRQ( TC0_IRQn ); NVIC_ClearPendingIRQ( TC1_IRQn ); NVIC_SetPriority( TC0_IRQn, tmrLOWER_PRIORITY ); NVIC_SetPriority( TC1_IRQn, tmrHIGHER_PRIORITY ); NVIC_EnableIRQ( TC0_IRQn ); NVIC_EnableIRQ( TC1_IRQn ); /* Start the timer last of all. */ tc_start( TC0, 0 ); }
static void enable_output(const channel_def_t* channel, int freq) { if (channel->externally_driven) { uint32_t clock = sysclk_get_peripheral_bus_hz(channel->ex.timer) / 32; // clock source is PB / 32 uint32_t rc = clock / freq; // check for over/underflow if (rc > 0xffff) rc = 0xffff; else if (rc < 8) rc = 8; // set up RA, RB, and RC. always use 50% duty cycle (RA = RB = RC/2) tc_write_ra(channel->ex.timer, channel->ex.channel, (uint16_t)rc / 2); tc_write_rb(channel->ex.timer, channel->ex.channel, (uint16_t)rc / 2); tc_write_rc(channel->ex.timer, channel->ex.channel, (uint16_t)rc); tc_start(channel->ex.timer, channel->ex.channel); } else if (channel->in.active_level) { gpio_set_pin_high(channel->in.pin1); } else { gpio_set_pin_low(channel->in.pin1); } }
//Initialize the clock void clock_init(void) { GlobalInterruptDisable(); INTC_RegisterGroupHandler(INTC_IRQ_GROUP(AVR32_TC_IRQ0), AVR32_INTC_INT0, tc_irq); GlobalInterruptEnable(); // Initialize the timer/counter. tc_init_waveform(tc, &WAVEFORM_OPT); // Initialize the timer/counter waveform. // Set the compare triggers. // Remember TC counter is 16-bits, so counting second is not possible with fPBA = 12 MHz. // We configure it to count ms. // We want: (1/(fPBA/8)) * RC = 0.001 s, hence RC = (fPBA/8) / 1000 = 1500 to get an interrupt every 1 ms. tc_write_rc(tc, TC_CHANNEL, (F_PBA_SPEED / 8) / 1000); // Set RC value. //tc_write_ra(tc, TC_CHANNEL, 0); // Set RA value. //tc_write_rb(tc, TC_CHANNEL, 1900); // Set RB value. //gpio_enable_module_pin(AVR32_TC_A0_0_1_PIN, AVR32_TC_A0_0_1_FUNCTION); //gpio_enable_module_pin(AVR32_TC_B0_0_1_PIN, AVR32_TC_B0_0_1_FUNCTION); tc_configure_interrupts(tc, TC_CHANNEL, &TC_INTERRUPT); // Start the timer/counter. tc_start(tc, TC_CHANNEL); // And start the timer/counter. }
// [main_tc_configure] static void configure_tc(void) { uint32_t ul_div; uint32_t ul_tcclks; uint32_t ul_sysclk = sysclk_get_cpu_hz(); /* Configure PMC */ pmc_enable_periph_clk(ID_TC0); #if SAMG55 /* Enable PCK output */ pmc_disable_pck(PMC_PCK_3); pmc_switch_pck_to_sclk(PMC_PCK_3, PMC_PCK_PRES_CLK_1); pmc_enable_pck(PMC_PCK_3); #endif /** Configure TC for a 4Hz frequency and trigger on RC compare. */ tc_find_mck_divisor(4, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk); tc_init(TC0, 0, ul_tcclks | TC_CMR_CPCTRG); tc_write_rc(TC0, 0, (ul_sysclk / ul_div) / 4); /* Configure and enable interrupt on RC compare */ NVIC_EnableIRQ((IRQn_Type) ID_TC0); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); #ifdef LED1_GPIO /** Start the counter if LED1 is enabled. */ if (g_b_led1_active) { tc_start(TC0, 0); } #else tc_start(TC0, 0); #endif }
/*************************************************************************//** *****************************************************************************/ void HAL_TimerInit(void) { halTimerIrqCount = 0; // System Tick sysclk_enable_peripheral_clock(SYSTIMER_TICK_CHANNEL_ID); tc_init(SYSTIMER, SYSTIMER_TICK_CHANNEL, TC_CMR_TCCLKS_TIMER_CLOCK3 | TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC); NVIC_DisableIRQ(SYSTIMER_TICK_CHANNEL_IRQn); NVIC_ClearPendingIRQ(SYSTIMER_TICK_CHANNEL_IRQn); NVIC_EnableIRQ(SYSTIMER_TICK_CHANNEL_IRQn); tc_enable_interrupt(SYSTIMER, SYSTIMER_TICK_CHANNEL, TC_IER_CPCS); tc_write_rc(SYSTIMER, SYSTIMER_TICK_CHANNEL, TIMER_TOP); tc_start(SYSTIMER, SYSTIMER_TICK_CHANNEL); sysclk_enable_peripheral_clock(SYSTIMER_DELAY_CHANNEL_ID); tc_init(SYSTIMER, SYSTIMER_DELAY_CHANNEL, TC_CMR_TCCLKS_TIMER_CLOCK3 | TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_CPCDIS | TC_CMR_CPCSTOP); NVIC_DisableIRQ(SYSTIMER_DELAY_CHANNEL_IRQn); NVIC_ClearPendingIRQ(SYSTIMER_DELAY_CHANNEL_IRQn); NVIC_EnableIRQ(SYSTIMER_DELAY_CHANNEL_IRQn); tc_enable_interrupt(SYSTIMER, SYSTIMER_DELAY_CHANNEL, TC_IER_CPCS); }
// Set the frequency of the generated tone. 0 means off. void audioFrequencySet(uint32_t freq) { // In order to avoid audio hiccups, don't do anything if setting // same frequency. if (currFreq == freq) { return; } tc_stop(TC0, 0); if (freq == 0) { return; } // Find the best divisor for this frequency uint32_t ul_div, ul_tcclks; tc_find_mck_divisor(freq, SystemCoreClock, &ul_div, &ul_tcclks, SystemCoreClock); // Put Timer into wavesel up RC mode with TIOA at 50% duty cycle // Clear TIOA at CPC match and set at CPA match tc_init(TC0, 0, ul_tcclks | TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_ACPC_CLEAR | TC_CMR_ACPA_SET); uint16_t rcVal = (SystemCoreClock / ul_div) / freq; tc_write_rc(TC0, 0, rcVal); tc_write_ra(TC0, 0, rcVal / 2); // 50% duty cycle // Start the thing tc_start(TC0, 0); currFreq = freq; }
void lp_ticker_set_interrupt(timestamp_t timestamp) { uint32_t cur_time; uint32_t delta; cur_time = lp_ticker_read(); delta = timestamp - cur_time; uint16_t interruptat=0; if(delta > OVERFLOW_16bit_VALUE) { lp_ticker_interrupt_counter= (delta/OVERFLOW_16bit_VALUE) -1; lp_ticker_interrupt_offset=delta%OVERFLOW_16bit_VALUE; interruptat=OVERFLOW_16bit_VALUE; } else { lp_ticker_interrupt_counter=0; lp_ticker_interrupt_offset=0; interruptat=delta; } NVIC_DisableIRQ(TICKER_COUNTER_IRQn2); tc_write_rc(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2, (uint32_t)interruptat); NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn2); NVIC_SetPriority(TICKER_COUNTER_IRQn2, 0); NVIC_EnableIRQ(TICKER_COUNTER_IRQn2); tc_enable_interrupt(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2, TC_IDR_CPCS ); tc_start(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); }
void config_uart(void){ /* configura pinos */ gpio_configure_group(PINS_UART0_PIO, PINS_UART0, PINS_UART0_FLAGS); /* ativa clock */ sysclk_enable_peripheral_clock(CONSOLE_UART_ID); /* Configuração UART */ const usart_serial_options_t uart_serial_options = { .baudrate = CONF_UART_BAUDRATE, .paritytype = UART_MR_PAR_NO, .stopbits = 0 }; stdio_serial_init((Usart *)CONF_UART, &uart_serial_options); } static void configure_tc(void) { uint32_t ul_sysclk = sysclk_get_cpu_hz(); pmc_enable_periph_clk(ID_TC0); tc_init(TC0, 0, TC_CMR_CPCTRG | TC_CMR_TCCLKS_TIMER_CLOCK5); tc_write_rc(TC0, 0, 8192); NVIC_EnableIRQ(ID_TC0); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); tc_start(TC0,0); }
/** * Configure Timer Counter 0 to generate an interrupt every 1s. */ static void configure_tc(void) { /* * Aqui atualizamos o clock da cpu que foi configurado em sysclk init * * O valor atual está em : 120_000_000 Hz (120Mhz) */ uint32_t ul_sysclk = sysclk_get_cpu_hz(); /* * Ativa o clock do periférico TC 0 */ pmc_enable_periph_clk(ID_TC0); // Configura TC para operar no modo de comparação e trigger RC tc_init(TC0,0,TC_CMR_CPCTRG | TC_CMR_TCCLKS_TIMER_CLOCK5); // Valor para o contador de um em um segundo. tc_write_rc(TC0,0,32768); NVIC_EnableIRQ((IRQn_Type) ID_TC0); tc_enable_interrupt(TC0,0,TC_IER_CPCS); tc_start(TC0, 0); }
/** * \brief Initialize the timer counter (TC0). */ void sys_init_timing(void) { uint32_t ul_div; uint32_t ul_tcclks; /* Clear tick value. */ gs_ul_clk_tick = 0; /* Configure PMC. */ pmc_enable_periph_clk(ID_TC0); /* Configure TC for a 1kHz frequency and trigger on RC compare. */ tc_find_mck_divisor(1000, sysclk_get_main_hz(), &ul_div, &ul_tcclks, sysclk_get_main_hz()); tc_init(TC0, 0, ul_tcclks | TC_CMR_CPCTRG); tc_write_rc(TC0, 0, (sysclk_get_main_hz() / ul_div) / 1000); /* Configure and enable interrupt on RC compare. */ NVIC_EnableIRQ((IRQn_Type)ID_TC0); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); /* Start timer. */ tc_start(TC0, 0); }
/*! \brief to load compare value in channel compare register */ void tmr_write_cmpreg(uint16_t compare_value) { #if SAM4E tc_write_ra(TIMER, TIMER_CHANNEL_ID, compare_value); #else tc_write_rc(TIMER, TIMER_CHANNEL_ID, compare_value); #endif }
// [main_tc_configure] static void configure_tc(void) { uint32_t ul_sysclk = sysclk_get_cpu_hz(); pmc_enable_periph_clk(ID_TC0); tc_init(TC0,0,TC_CMR_TCCLKS_TIMER_CLOCK5 |TC_CMR_CPCTRG); tc_write_rc(TC0,0,32000); tc_enable_interrupt(TC0,0,TC_IER_CPCS); NVIC_EnableIRQ(ID_TC0); tc_start(TC0,0); }
void configure_timer_for_run_time_stats(void) { pmc_enable_periph_clk(ID_TC0); tc_init(TC0, 0, // Init timer counter 0 channel 0. TC_CMR_WAVE | // Waveform Mode is enabled. TC_CMR_TCCLKS_TIMER_CLOCK5 // Use slow clock to avoid overflow. ); tc_write_rc(TC0, 0, 0xffffffff); // Load the highest possible value into TC. tc_start(TC0, 0); // Start Timer counter 0 channel 0. }
void vInitialiseTimerForIntQueueTest( void ) { uint32_t ulInputFrequency; /* Calculate the frequency of the clock that feeds the TC. */ ulInputFrequency = configCPU_CLOCK_HZ; ulInputFrequency /= trmDIVIDER; /* Three channels are used - two that run at or under configMAX_SYSCALL_INTERRUPT_PRIORITY, and one that runs over configMAX_SYSCALL_INTERRUPT_PRIORITY. */ sysclk_enable_peripheral_clock( ID_TC0 ); sysclk_enable_peripheral_clock( ID_TC1 ); sysclk_enable_peripheral_clock( ID_TC2 ); /* Init TC channels to waveform mode - up mode clean on RC match. */ tc_init( TC0, tmrTIMER_0_CHANNEL, TC_CMR_TCCLKS_TIMER_CLOCK4 | TC_CMR_WAVE | TC_CMR_ACPC_CLEAR | TC_CMR_CPCTRG ); tc_init( TC0, tmrTIMER_1_CHANNEL, TC_CMR_TCCLKS_TIMER_CLOCK4 | TC_CMR_WAVE | TC_CMR_ACPC_CLEAR | TC_CMR_CPCTRG ); tc_init( TC0, tmrTIMER_2_CHANNEL, TC_CMR_TCCLKS_TIMER_CLOCK4 | TC_CMR_WAVE | TC_CMR_ACPC_CLEAR | TC_CMR_CPCTRG ); tc_enable_interrupt( TC0, tmrTIMER_0_CHANNEL, tmrTRIGGER_ON_RC ); tc_enable_interrupt( TC0, tmrTIMER_1_CHANNEL, tmrTRIGGER_ON_RC ); tc_enable_interrupt( TC0, tmrTIMER_2_CHANNEL, tmrTRIGGER_ON_RC ); tc_write_rc( TC0, tmrTIMER_0_CHANNEL, ( ulInputFrequency / tmrTIMER_0_FREQUENCY ) ); tc_write_rc( TC0, tmrTIMER_1_CHANNEL, ( ulInputFrequency / tmrTIMER_1_FREQUENCY ) ); tc_write_rc( TC0, tmrTIMER_2_CHANNEL, ( ulInputFrequency / tmrTIMER_2_FREQUENCY ) ); NVIC_SetPriority( TC0_IRQn, tmrTIMER_0_PRIORITY ); NVIC_SetPriority( TC1_IRQn, tmrTIMER_1_PRIORITY ); NVIC_SetPriority( TC2_IRQn, tmrTIMER_2_PRIORITY ); NVIC_EnableIRQ( TC0_IRQn ); NVIC_EnableIRQ( TC1_IRQn ); NVIC_EnableIRQ( TC2_IRQn ); tc_start( TC0, tmrTIMER_0_CHANNEL ); tc_start( TC0, tmrTIMER_1_CHANNEL ); tc_start( TC0, tmrTIMER_2_CHANNEL ); }
/** * \brief Configure Timer Counter 0 (TC0) to generate an interrupt every * second. */ static void demo_configure_tc0( void ) { /* Enable TC0 peripheral clock. */ pmc_enable_periph_clk(ID_TC1); /* Configure TC for a 1s (= 1Hz) tick. */ tc_init(TC0, 1, 0x4 | TC_CMR_ACPC_SET | TC_CMR_WAVE | TC_CMR_ACPA_CLEAR | TC_CMR_WAVSEL_UP_RC); /* 50% duty, 1s frequency */ tc_write_ra(TC0, 1, 16384); tc_write_rc(TC0, 1, 32768); }
/*************************************************************************//** *****************************************************************************/ void HAL_TimerDelay(uint16_t us) { halTimerDelayInt = 0; tc_write_rc(SYSTIMER, SYSTIMER_DELAY_CHANNEL, us); tc_start(SYSTIMER, SYSTIMER_DELAY_CHANNEL); // Wait compare match interrupt... while(halTimerDelayInt == 0) { // Stop processor clock until next interrupt... __WFI(); } }
void tc_init(void) { // The timer/counter instance and channel number are used in several functions. // It's defined as local variable for ease-of-use causes and readability. volatile avr32_tc_t *tc = WIFI_TC; // Options for waveform genration. tc_waveform_opt_t waveform_opt = { .channel = WIFI_TC_CHANNEL_ID, // Channel selection. .bswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .aswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .acpc = TC_EVT_EFFECT_TOGGLE, // RC compare effect on TIOA: toggle. .acpa = TC_EVT_EFFECT_TOGGLE, // RA compare effect on TIOA: toggle (other possibilities are none, set and clear). .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,// Waveform selection: Up mode with automatic trigger(reset) on RC compare. .enetrg = FALSE, // External event trigger enable. .eevt = TC_EXT_EVENT_SEL_TIOB_INPUT, // External event selection. .eevtedg = TC_SEL_NO_EDGE, // External event edge selection. .cpcdis = FALSE, // Counter disable when RC compare. .cpcstop = FALSE, // Counter clock stopped with RC compare. .burst = TC_BURST_NOT_GATED, // Burst signal selection. .clki = TC_CLOCK_RISING_EDGE, // Clock inversion. .tcclks = TC_CLOCK_SOURCE_TC2 // Internal source clock 3, connected to fPBA / 2. }; // Assign I/O to timer/counter channel pin & function. gpio_enable_module_pin(WIFI_TC_CHANNEL_PIN, WIFI_TC_CHANNEL_FUNCTION); // Initialize the timer/counter. tc_init_waveform(tc, &waveform_opt); // Initialize the timer/counter waveform. // Set the compare triggers. tc_write_ra(tc, WIFI_TC_CHANNEL_ID, 0x01A4); // Set RA value. tc_write_rc(tc, WIFI_TC_CHANNEL_ID, 0x0348); // Set RC value. // Start the timer/counter. tc_start(tc, WIFI_TC_CHANNEL_ID); }
/** * \brief Enable TC1 channel 0 to trigger each second to compute GMAC stats. */ static void configure_timer_for_bandwidth_stats(void) { pmc_enable_periph_clk(ID_TC3); // Warning TC number is the channel not TC number. // Hence TC3 means TC1 channel 0. tc_init(TC1, 0, // Init timer counter 1 channel 0. TC_CMR_WAVE | // Waveform Mode is enabled. TC_CMR_CPCTRG | // UP mode with automatic trigger on RC Compare TC_CMR_TCCLKS_TIMER_CLOCK5 // Use slow clock to avoid overflow. ); tc_write_rc(TC1, 0, 32768); // Load the highest possible value into TC. /* Configure TC interrupts for TC TC_CHANNEL_CAPTURE only */ NVIC_SetPriority(TC3_IRQn, 0); // TC3 means TC1 channel 0. NVIC_EnableIRQ(TC3_IRQn); // TC3 means TC1 channel 0. tc_enable_interrupt(TC1, 0, TC_IER_CPCS); tc_start(TC1, 0); // Start Timer counter 0 channel 0. }
void rtimer_arch_init(void) { /* * In this implementation we will make use of two Timer Counters (TC). * The first (TC0) is used to count the universal time, and triggers * an interrupt on overflow. The timer runs always, and counts the total * time elapsed since device boot. It is used to extract the current time * (now) * * The second timer (TC1) is used to schedule events in real time. */ /* Configure PMC: Enable peripheral clock on component: TC0, channel 0 [see sam3x8e.h] */ pmc_enable_periph_clk(ID_TC0); /* Configure PMC: Enable peripheral clock on component: TC0, channel 1 [see sam3x8e.h] */ pmc_enable_periph_clk(ID_TC1); /* Configure the TC0 for 10500000 Hz and trigger on RC register compare */ tc_init(TC0, 0, RT_PRESCALER | TC_CMR_CPCTRG); /* Configure the TC1 for 10500000 Hz and trigger on RC register compare */ tc_init(TC0, 1, RT_PRESCALER | TC_CMR_CPCTRG); /* Disable all interrupts on both counters*/ tc_disable_interrupt(TC0,0,0b11111111); tc_disable_interrupt(TC0,1,0b11111111); /* Configure the main counter to trigger an interrupt on RC compare (overflow) */ tc_write_rc(TC0, 0, 0xffffffff); /* Configure interrupt on the selected timer channel, setting the corresponding callback */ NVIC_EnableIRQ((IRQn_Type) ID_TC0); /* Configure interrupt on the selected timer channel, setting the corresponding callback */ NVIC_EnableIRQ((IRQn_Type) ID_TC1); /* Enable TC0 interrupt on RC Compare */ tc_enable_interrupt(TC0, 0, TC_IER_CPCS); /* Start the universal time counter */ tc_start(TC0, 0); #if DEBUG printf("DEBUG: Universal Real-Timer started.\n"); #endif }
/** * \brief TC configuration. */ static void dsp_configure_tc(void) { pmc_enable_periph_clk(ID_TC1); /* * Init timer counter 0 * RC Compare Effect on TIOA "SET" * Waveform Mode is enabled * UP mode with automatic trigger on RC Compare */ tc_init(TC0, 1, TC_CMR_ACPC_SET | TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC |TC_CMR_ACPA_CLEAR ); /* Load in TC RA register */ tc_write_ra(TC0, 1, TC_RA); /* Load in TC RC register */ tc_write_rc(TC0, 1, TC_RC); }
void TICKER_COUNTER_Handlr2(void) { uint32_t status=tc_get_status(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); uint32_t interrupmask=tc_get_interrupt_mask(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); if (((status & interrupmask) & TC_IER_CPCS)) { if(lp_ticker_interrupt_counter) { lp_ticker_interrupt_counter--; } else { if(lp_ticker_interrupt_offset) { tc_stop(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); tc_write_rc(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2, (uint32_t)lp_ticker_interrupt_offset); tc_start(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); lp_ticker_interrupt_offset=0; } else { lp_ticker_irq_handler(); } } } }
static void reset_timeout(void) { if (s_period_counter > 0) { // see how long to wait uint16_t rc = min(0xffff,s_period_counter); tc_write_rc(CONFIG_BSP_BUZZER_REP_TIMER, CONFIG_BSP_BUZZER_REP_CHANNEL, rc); // remember how much we've waited s_period_counter -= rc; // Reset the counter tc_start(CONFIG_BSP_BUZZER_REP_TIMER, CONFIG_BSP_BUZZER_REP_CHANNEL); } else { // make sure the timer is stopped tc_stop(CONFIG_BSP_BUZZER_REP_TIMER, CONFIG_BSP_BUZZER_REP_CHANNEL); } }
/*! \brief to initialiaze hw timer */ uint8_t tmr_init(void) { uint8_t tmr_mul; /* Configure clock service. */ #if SAM4L sysclk_enable_peripheral_clock(TIMER); #else sysclk_enable_peripheral_clock(ID_TC); #endif /* Get system clock. */ tmr_mul = sysclk_get_peripheral_bus_hz(TIMER) / DEF_1MHZ; tmr_mul = tmr_mul >> 1; #if SAM4L tc_init(TIMER, TIMER_CHANNEL_ID, TC_CMR_TCCLKS_TIMER_CLOCK2 | TC_CMR_WAVE | TC_CMR_WAVSEL_UP_NO_AUTO); #elif SAM4E tc_init(TIMER, TIMER_CHANNEL_ID, TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC); #else tc_init(TIMER, TIMER_CHANNEL_ID, TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_WAVE | TC_CMR_WAVSEL_UP); #endif /* Configure and enable interrupt on RC compare. */ configure_NVIC(TIMER, TIMER_CHANNEL_ID); #if SAM4E tc_get_status(TIMER, TIMER_CHANNEL_ID); tc_enable_interrupt(TIMER, TIMER_CHANNEL_ID, TC_IER_CPCS); tc_write_rc(TIMER, TIMER_CHANNEL_ID, UINT16_MAX); #else tc_get_status(TIMER, TIMER_CHANNEL_ID); tc_enable_interrupt(TIMER, TIMER_CHANNEL_ID, TC_IER_COVFS); #endif tmr_disable_cc_interrupt(); tc_start(TIMER, TIMER_CHANNEL_ID); return tmr_mul; }
/** * \brief Configure Timer Counter 0 (TC0) to generate an interrupt every 200ms. * This interrupt will be used to flush USART input and echo back. */ static void configure_tc(void) { uint32_t ul_div; uint32_t ul_tcclks; static uint32_t ul_sysclk; /* Get system clock. */ ul_sysclk = sysclk_get_cpu_hz(); /* Configure PMC. */ pmc_enable_periph_clk(ID_TC0); /* Configure TC for a 50Hz frequency and trigger on RC compare. */ tc_find_mck_divisor(TC_FREQ, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk); tc_init(TC0, 0, ul_tcclks | TC_CMR_CPCTRG); tc_write_rc(TC0, 0, (ul_sysclk / ul_div) / TC_FREQ); /* Configure and enable interrupt on RC compare. */ NVIC_EnableIRQ((IRQn_Type)ID_TC0); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); }
/** * \brief Configure Timer Counter 0 (TC0) to generate an interrupt every 200ms. * This interrupt will be used to flush USART input and echo back. */ static void configure_tc(void) { uint32_t ul_div; uint32_t ul_tcclks; static uint32_t ul_pbaclk; /* Configure clock service. */ sysclk_enable_peripheral_clock(TC0); /* Get system clock. */ ul_pbaclk = sysclk_get_peripheral_bus_hz(TC0); /* Configure TC for a 1Hz frequency and trigger on RC compare. */ tc_find_mck_divisor(TC_FREQ, ul_pbaclk, &ul_div, &ul_tcclks, ul_pbaclk); tc_init(TC0, 0, ul_tcclks | TC_CMR_CPCTRG); tc_write_rc(TC0, 0, (ul_pbaclk / ul_div) / TC_FREQ); /* Configure and enable interrupt on RC compare. */ NVIC_EnableIRQ(TC00_IRQn); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); }
void TC0_Handler(void) { volatile uint32_t ul_dummy, TC_value; /* Get the current timer counter value from a 32-bit register*/ TC_value = tc_read_tc(TC0,0); /* Clear status bit to acknowledge interrupt */ ul_dummy = tc_get_status(TC0, 0); if ((ul_dummy & TC_SR_CPCS) == TC_SR_CPCS) { #if DEBUG printf("%08x OV \n",TC_value); #endif time_msb++; rtimer_clock_t now = ((rtimer_clock_t)time_msb << 32)|tc_read_tc(TC0,0); rtimer_clock_t clock_to_wait = next_rtimer_time - now; if(clock_to_wait <= 0x100000000 && clock_to_wait > 0) { // We must set now the Timer Compare Register. // Set the auxiliary timer (TC0,1) at the write time interrupt tc_write_rc(TC0,1,(uint32_t)clock_to_wait); // Set and enable interrupt on RC compare tc_enable_interrupt(TC0,1,TC_IER_CPCS); // Start the auxiliary timer tc_start(TC0,1); } } else { printf("ERROR: TC: Unknown interrupt.\n"); } }
static void configure_tc(void) { /* * Aqui atualizamos o clock da cpu que foi configurado em sysclk init * * O valor atual est'a em : 120_000_000 Hz (120Mhz) */ uint32_t ul_sysclk = TC_CMR_TCCLKS_TIMER_CLOCK5; /* * Ativa o clock do periférico TC 0 * */ pmc_enable_periph_clk(ID_TC0); /* * Configura TC para operar no modo de comparação e trigger RC * devemos nos preocupar com o clock em que o TC irá operar ! * * Cada TC possui 3 canais, escolher um para utilizar. * * Uma opção para achar o valor do divisor é utilizar a funcao * tc_find_mck_divisor() */ tc_init(TC0, 0, TC_CMR_CPCTRG | TC_CMR_TCCLKS_TIMER_CLOCK5); tc_write_rc(TC0, 0, 534); /* * Devemos configurar o NVIC para receber interrupções do TC */ NVIC_EnableIRQ(ID_TC0); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); tc_start(TC0,0); }
/** * \brief Configure Timer Counter 0 to generate an interrupt with the specific * frequency. * * \param freq Timer counter frequency. */ static void configure_tc(uint32_t freq) { uint32_t ul_div; uint32_t ul_tcclks; uint32_t ul_sysclk = sysclk_get_cpu_hz(); /* Disable TC first */ tc_stop(TC0, 0); tc_disable_interrupt(TC0, 0, TC_IER_CPCS); /** Configure TC with the frequency and trigger on RC compare. */ tc_find_mck_divisor(freq, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk); tc_init(TC0, 0, ul_tcclks | TC_CMR_CPCTRG); tc_write_rc(TC0, 0, (ul_sysclk / ul_div) / 4); /* Configure and enable interrupt on RC compare */ NVIC_EnableIRQ((IRQn_Type)ID_TC0); tc_enable_interrupt(TC0, 0, TC_IER_CPCS); /** Start the counter. */ tc_start(TC0, 0); }