/** * \brief Run tests and turn on power to simulated oven plate * * This functions runs some class B tests, reinitializes Timer/Counters, ADC and * DAC used by the oven, then turns on and starts monitoring of periodic tests. */ static void ovenctl_turn_on_plate(void) { /* Store current DAC value since the analog IO test is destructive */ uint16_t dac_val = DACB.CH0DATA; /* Run tests -- classb_error is updated if any of them fail */ oven_classb_run_tests(); /* Initialize the ADC and DAC modules, as well as the Timer/Counters * we use to emulate real world application. */ main_init_adc_dac(); DACB.CH0DATA = dac_val; main_init_tc(); /* Enable and set up timer for periodic temperature checking */ tc_enable(&OVEN_PERIODIC_TEMPTEST_TC); /* Set timer to overflow every 600ms: 24MHz / (1024 * 14063) = 0.6s */ tc_write_clock_source(&OVEN_PERIODIC_TEMPTEST_TC, TC_CLKSEL_DIV1024_gc); tc_write_period(&OVEN_PERIODIC_TEMPTEST_TC, 14062); /* Set up temperature check as interrupt callback function, then enable * interrupts */ tc_set_overflow_interrupt_callback(&OVEN_PERIODIC_TEMPTEST_TC, ovenctl_periodic_temperature_sanity_check); tc_set_overflow_interrupt_level(&OVEN_PERIODIC_TEMPTEST_TC, TC_OVFINTLVL_LO_gc); /* Enable monitoring of the periodic temperature check */ classb_intmon_set_state(TEMP_SANITY_TEST, M_ENABLE); /* Enable and set up timer for periodic execution of Class B tests */ tc_enable(&OVEN_PERIODIC_CLASSB_TC); /* Set timer to overflow every second: 24MHz / (1024 * 23438) = 1s */ tc_write_clock_source(&OVEN_PERIODIC_CLASSB_TC, TC_CLKSEL_DIV1024_gc); tc_write_period(&OVEN_PERIODIC_CLASSB_TC, 23437); /* Set up periodic class B test as interrupt callback function, then * enable interrupts */ tc_set_overflow_interrupt_callback(&OVEN_PERIODIC_CLASSB_TC, ovenctl_periodic_classb_tests); tc_set_overflow_interrupt_level(&OVEN_PERIODIC_CLASSB_TC, TC_OVFINTLVL_LO_gc); /* Enable monitoring of the periodic temperature check */ classb_intmon_set_state(PER_CLASSB_TESTS, M_ENABLE); }
/** * \b avrInitSystemTickTimer * * Initialise the system tick timer. Uses the AVR's timer1 facility. * * @return None */ void avrInitSystemTickTimer ( void ) { /* * Unmask clock for TCC1 */ tc_enable(&TCC1); /* * Configure interrupts callback functions for CCA interrupt */ tc_set_cca_interrupt_callback(&TCC1, cca_interrupt_callback); /* * Configure TC in normal mode, configure period, CCA * Enable CCA channel */ tc_set_wgm(&TCC1, TC_WG_NORMAL); tc_write_period(&TCC1, AVR_CPU_HZ / 256 / SYSTEM_TICKS_PER_SEC); tc_write_cc(&TCC1, TC_CCA, AVR_CPU_HZ / 256 / SYSTEM_TICKS_PER_SEC / 2); tc_enable_cc_channels(&TCC1,(enum tc_cc_channel_mask_enable_t)(TC_CCAEN)); /* * Enable TC interrupts (overflow, CCA and CCB) */ tc_set_cca_interrupt_level(&TCC1, TC_CCAINTLVL_LO_gc); /* * Run TCC1 at AVR_CPU_HZ / 256 */ tc_write_clock_source(&TCC1, TC_CLKSEL_DIV256_gc); }
/** * \internal * \brief Initializes the timer counter used to generate a delay */ static void main_delay_init(void) { tc_enable(CONF_DELAY_TC); tc_set_wgm(CONF_DELAY_TC, TC_WG_NORMAL); tc_set_resolution(CONF_DELAY_TC, 1); tc_write_period(CONF_DELAY_TC, 0xFFFF); }
void generator_qenc_set_freq(uint32_t freq) { /* Number of ticks per step */ uint16_t ticks = 0; /* The following code calculates the upper boundary of the timer and the * interrupt positions to get a correct Quadrature signal of the given * frequency. * The different compare interrupts sets the phase0 and phase90 signals. * Phase-0 uses Pin1, Phase90-Pin2 and Index-Pin3 from selected port * * Compare A interrupt clear phase0 and sets phase90 * Compare B interrupt sets phase0 and phase90 * Compare C interrupt sets phase0 and clear phase90 * Compare D interrupt clears phase0 and phase90. * * Compare A interrupt also sets the index signal when one round has * passed. */ /* Calculates upper boundary of timer to get desired frequency */ tc_set_resolution(generator_qenc_timer, (freq * generator_qenc_revolution) / 1000); ticks = ((uint64_t)tc_get_resolution(generator_qenc_timer) * 1000) / (freq * generator_qenc_revolution); /* Write timer period register */ tc_write_count(generator_qenc_timer, 0); tc_write_period(generator_qenc_timer, ticks); }
/*! \brief to initialiaze hw timer */ uint8_t tmr_init(void) { uint8_t timer_multiplier; tc_enable(TIMER); tc_set_overflow_interrupt_callback(TIMER, (tc_callback_t)tc_ovf_callback); /*initialize timer in waveform generator - Normal mode */ tc_set_wgm(TIMER, TC_WG_NORMAL); tc_write_period(TIMER, TIMER_PERIOD); /* select clock division as 1 */ tc_write_clock_source(TIMER, TC_CLKSEL_DIV1_gc); tc_set_overflow_interrupt_level(TIMER, TC_INT_LVL_HI); tc_set_cca_interrupt_callback(TIMER, (tc_callback_t)tc_cca_callback); tc_enable_cc_channels(TIMER, TC_CCAEN); tc_set_cca_interrupt_level(TIMER, TC_INT_LVL_OFF); /* calculate how faster the timer with current clk freq compared to * timer with 1Mhz */ timer_multiplier = sysclk_get_peripheral_bus_hz(TIMER) / DEF_1MHZ; return timer_multiplier; }
int main(void) { pmic_init(); board_init(); sysclk_init(); sleepmgr_init(); cpu_irq_enable(); #if (BOARD == XMEGA_A3BU_XPLAINED) /* The status LED must be used as LED2, so we turn off * the green led which is in the same packaging. */ ioport_set_pin_high(LED3_GPIO); #endif /* * Unmask clock for TIMER_EXAMPLE */ tc_enable(&TIMER_EXAMPLE); /* * Configure interrupts callback functions for TIMER_EXAMPLE * overflow interrupt, CCA interrupt and CCB interrupt */ tc_set_overflow_interrupt_callback(&TIMER_EXAMPLE, example_ovf_interrupt_callback); tc_set_cca_interrupt_callback(&TIMER_EXAMPLE, example_cca_interrupt_callback); tc_set_ccb_interrupt_callback(&TIMER_EXAMPLE, example_ccb_interrupt_callback); /* * Configure TC in normal mode, configure period, CCA and CCB * Enable both CCA and CCB channels */ tc_set_wgm(&TIMER_EXAMPLE, TC_WG_NORMAL); tc_write_period(&TIMER_EXAMPLE, TIMER_EXAMPLE_PERIOD); tc_write_cc(&TIMER_EXAMPLE, TC_CCA, TIMER_EXAMPLE_PERIOD / 2); tc_write_cc(&TIMER_EXAMPLE, TC_CCB, TIMER_EXAMPLE_PERIOD / 4); tc_enable_cc_channels(&TIMER_EXAMPLE,(enum tc_cc_channel_mask_enable_t)(TC_CCAEN | TC_CCBEN)); /* * Enable TC interrupts (overflow, CCA and CCB) */ tc_set_overflow_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO); tc_set_cca_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO); tc_set_ccb_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO); /* * Run TIMER_EXAMPLE at TIMER_EXAMPLE_PERIOD(31250Hz) resolution */ tc_set_resolution(&TIMER_EXAMPLE, TIMER_EXAMPLE_PERIOD); do { /* Go to sleep, everything is handled by interrupts. */ sleepmgr_enter_sleep(); } while (1); }
static void init_timer_isr(void) { tc_enable(&TCC0); tc_write_period(&TCC0, TIMER_PERIOD); tc_write_clock_source(&TCC0, TC_CLKSEL_DIV8_gc); tc_set_cca_interrupt_level(&TCC0, PMIC_LVL_LOW); tc_set_cca_interrupt_callback(&TCC0, example_cca_interrupt_callback); }
void init_timer_isr( void ) { tc_enable (&TCC0); tc_write_period (&TCC0, (TICKS_PER_MS * qt_measurement_period_msec)); tc_write_clock_source (&TCC0, TC_CLKSEL_DIV8_gc); tc_set_cca_interrupt_level (&TCC0, PMIC_LVL_LOW); tc_set_cca_interrupt_callback(&TCC0, example_cca_interrupt_callback); }
/** * Initialize trace */ void hf_trace_init() { tc_enable(&TCC0); tc_set_overflow_interrupt_callback(&TCC0, tc_wrap); tc_set_wgm(&TCC0, TC_WG_NORMAL); tc_write_period(&TCC0, 65535); tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO); tc_write_clock_source(&TCC0, TC_CLKSEL_DIV8_gc); }
/** * \brief Configure timer interrupts for touch measurements */ static void touch_init_timer_isr(void) { tc_enable(&TOUCH_TC); tc_set_overflow_interrupt_callback(&TOUCH_TC, &touch_timer_period_handler); tc_set_resolution(&TOUCH_TC, (uint32_t)1000000); tc_write_period(&TOUCH_TC, (tc_get_resolution(&TOUCH_TC) * TOUCH_TC_PERIOD_MS) / 1000); tc_set_overflow_interrupt_level(&TOUCH_TC, TC_INT_LVL_LO); }
void init_MS5611_callback() { tc_enable(&(MS5611_TIMER)); // timer used for callback functionality tc_set_overflow_interrupt_callback(&(MS5611_TIMER), ms5611_altitude); // sets up a function to callback when it's time to run tc_set_wgm(&(MS5611_TIMER), TC_WG_NORMAL); // sets the waveform generation tc_write_period(&(MS5611_TIMER), MS5611_HZ); tc_set_overflow_interrupt_level(&(MS5611_TIMER), TC_INT_LVL_LO); // medium priority 0x02 tc_write_clock_source(&(MS5611_TIMER), TC_CLKSEL_DIV1024_gc); // set clock prescaler to 1024 }
void XBee_Init() { tc_enable(&(XBEE_TIMER)); // timer used for callback functionality tc_set_overflow_interrupt_callback(&(XBEE_TIMER), SendTelemetry); // sets up a function to callback when it's time to run tc_set_wgm(&(XBEE_TIMER), TC_WG_NORMAL); // sets the waveform generation tc_write_period(&(XBEE_TIMER), XBEE_HZ); // this should run at 2 HZ tc_set_overflow_interrupt_level(&(XBEE_TIMER), TC_INT_LVL_MED); // low priority 0x01 tc_write_clock_source(&(XBEE_TIMER), TC_CLKSEL_DIV1024_gc); // set clock prescaler to 1024 }
void TimerE1_init(void) { tc_write_clock_source(&TCE1,TC_CLKSEL_DIV256_gc); tc_set_wgm(&TCE1,TC_WG_SS); tc_write_period(&TCE1,0x00FF); tc_set_direction(&TCE1,TC_UP); tc_enable_cc_channels(&TCE1,TC_CCAEN); tc_enable(&TCE1); };
void TimerD0_init(void) { tc_write_clock_source(&TCD0,TC_CLKSEL_DIV256_gc); tc_set_wgm(&TCD0,TC_WG_NORMAL); tc_set_overflow_interrupt_level(&TCD0,TC_INT_LVL_MED); tc_write_period(&TCD0,TIMERD0_PER); tc_set_direction(&TCD0,TC_UP); tc_enable(&TCD0); };
void app_touch_init(void) { #ifdef QTOUCH_STUDIO_MASKS SNS_array[0][0] = 0x50; SNS_array[0][1] = 0x00; SNS_array[1][0] = 0x00; SNS_array[1][1] = 0x00; SNSK_array[0][0] = 0xA0; SNSK_array[0][1] = 0x00; SNSK_array[1][0] = 0x00; SNSK_array[1][1] = 0x00; #endif /* Configures the sensors as keys and assigns the channel numbers. * The sensor is wired up with SNS=PF6 and SNSK=PF7 * When using "pin reconfigurability" this will result in channel 0 * because it is the first and only channel that is used. * For the standard qtouch library setup we would need to use * channel 3 since we are using the last two pins on the port. */ qt_enable_key(CHANNEL_0, NO_AKS_GROUP, 10u, HYST_6_25); qt_enable_key(CHANNEL_1, NO_AKS_GROUP, 10u, HYST_6_25); qt_init_sensing(); /* This will fill the default threshold values in the configuration * data structure. But User can change the values of these parameters. */ qt_config_data.qt_di = DEF_QT_DI; qt_config_data.qt_neg_drift_rate = DEF_QT_NEG_DRIFT_RATE; qt_config_data.qt_pos_drift_rate = DEF_QT_POS_DRIFT_RATE; qt_config_data.qt_max_on_duration = DEF_QT_MAX_ON_DURATION; qt_config_data.qt_drift_hold_time = DEF_QT_DRIFT_HOLD_TIME; qt_config_data.qt_recal_threshold = DEF_QT_RECAL_THRESHOLD; qt_config_data.qt_pos_recal_delay = DEF_QT_POS_RECAL_DELAY; /* Initialize the timer counter */ tc_enable(&TCC0); tc_write_period(&TCC0, TIMER_PERIOD); tc_write_clock_source(&TCC0, TC_CLKSEL_DIV8_gc); tc_set_cca_interrupt_level(&TCC0, PMIC_LVL_LOW); tc_set_cca_interrupt_callback(&TCC0, app_touch_tc_interrupt_callback); /* * Set up callback function. This function is called after the library * has made capacitive measurements, but before it has processed them. * The user can use this hook to apply filter functions to the measured * signal values.(Possibly to fix sensor layout faults) */ qt_filter_callback = NULL; #ifdef _DEBUG_INTERFACE_ QDebug_Init(); #endif sleepmgr_lock_mode(SLEEPMGR_IDLE); }
int main(void) { pmic_init(); board_init(); sysclk_init(); sleepmgr_init(); cpu_irq_enable(); /* Enables the Timer defined in conf_example.h : TCE0 in this example */ tc_enable(&TIMER_EXAMPLE); /* Configures the interrupt level of CCA and CCB modules : low */ tc_set_cca_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO); tc_set_ccb_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO); /* Configures the waveform generator of this Timer mode in NORMAL mode */ tc_set_wgm(&TIMER_EXAMPLE, TC_WG_NORMAL); /* Declares the interrupt functions which will be called when CCA and CCB interrupts will occur */ tc_set_cca_interrupt_callback(&TIMER_EXAMPLE, example_cca_interrupt_callback); tc_set_ccb_interrupt_callback(&TIMER_EXAMPLE, example_ccb_interrupt_callback); /* Configures the Timer period*/ tc_write_period(&TIMER_EXAMPLE, TIMER_EXAMPLE_PERIOD); /* Configures the CCA and CCB levels*/ tc_write_cc(&TIMER_EXAMPLE, TC_CCA, TIMER_EXAMPLE_PERIOD/2); tc_write_cc(&TIMER_EXAMPLE, TC_CCB, TIMER_EXAMPLE_PERIOD/2); /* Enables the CCA and CCB channels*/ tc_enable_cc_channels(&TIMER_EXAMPLE,TC_CCAEN); tc_enable_cc_channels(&TIMER_EXAMPLE,TC_CCAEN); /* Configures the waveform genertaor in Dual Slope mode and Top*/ tc_set_wgm(&TIMER_EXAMPLE,TC_WG_DS_T); /* Enables and configures the deadtime of CCA and CCB outputs*/ tc_awex_enable_cca_deadtime(&AWEXE); tc_awex_enable_ccb_deadtime(&AWEXE); tc_awex_set_dti_high(&AWEXE, TIMER_EXAMPLE_PERIOD/6); tc_awex_set_dti_low(&AWEXE, TIMER_EXAMPLE_PERIOD/6); /* Outputs CCA and CCB on Port E0 and E1*/ tc_awex_set_output_override(&AWEXE, 0x03); tc_set_resolution(&TIMER_EXAMPLE, 10000); do { /* Go to sleep, everything is handled by interrupts. */ sleepmgr_enter_sleep(); } while (1); }
void TimerC0_init(void) { tc_write_clock_source(&TCC0,TC_CLKSEL_DIV64_gc);//1 tc_set_wgm(&TCC0,TC_WG_SS); tc_write_period(&TCC0,0x77);//0x01DFF tc_set_direction(&TCC0,TC_UP); tc_enable_cc_channels(&TCC0,TC_CCAEN); tc_enable_cc_channels(&TCC0,TC_CCBEN); tc_enable(&TCC0); tc_write_cc(&TCC0,TC_CCA,0x5D); };
/** * \brief Start a PWM channel * * This function enables a channel with a given duty cycle. * * \param *config Pointer to the PWM configuration struct * \param duty_cycle_scale Duty cycle as a value between 0 and 100. */ void pwm_start(struct pwm_config *config, uint8_t duty_cycle_scale) { /* Set given duty cycle */ pwm_set_duty_cycle_percent(config, duty_cycle_scale); /* Set correct TC period */ tc_write_period(config->tc, config->period); /* Enable CC channel for this TC */ tc_enable_cc_channels(config->tc, config->cc_mask); /* Enable TC by setting correct clock prescaler */ tc_write_clock_source(config->tc, config->clk_sel); }
static void prvSetupTimerInterrupt(void) { // Use TCC0 as a tick counter. If this is to be changed, change ISR as well tc_enable(&TCC0); tc_set_wgm(&TCC0, TC_WG_NORMAL); // Select the clock source and prescale by 64 tc_write_clock_source(&TCC0, TC_CLKSEL_DIV64_gc); //set period of counter tc_write_period(&TCC0, configCPU_CLOCK_HZ / configTICK_RATE_HZ / 64 - 1); //enable interrupt and set low level //tc_set_overflow_interrupt_callback(&TCC0, tickTimer); tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO); cpu_irq_enable(); }
static void qdec_enabled_tc(qdec_config_t *config) { /* Configure TC for quadrature decode for event action and * event channel selection: * - Set event source and event action as per sent parameters * - Load Period register of TC with number of counts for single * revolution * - Write clock value and start timer */ tc_enable(config->timer); tc_set_input_capture(config->timer, (TC_EVSEL_t)(TC_EVSEL_CH0_gc + config->event_channel), TC_EVACT_QDEC_gc); tc_write_count(config->timer, 0); tc_write_period(config->timer, config->revolution - 1); tc_write_clock_source(config->timer, TC_CLKSEL_DIV1_gc); }
static void init_timer_isr( void ) { tc_enable(&TCD0); /* We divide the peripheral 2MHz clock by 2 to get 1MHz*/ tc_write_clock_source(&TCD0, TC_CLKSEL_DIV2_gc); /* Set Compare A interrupt to low level */ tc_set_cca_interrupt_level(&TCD0, TC_INT_LVL_LO); /* 1000 counts is 1ms at 1MHz input clock */ tc_write_period (&TCD0, 1000 * qt_measurement_period_msec); /* Handling callback */ tc_set_cca_interrupt_callback(&TCD0, touch_timer_callback); /* Enable CCA */ tc_enable_cc_channels(&TCD0, TC_CCAEN); }
void sha204_delay_us(uint16_t delay) { // Configure TC resolution and period (value at which overflow is triggered). tc_set_resolution(DELAY_COUNTER, 1000000); // causes a divisor value of 8 => 250 ns for system clock = 32 MHz // Get actual resolution. uint32_t resolution = tc_get_resolution(DELAY_COUNTER); // Write value for delay to counter register. tc_write_period(DELAY_COUNTER, (resolution * (uint32_t) delay) / 1000000); // Restart counter. tc_restart(DELAY_COUNTER); // Reset timeout flag. sha204_timer_expired = false; // Wait for timer to expire. while (sha204_timer_expired == false); }
int main (void) { sysclk_init(); board_init(); pmic_init(); gfx_mono_init(); adc_sensors_init(); // Enable display backlight gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT); cpu_irq_enable(); while(true){ if(state==1){ start_game(); }else if(state==2){ tc_enable(&TCC0); tc_set_overflow_interrupt_callback(&TCC0, sun_count); tc_set_wgm(&TCC0, TC_WG_NORMAL); tc_write_period(&TCC0, 13500); tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO); tc_write_clock_source(&TCC0, TC_CLKSEL_DIV256_gc); tc_enable(&TCC1); tc_set_overflow_interrupt_callback(&TCC1, button_press); tc_set_wgm(&TCC1, TC_WG_NORMAL); tc_write_period(&TCC1, 62500); tc_set_overflow_interrupt_level(&TCC1, TC_INT_LVL_LO); tc_write_clock_source(&TCC1, TC_CLKSEL_DIV8_gc); gfx_mono_draw_string("SUN: 0", 0, 0, &sysfont); gfx_mono_draw_string(">", 0, cursor_position, &sysfont); gfx_mono_draw_string("Score: 0", 63, 0, &sysfont); randomPeta(); char* score_string = NULL; uint16_t old_score = 0; for(j = 0; j <= 70; j++){ if(sun_value > 10){ lightsensor_measure(); while (!lightsensor_data_is_ready()) { // Wait until the conversion is complete } if(lightsensor_get_raw_value() > 250){ sun_value -= 10; sunBurst(); gfx_mono_draw_filled_rect(12,8,114,24,GFX_PIXEL_CLR); } } if(score > old_score){ sprintf(score_string, "%3d", score); gfx_mono_draw_string(score_string, 100, 0, &sysfont); old_score = score; } if(lose){ state=3; break; }else if(zombie==0){ state=4; break; } tampilkanPeta(); tampilkanTembak(); delay_ms(1000); } }else if(state==3){ cpu_irq_disable(); gfx_mono_draw_filled_rect(0,0,128,32,GFX_PIXEL_CLR); while(true){ gfx_mono_draw_string("GAME OVER",36,8,&sysfont) ; gfx_mono_draw_string("You Lose",39,20,&sysfont) ; } }else if(state==4){ cpu_irq_disable(); gfx_mono_draw_filled_rect(0,0,128,32,GFX_PIXEL_CLR); while(true){ gfx_mono_draw_string("GAME OVER",36,2,&sysfont) ; gfx_mono_draw_string("You Win",42,12,&sysfont) ; gfx_mono_draw_string("Score = ",30,22,&sysfont) ; char* score_string = NULL; sprintf(score_string, "%3d", score); gfx_mono_draw_string(score_string, 79, 22, &sysfont); } } } }
/** * \brief Test read from fixed location, trigger from timer and callback * * \note This test sets up a timer to trigger the DMA module, * which in turn reads the timer_overflow_counter variable and writes * it to memory sequentially. It then checks to see that the memory block * written is sequential according to the overflow count. * * \param test Current test */ static void run_dma_triggered_with_callback(const struct test_case *test) { struct dma_channel_config config_params; bool success; /* Null the buffer */ set_buffer(dest_block_tc, 0x0000); /* Null out the config parameter struct */ memset(&config_params, 0, sizeof(config_params)); /* * Enable the timer, and set it to count up. * When it overflows, it triggers the DMA to * read timer_overflow_counter. */ tc_enable(&TIMER); tc_set_direction(&TIMER, TC_UP); tc_write_period(&TIMER, TIMER_PERIOD); tc_set_resolution(&TIMER, TIMER_RESOLUTION); tc_set_overflow_interrupt_level(&TIMER, PMIC_LVL_LOW); tc_set_overflow_interrupt_callback(&TIMER, timer_overflow_callback); /* Enable the DMA module */ dma_enable(); /* Set callback for transfer done */ dma_set_callback(DMA_CHANNEL_0, dma_transfer_is_complete); /* Set low interrupt level */ dma_channel_set_interrupt_level(&config_params, PMIC_LVL_LOW); /* Set up the DMA to read the timer value * * - Single shot transfer mode * - Two byte (16-bit) burst length * - Increment on source and destination * - Reload on burst for source * - No reload for destination */ dma_channel_set_single_shot(&config_params); dma_channel_set_burst_length(&config_params, DMA_CH_BURSTLEN_1BYTE_gc); dma_channel_set_src_reload_mode(&config_params, DMA_CH_SRCRELOAD_BURST_gc); dma_channel_set_src_dir_mode(&config_params, DMA_CH_SRCDIR_FIXED_gc); dma_channel_set_dest_reload_mode(&config_params, DMA_CH_DESTRELOAD_NONE_gc); dma_channel_set_dest_dir_mode(&config_params, DMA_CH_DESTDIR_INC_gc); /* Set trigger source to TCC0's overflow */ dma_channel_set_trigger_source(&config_params, DMA_CH_TRIGSRC_TCC0_OVF_gc); /* Transfer DEST_BLOCK_TC_SIZE bytes */ dma_channel_set_transfer_count(&config_params, DEST_BLOCK_TC_SIZE); /* Set address */ dma_channel_set_source_address(&config_params, (uint16_t)(uintptr_t)&timer_overflow_counter); dma_channel_set_destination_address(&config_params, (uint16_t)(uintptr_t)dest_block_tc); /* Reset the channel */ dma_channel_reset(DMA_CHANNEL_0); /* Write the config */ dma_channel_write_config(DMA_CHANNEL_0, &config_params); /* Enable the channel */ dma_channel_enable(DMA_CHANNEL_0); /* Wait for transfer to finish */ while (!dma_has_completed) { /* Intentionally left empty */ } /* Disable DMA */ dma_disable(); /* Verify that the result is as expected */ success = block_compare(dest_block_tc, expected_result_tc, DEST_BLOCK_TC_SIZE); test_assert_true(test, success, "Result is not as expected"); }
static void qdec_enabled_tc_freq(qdec_config_t *config) { volatile uint8_t *evsys_chctrl, *evsys_chctrl_freq; /* Configuration of frequency calculation */ Assert(config->event_channel != config->freq_opt.event_channel); if (config->index.enabled) { Assert((config->event_channel + 1) != config->freq_opt.event_channel); } #if XMEGA_E /* Channel must be < 4, because QDec channel is 0 * and EVSYS.DFCTRL enables filter per event group */ Assert(config->freq_opt.event_channel < 4); #endif /* In event channel enable digital filter as QDec event channel */ #if XMEGA_E if (EVSYS.DFCTRL & EVSYS_PRESCFILT_CH04_gc) { if (config->freq_opt.event_channel == 1) { EVSYS.DFCTRL |= EVSYS_PRESCFILT_CH15_gc; } else if (config->freq_opt.event_channel == 2) { EVSYS.DFCTRL |= EVSYS_PRESCFILT_CH26_gc; } else { EVSYS.DFCTRL |= EVSYS_PRESCFILT_CH37_gc; } } #endif evsys_chctrl_freq = &EVSYS.CH0CTRL + config->freq_opt.event_channel; evsys_chctrl = &EVSYS.CH0CTRL + config->event_channel; *evsys_chctrl_freq = *evsys_chctrl & EVSYS_DIGFILT_gm; /* Configure event channel for frequency calculation */ qdec_evsys_pin_2_chmux(config->port, config->pins_base, config->freq_opt.event_channel); /* Configure TC to capture frequency * Load timer period register * Enable capture on CCA channel * Select timer clock source */ tc_enable(config->freq_opt.timer); tc_set_input_capture(config->freq_opt.timer, (TC_EVSEL_t)(TC_EVSEL_CH0_gc + config->freq_opt.event_channel), TC_EVACT_FRQ_gc); tc_write_count(config->freq_opt.timer, 0); tc_write_period(config->freq_opt.timer, 0xFFFF); tc_enable_cc_channels(config->freq_opt.timer, TC_CCAEN); tc_set_resolution(config->freq_opt.timer, (config->freq_opt.unit / 1000) / config->revolution); config->freq_opt.coef = (((uint64_t)tc_get_resolution(config->freq_opt.timer) * 1000) / config->freq_opt.unit) * 4 / config->revolution; config->freq_opt.last_freq = 0; /* Initialize frequence to 0Hz */ }