/** * \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); }
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 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 */ }