Beispiel #1
0
/**
 * \brief Initialize Timer/Counters used to simulate oven actuation signal
 *
 * TCC0 is set up to generate a dual variable frequency signal with dead-time
 * insertion using the AWEX module. This is similar to how heating elements are
 * actuated in real induction ovens. Its output is on pin C2 which is marked as
 * RXD on header J1.
 *
 * TCC1 is set up to capture a frequency signal via a pin change event using the
 * XMEGA Event System. Its input is pin C4 which is marked as SS on header J1.
 */
void main_init_tc(void)
{
    /* Set up timer for PWM output, used to actuate cooking element */
    tc_enable(&OVEN_FREQ_TC);

    /* Configures the waveform generator in Frequency generation mode */
    tc_set_wgm(&OVEN_FREQ_TC, TC_WG_FRQ);

    /* Configures the CCA level. This controls frequency generation */
    tc_write_cc(&OVEN_FREQ_TC, TC_CCA, FREQ_TIMER_PERIOD_INIT / 2);

    /* Enables and configures the deadtime of AWEX channel B outputs */
    tc_awex_enable_ccb_deadtime(&AWEXC);

    tc_awex_set_dti_high(&AWEXC, FREQ_TIMER_PERIOD_INIT / 4);
    tc_awex_set_dti_low(&AWEXC, FREQ_TIMER_PERIOD_INIT / 4);

    /* Output of AWEX channel B is on pins C2 and C3 */
    tc_awex_set_output_override(&AWEXC, 0x0C);

    /* Make sure that the output is initially turned off */
    tc_write_clock_source(&OVEN_FREQ_TC, TC_CLKSEL_OFF_gc);

    /* Set up timer for input capture for the simulation to read "real"
     * power
     */
    tc_enable(&OVEN_FREQ_CAPT_TC);
    /* Select Event Channel 1 as input to the timer, and perform frequency
     * capture.
     */
    tc_set_input_capture(&OVEN_FREQ_CAPT_TC, TC_EVSEL_CH1_gc,
                         TC_EVACT_FRQ_gc);
    /* Enable Capture Channel A */
    tc_enable_cc_channels(&OVEN_FREQ_CAPT_TC, TC_CCAEN);

    /* Make sure pin C4 is configured for input and sensing on rise and fall
     * and pin C2 is configured for output.
     */
    ioport_configure_pin(J1_PIN4, IOPORT_DIR_INPUT | IOPORT_BOTHEDGES);
    ioport_configure_pin(J1_PIN2, IOPORT_DIR_OUTPUT);

    /* Turn on power to the event system */
    PR.PRGEN &= ~PR_EVSYS_bm;
    /* Use pin C4 as input to Event Channel 1 */
    EVSYS.CH1MUX = EVSYS_CHMUX_PORTC_PIN4_gc;

    /* Turn on timer used for input capture */
    tc_write_clock_source(&OVEN_FREQ_CAPT_TC, TC_CLKSEL_DIV256_gc);
}
Beispiel #2
0
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);
}
Beispiel #3
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 */
}