/** * \internal * \brief QDEC Unit Test Clean up for XMEGA PORT D and QDEC * * \param test Current test case * \param config Configuration of QDec * \param sequence Test sequence to execute * \param seq_size size of test sequence */ static void generator_qenc_seq(const struct test_case *test, qdec_config_t *config, struct qenc_step *sequence, uint8_t seq_size) { uint16_t pos; for (uint8_t i = 0; i < seq_size; i++) { generator_qenc(sequence[i].encoder); main_delay_ms(10); pos = qdec_get_position(config); test_assert_true(test, sequence[i].qdec_pos == pos, "QDec sequence failure: expected %u, catched %u\r\n", sequence[i].qdec_pos, pos); } }
void app_sampling_task(void) { static uint16_t time_stamp; static uint8_t time_last; uint8_t time_pos; adc_result_t light; char string[30]; uint8_t light_bar_pos; irqflags_t flags; static uint16_t qdec_position_last = 2; uint16_t qdec_position; /* Manage frequency sample through Quadrature encoder */ qdec_position = qdec_get_position(&qdec_config) / 2; if (qdec_position != qdec_position_last) { /* Quadrature encoder have changed */ qdec_position_last = qdec_position; app_sampling_rate = (qdec_position_last + 1) * 2; flags = cpu_irq_save(); if (app_sampling_rtc_run) { time_stamp = rtc_get_time(); rtc_set_alarm_relative(app_sampling_rate - 1); } cpu_irq_restore(flags); app_sampling_display_rate(); } /* Update sampling progress bar */ time_pos = ((rtc_get_time() - time_stamp) * 8) / app_sampling_rate; if (time_pos > 8) { time_pos = 8; } if (time_last > time_pos) { gfx_mono_draw_filled_circle( DISPLAY_SAMPLING_PROCIRCLE_POS_X, DISPLAY_SAMPLING_PROCIRCLE_POS_Y, DISPLAY_SAMPLING_PROCIRCLE_RADIUS, GFX_PIXEL_CLR, GFX_WHOLE); } if (time_last != time_pos) { gfx_mono_draw_filled_circle( DISPLAY_SAMPLING_PROCIRCLE_POS_X, DISPLAY_SAMPLING_PROCIRCLE_POS_Y, DISPLAY_SAMPLING_PROCIRCLE_RADIUS, GFX_PIXEL_SET, (1lu << time_pos) - 1); } time_last = time_pos; /* Manage FIFO about sensor data */ if (2 > fifo_get_used_size(&app_sampling_fifo_desc)) { return; /* Not enought data */ } /* Get values */ time_stamp = fifo_pull_uint16_nocheck(&app_sampling_fifo_desc); light = (adc_result_t)fifo_pull_uint16_nocheck(&app_sampling_fifo_desc); /* Display values through USART */ sprintf(string, "%4u,%02us - %3d light\r\n", time_stamp / 4, (time_stamp % 4) * 25, light); printf("%s", string); /* Update light progress bar */ light_bar_pos = ((uint32_t)light * DISPLAY_LIGHT_PROBAR_MAX_SIZE_X) / 2048lu; if (light_bar_pos > DISPLAY_LIGHT_PROBAR_MAX_SIZE_X) { light_bar_pos = DISPLAY_LIGHT_PROBAR_MAX_SIZE_X; } gfx_mono_draw_filled_rect(DISPLAY_LIGHT_PROBAR_POS_X, DISPLAY_LIGHT_PROBAR_POS_Y, light_bar_pos, DISPLAY_LIGHT_PROBAR_SIZE_Y, GFX_PIXEL_SET); gfx_mono_draw_filled_rect(DISPLAY_LIGHT_PROBAR_POS_X + light_bar_pos, DISPLAY_LIGHT_PROBAR_POS_Y, DISPLAY_LIGHT_PROBAR_MAX_SIZE_X - light_bar_pos, DISPLAY_LIGHT_PROBAR_SIZE_Y, GFX_PIXEL_CLR); }
/** * \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); } } } }