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);
}
Beispiel #2
0
/**
 * \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);
			}
		}
	}
}