int main(void) { /* Usual initializations */ board_init(); sysclk_init(); sleepmgr_init(); irq_initialize_vectors(); cpu_irq_enable(); /* * Configure TCC4 to generate 50ms overflow interrupt * using 500kHz (2us) resolution clock (50ms = 25000 * 2us) */ /* Unmask clock for TCC4 */ tc45_enable(&TCC4); /* Enable overflow interrupt */ tc45_set_overflow_interrupt_level(&TCC4, TC45_INT_LVL_LO); /* Configure TC in normal mode */ tc45_set_wgm(&TCC4, TC45_WG_NORMAL); /* Configure call back interrupt */ tc45_set_overflow_interrupt_callback(&TCC4, example_overflow_interrupt_callback); /* Configure TC period and resolution */ tc45_write_period(&TCC4, 25000); tc45_set_resolution(&TCC4, 500000); /* * Configure TCD5 to generate 2ms Single Slope PWM */ /* Unmask clock for TCD5 */ tc45_enable(&TCD5); /* Configure TC in PWM Single Slope PWM */ tc45_set_wgm(&TCD5, TC45_WG_SS); /* Use the max period (2MHz / FFFFh = 30Hz) */ tc45_write_period(&TCC4, 0xFFFF); /* Initialize and enable Channel A */ tc45_write_cc(&TCD5, TC45_CCA, 0); tc45_enable_cc_channels(&TCD5, TC45_CCACOMP); /* Run TC at 2MHz clock resolution (CPU frequency 32MHz) */ tc45_set_resolution(&TCD5, 20000000); do { /* Go to sleep, everything is handled by interrupts. */ sleepmgr_enter_sleep(); } while (1); }
int main(void) { /* Usual initializations */ board_init(); sysclk_init(); sleepmgr_init(); irq_initialize_vectors(); cpu_irq_enable(); /* Unmask clock for TCC4 */ tc45_enable(&TCC4); /* Configure TC in normal mode */ tc45_set_wgm(&TCC4, TC45_WG_NORMAL); /* Configure period equal to resolution to obtain 1Hz */ tc45_write_period(&TCC4, TIMER_EXAMPLE_RESOLUTION); /* Configure CCA to occur at the middle of TC period */ tc45_write_cc(&TCC4, TC45_CCA, TIMER_EXAMPLE_RESOLUTION / 2); /* Configure CCB to occur at the quarter of TC period */ tc45_write_cc(&TCC4, TC45_CCB, TIMER_EXAMPLE_RESOLUTION / 4); /* Enable both CCA and CCB channels */ tc45_enable_cc_channels(&TCC4, TC45_CCACOMP); tc45_enable_cc_channels(&TCC4, TC45_CCBCOMP); /* * Configure interrupts callback functions for TCC4 * overflow interrupt, CCA interrupt and CCB interrupt */ tc45_set_overflow_interrupt_callback(&TCC4, example_ovf_interrupt_callback); tc45_set_cca_interrupt_callback(&TCC4, example_cca_interrupt_callback); tc45_set_ccb_interrupt_callback(&TCC4, example_ccb_interrupt_callback); /* * Enable TC interrupts (overflow, CCA and CCB) */ tc45_set_overflow_interrupt_level(&TCC4, TC45_INT_LVL_LO); tc45_set_cca_interrupt_level(&TCC4, TC45_INT_LVL_LO); tc45_set_ccb_interrupt_level(&TCC4, TC45_INT_LVL_LO); /* * Run TCC4 */ tc45_set_resolution(&TCC4, TIMER_EXAMPLE_RESOLUTION); do { /* Go to sleep, everything is handled by interrupts. */ sleepmgr_enter_sleep(); } while (1); }
// setup the board instead of board_init() as recommended by ASF.. because christmas lights, that's why. void init (void) { static usart_serial_options_t usart_options = { .baudrate = USART_SERIAL_BAUDRATE, .charlength = USART_SERIAL_CHAR_LENGTH, .paritytype = USART_SERIAL_PARITY, .stopbits = USART_SERIAL_STOP_BIT }; // initialize ASF stuff board_init(); sysclk_init(); ioport_init(); pmic_init(); pmic_set_scheduling(PMIC_SCH_FIXED_PRIORITY); // remap, enable TX, and configure USART on PORT C PORTC.REMAP |= PR_USART0_bm; PORTC.DIR |= (1 << PIN7_bp); sysclk_enable_module(SYSCLK_PORT_C, PR_USART0_bm); usart_init_rs232(USART_SERIAL, &usart_options); // setup timer for PWM tc45_enable(&TCC4); tc45_set_overflow_interrupt_callback(&TCC4, pwm_callback); tc45_set_wgm(&TCC4, TC45_WG_NORMAL); tc45_write_period(&TCC4, 256); tc45_set_overflow_interrupt_level(&TCC4, TC45_INT_LVL_MED); // enable all channels and turn off (high) ioport_set_port_dir(IOPORT_PORTA, PORTA_MASK, IOPORT_DIR_OUTPUT); ioport_set_port_dir(IOPORT_PORTD, PORTD_MASK, IOPORT_DIR_OUTPUT); ioport_set_port_dir(IOPORT_PORTR, PORTR_MASK, IOPORT_DIR_OUTPUT); ioport_set_port_level(IOPORT_PORTA, PORTA_MASK, 0xFF); ioport_set_port_level(IOPORT_PORTD, PORTD_MASK, 0xFF); ioport_set_port_level(IOPORT_PORTR, PORTR_MASK, 0xFF); for (uint8_t i=0; i<NUM_CHANNELS; i++) { compare[i] = 0; compbuff[i] = 0; } // enable status LEDs and turn off ioport_set_pin_dir(LED_STATUS, IOPORT_DIR_OUTPUT); ioport_set_pin_dir(LED_DATA, IOPORT_DIR_OUTPUT); ioport_set_pin_level(LED_STATUS, 1); ioport_set_pin_level(LED_DATA, 1); // enable interrupts and start timer for PWM cpu_irq_enable(); tc45_write_clock_source(&TCC4, TC45_CLKSEL_DIV2_gc); }
int main(void) { uint8_t otmx_mode_index = 0; bool btn_released = true; /* Usual initializations */ board_init(); sysclk_init(); sleepmgr_init(); irq_initialize_vectors(); cpu_irq_enable(); /* Enables the Timers defined in conf_example.h : TCC4 (1) and TCC5 (2) *in this example */ tc45_enable(&TCC4); tc45_enable(&TCC5); /* Configures the interrupt level of CCA and CCB modules of the 2 *Timers: low */ tc45_set_cca_interrupt_level(&TCC4, TC45_INT_LVL_LO); tc45_set_ccb_interrupt_level(&TCC4, TC45_INT_LVL_LO); tc45_set_cca_interrupt_level(&TCC5, TC45_INT_LVL_LO); tc45_set_ccb_interrupt_level(&TCC5, TC45_INT_LVL_LO); /* Declares the interrupt functions which will be called when CCA and * CCB * interrupts will occur */ tc45_set_cca_interrupt_callback(&TCC4, example_cca_tcc4_interrupt_callback); tc45_set_ccb_interrupt_callback(&TCC4, example_ccb_tcc4_interrupt_callback); tc45_set_cca_interrupt_callback(&TCC5, example_cca_tcc5_interrupt_callback); tc45_set_ccb_interrupt_callback(&TCC5, example_ccb_tcc5_interrupt_callback); /* Configures the Timer periods*/ tc45_write_period(&TCC4, TIMER_TCC4_PERIOD); tc45_write_period(&TCC5, TIMER_TCC5_PERIOD); /* Configures the CCA and CCB levels*/ tc45_write_cc(&TCC4, TC45_CCA, TIMER_TCC4_PERIOD / 2); tc45_write_cc(&TCC4, TC45_CCB, TIMER_TCC4_PERIOD / 2); tc45_write_cc(&TCC5, TC45_CCA, TIMER_TCC5_PERIOD / 4); tc45_write_cc(&TCC5, TC45_CCB, TIMER_TCC5_PERIOD / 4); /* Enables the CCA and CCB channels*/ tc45_enable_cc_channels(&TCC4, TC45_CCACOMP); tc45_enable_cc_channels(&TCC4, TC45_CCBCOMP); tc45_enable_cc_channels(&TCC5, TC45_CCACOMP); tc45_enable_cc_channels(&TCC5, TC45_CCBCOMP); /* Configures the waveform genertaor in Dual Slope mode and Top*/ tc45_set_wgm(&TCC4, TC45_WG_DS_T); tc45_set_wgm(&TCC5, TC45_WG_DS_T); tc45_set_resolution(&TCC4, TIMER_TCC4_TCC5_RESOLUTION); tc45_set_resolution(&TCC5, TIMER_TCC4_TCC5_RESOLUTION); while (1) { /* Go to sleep, everything is handled by interrupts. */ sleepmgr_enter_sleep(); /* Configures the Output Matrix mode */ if (gpio_pin_is_high(GPIO_PUSH_BUTTON_0)) { /* button released */ btn_released = true; continue; } /* button pressed */ if (!btn_released) { /* Wait release of button */ continue; } btn_released = false; /* Change OTMX mode */ otmx_mode_index++; switch (otmx_mode_index) { case 0: tc45_wex_set_otmx(&WEXC, WEX_OTMX_DEFAULT); break; case 1: tc45_wex_set_otmx(&WEXC, WEX_OTMX_1); break; case 2: tc45_wex_set_otmx(&WEXC, WEX_OTMX_2); break; case 3: tc45_wex_set_otmx(&WEXC, WEX_OTMX_3); break; case 4: tc45_wex_set_otmx(&WEXC, WEX_OTMX_4); break; default: otmx_mode_index = -1; break; } } }
/** * \brief Test read from fixed location, trigger from timer and callback * * \note This test sets up a timer to trigger the EDMA module, * which in turn reads the timer45_overflow_counter variable and writes * it to memory sequentially. It then checks to see that the memory block * written is sequential according to the overflow count. This test uses the * event system wired on timer45 overflow as trigger. * * \param test Current test */ static void run_edma_triggered_with_callback(const struct test_case *test) { struct edma_channel_config config_params; bool success; /* Null the buffer */ set_buffer(dest_block_tc45, 0x0000); /* Null out the config parameter struct */ memset(&config_params, 0, sizeof(config_params)); /* Enable the Event System on EVSYS_CH_2 */ EVSYS.CH2MUX = EVSYS_CHMUX_TCC4_OVF_gc; /* * Enable the timer, and set it to count up. * When it overflows, it triggers the EDMA to * read timer45_overflow_counter. */ tc45_set_overflow_interrupt_callback(&TIMER45, timer45_overflow_callback); tc45_enable(&TIMER45); tc45_set_overflow_interrupt_level(&TIMER45, TC45_INT_LVL_LO); tc45_set_direction(&TIMER45, TC45_UP); tc45_write_period(&TIMER45, TIMER45_PERIOD); tc45_set_resolution(&TIMER45, TIMER45_RESOLUTION); /* * Enable the EDMA module, standard channel 0, * peripheral channels 2 and 3 */ edma_enable(EDMA_CHMODE_STD0_gc); /* Set callback for transfer done */ edma_set_callback(EDMA_CH_0, ut_edma_transfer_is_complete); /* Set low interrupt level */ edma_channel_set_interrupt_level(&config_params, EDMA_INT_LVL_LO); /* Set up the EDMA to read the timer value * * - Single shot transfer mode * - 1 byte (16-bit) burst length * - Increment on source and destination * - Reload on burst for source * - No reload for destination */ edma_channel_set_single_shot(&config_params); edma_channel_set_burst_length(&config_params, EDMA_CH_BURSTLEN_1BYTE_gc); edma_channel_set_src_reload_mode(&config_params, EDMA_CH_RELOAD_BURST_gc); edma_channel_set_src_dir_mode(&config_params, EDMA_CH_DIR_FIXED_gc); edma_channel_set_dest_reload_mode(&config_params, EDMA_CH_RELOAD_NONE_gc); edma_channel_set_dest_dir_mode(&config_params, EDMA_CH_DESTDIR_INC_gc); /* Set trigger source to Event Channel 2 (set to TCC4's overflow) */ edma_channel_set_trigger_source(&config_params, EDMA_CH_TRIGSRC_EVSYS_CH2_gc); /* Transfer DEST_BLOCK_TC45_SIZE bytes */ edma_channel_set_transfer_count16(&config_params, DEST_BLOCK_TC45_SIZE); /* Set address */ edma_channel_set_source_address(&config_params, (uint16_t)(uintptr_t)&timer45_overflow_counter); edma_channel_set_destination_address(&config_params, (uint16_t)(uintptr_t)dest_block_tc45); /* Reset the channel */ edma_channel_reset(EDMA_CH_0); /* Write the config */ edma_channel_write_config(EDMA_CH_0, &config_params); /* Enable the channel */ edma_channel_enable(EDMA_CH_0); /* Wait for transfer to finish */ while (!edma_has_completed) { /* Intentionally left empty */ } /* Disable EDMA and stop TC45 interrupts */ tc45_set_overflow_interrupt_level(&TIMER45, TC45_INT_LVL_OFF); edma_disable(); /* Verify that the result is as expected */ success = block_compare(dest_block_tc45, expected_result_tc, DEST_BLOCK_TC45_SIZE); test_assert_true(test, success, "Result is not as expected"); /* * Stop TIMER45: * Already done in EDMA callback "ut_edma_transfer_is_complete()" */ }