Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/**
 * \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);
}
Ejemplo n.º 3
0
/**
 * \internal
 * \brief Generate a delay in ms
 *
 * \param delay_ms  Number of ms to wait
 */
static void main_delay_ms(uint16_t delay_ms)
{
	uint16_t ticks_delay;

	tc_write_count(CONF_DELAY_TC, 0);
	ticks_delay = (uint64_t)tc_get_resolution(CONF_DELAY_TC) * delay_ms
			/ 1000;
	while (ticks_delay > tc_read_count(CONF_DELAY_TC)) {
	}
}
Ejemplo n.º 4
0
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);
}
/**
 * \brief Get resolution in Hz for TC clock selection.
 * \internal
 *
 * \param tc_id     ID of TC.
 * \param timer_res Clock selection for TC.
 *
 * \return TC resolution in Hz.
 */
uint32_t tc_timer_get_resolution(uint8_t tc_id, timer_res_t timer_res)
{
	return tc_get_resolution(tc_id, timer_res);
}
Ejemplo n.º 6
0
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 */
}