void generator_qenc_enable(PORT_t *port, uint8_t pins_base, volatile void *timer, uint8_t revolution, uint32_t freq, bool dir ) { #if XMEGA_E Assert((TC4_t *)timer == &TCC4); #endif /* Store parameter in static global variable */ generator_qenc_port = port; generator_qenc_pins_base = pins_base; generator_qenc_revolution = revolution; generator_qenc_timer = timer; /* Clear all pins on test port */ port->DIRSET = QENC_PH0_PH90_INDEX_PINS << generator_qenc_pins_base; port->OUTCLR = QENC_PH0_PH90_INDEX_PINS << generator_qenc_pins_base; tc_enable(timer); tc_set_wgm(timer, TC_WG_NORMAL); generator_qenc_set_freq(freq); generator_qenc_set_direction(dir); /* Enable low level interrupt on CCA */ tc_set_overflow_interrupt_level(timer, TC_INT_LVL_LO); /* Set interrupt callback function for CCA */ tc_set_overflow_interrupt_callback(timer, generator_qenc_timer_ccaint_handler); }
/** * \brief Main application routine * - Configure system clock * - Call QDec driver API to configure it and enable it * - Call generator of quadrature encoder * - Get position, direction and frequency and display its */ int main( void ) { const usart_serial_options_t usart_serial_options = { .baudrate = CONF_TEST_BAUDRATE, .charlength = CONF_TEST_CHARLENGTH, .paritytype = CONF_TEST_PARITY, .stopbits = CONF_TEST_STOPBITS, }; qdec_config_t config; uint16_t qdec_position, qdec_position_prev = 0; uint32_t generator_qenc_freq = 2000 / QUADRATURE_RESOLUTION; bool generator_qenc_dir = true; /* Usual initializations */ board_init(); sysclk_init(); sleepmgr_init(); irq_initialize_vectors(); cpu_irq_enable(); stdio_serial_init(CONF_TEST_USART, &usart_serial_options); printf("\x0C\n\r-- QDec Example --\n\r"); printf("-- Compiled: %s %s --\n\r\n\r", __DATE__, __TIME__); /* QDec configuration * Here, we use the default hardware ressources * proposed by default configuration. */ qdec_get_config_defaults(&config); qdec_config_phase_pins(&config, CONF_QDEC_PORT, CONF_QDEC_PINS_BASE, false, 1); qdec_config_tc(&config, CONF_QDEC_TC); qdec_config_enable_freq(&config, 1); qdec_config_freq_tc(&config, CONF_QDEC_FREQ_TC); qdec_config_revolution(&config, QUADRATURE_RESOLUTION); /* QDec enable */ qdec_enabled(&config); /* Generate quadrature encoder signals */ generator_qenc_enable(CONF_QDEC_PORT, CONF_QDEC_PINS_BASE, CONF_GENERATOR_QENC_TC, QUADRATURE_RESOLUTION, generator_qenc_freq, generator_qenc_dir); while (1) { /* read position */ qdec_position = qdec_get_position(&config); if (qdec_position_prev != qdec_position) { /* New position then display it */ qdec_position_prev = qdec_position; printf("%02u", qdec_position); /* display direction */ if (qdec_get_direction(&config)) { printf(" ++"); } else { printf(" --"); } /* Display frequency */ printf(" %5umHz\r\n", qdec_get_frequency(&config)); } /* Manage Quadrature encoder generator through UART */ if (usart_rx_is_complete(CONF_TEST_USART)) { char key = getchar(); if (key == 'd') { generator_qenc_dir = !generator_qenc_dir; generator_qenc_set_direction(generator_qenc_dir); } if (key == '-') { if (generator_qenc_freq > QUADRATURE_GENERATOR_FREQ_STEP) { generator_qenc_freq -= QUADRATURE_GENERATOR_FREQ_STEP; generator_qenc_set_freq(generator_qenc_freq); } } if (key == '+') { generator_qenc_freq += QUADRATURE_GENERATOR_FREQ_STEP; generator_qenc_set_freq(generator_qenc_freq); } } } }