/* \brief This is an example that shows how to do the following: * - configure and start the OSC32K 32kHz oscillator, * - set-up a generic clock at 32kHz with the OSC32K osc as a source, * - output the generic clock to a pin, * - toggle all four leds 10 times, * - then switch the device into the static sleep mode (while still maintaining * the OSC32 32kHz oscillator). * */ int main(void) { //! OSC32K config. scif_osc32_opt_t osc32Conf = { SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, // 2-pin Crystal and high current mode. Crystal is connected to XIN32/XOUT32. OSC32_STARTUP, // oscillator startup time true, // select the alternate xin32_2 and xout32_2 for the 32kHz crystal oscillator false, // disable the 1kHz output true // enable the 32kHz output }; volatile int i,j; // - configure and start the OSC32K 32kHz oscillator, if(PASS != scif_start_osc32(&osc32Conf, true)) { // Error while(1) { gpio_tgl_gpio_pin(LED3_GPIO); for(i=1000; i; i--); } } // - set-up a generic clock at 32kHz with the OSC32K osc as a source, // - output the generic clock to a pin. local_start_gc(); // - toggle all four leds 10 times, for(i=25;i;i--) { gpio_tgl_gpio_pin(LED0_GPIO); gpio_tgl_gpio_pin(LED1_GPIO); gpio_tgl_gpio_pin(LED2_GPIO); gpio_tgl_gpio_pin(LED3_GPIO); for(j=1000;j;j--); } // - then switch the device into the static sleep mode (while still maintaining // the OSC32 32kHz oscillator). // If there is a chance that any PB write operations are incomplete, the CPU // should perform a read operation from any register on the PB bus before // executing the sleep instruction. AVR32_INTC.ipr[0]; // Dummy read SLEEP(AVR32_PM_SMODE_STATIC); // Note: in static sleep mode, the GCLK output is not maintained but the OSC32K // oscillator is still active (check the XIN32_2 pin (500mv peek-to-peek amplitude)). while(1); }
/** ** PDCA Init. **/ void init_pdca(void) { // PDCA channel 0/1 options static const pdca_channel_options_t PDCA_CH_OPTIONS = { .addr = (void *)aDataTransfered, // memory address .pid = AVR32_PDCA_PID_USART2_TX, // select peripheral - data are transmit on USART TX line. .size = 0, // transfer counter .r_addr = (void *)aDataTransfered, // next memory address .r_size = sizeof(aDataTransfered), // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE, // select size of one data packet .etrig = true // Trigger transfer on event. }; Disable_global_interrupt(); // Initialize interrupt vectors. INTC_init_interrupts(); // Register the PDCA interrupt handler to the interrupt controller. INTC_register_interrupt(&pdca_int_handler, PDCA_CHANNEL_IRQ, AVR32_INTC_INT0); Enable_global_interrupt(); // Init PDCA channel with the pdca_options. pdca_init_channel(PDCA_CHANNEL_USART, &PDCA_CH_OPTIONS); pdca_channel = pdca_get_handler(PDCA_CHANNEL_USART); // For use in the pdca interrupt handler. // Enable pdca transfer error interrupt & transfer complete interrupt. pdca_enable_interrupt_transfer_error(PDCA_CHANNEL_USART); pdca_enable_interrupt_transfer_complete(PDCA_CHANNEL_USART); // Enable the PEVC channel "PDCA CHANNEL 0/1 ONE-ITEM-TRANSFER" PEVC_CHANNELS_ENABLE(ppevc, 1<<PEVC_PDCA_SOT_USER); // Enable the PDCA. pdca_enable(PDCA_CHANNEL_USART); } /** ** AST Init. **/ void init_ast(void) { avr32_ast_pir0_t pir = { .insel = 14 // Set a event every second }; ast_calendar_t ast_calendar; ast_calendar.FIELD.sec = 30; ast_calendar.FIELD.min = 45; ast_calendar.FIELD.hour = 12; ast_calendar.FIELD.day = 7; ast_calendar.FIELD.month= 10; ast_calendar.FIELD.year = 9; scif_osc32_opt_t opt; opt.mode = SCIF_OSC_MODE_2PIN_CRYSTAL; opt.startup = AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC; // Start OSC_32KHZ scif_start_osc32(&opt,true); // Initialize the AST if (!ast_init_calendar(&AVR32_AST, AST_OSC_32KHZ, AST_PSEL_32KHZ_1HZ, ast_calendar)) { print_dbg("Error initializing the AST\r\n"); while(1); } ast_set_periodic0_value(&AVR32_AST,pir); ast_enable_periodic0(&AVR32_AST); // Clear All Interrupt AVR32_AST.scr=0xFFFFFFFF; // Enable the AST ast_enable(&AVR32_AST); } /*! \brief Initializes the MCU system clocks. */ static void init_sys_clocks(void) { /*! \name System Clock Frequencies */ //! @{ static pcl_freq_param_t pcl_freq_param = { .cpu_f = FCPU_HZ, .pba_f = FPBA_HZ, .osc0_f = FOSC0, .osc0_startup = OSC0_STARTUP }; //! @} // Configure system clocks. if (pcl_configure_clocks(&pcl_freq_param) != PASS) { while(1); } } /*! \brief This example show a DMA transfer to USART controlled by the AST periodic alarm using the PEVC. */ int main(void) { int i; // Init the string with a simple recognizable pattern. for(i=0;i<sizeof(aDataTransfered);i++) aDataTransfered[i] = '0' + (i%36); init_sys_clocks(); init_usart(); gpio_clr_gpio_pin(LED0_GPIO); init_pevc(); init_ast(); init_pdca(); while(1) { gpio_tgl_gpio_pin(LED1_GPIO); delay_ms(500); //Wait 500ms } }
/*! * \brief main function : do init and loop (poll if configured so) */ int main(void) { char temp[20]; char *ptemp; static const gpio_map_t USART_GPIO_MAP = { {EXAMPLE_USART_RX_PIN, EXAMPLE_USART_RX_FUNCTION}, {EXAMPLE_USART_TX_PIN, EXAMPLE_USART_TX_FUNCTION} }; /* USART options */ static const usart_options_t USART_OPTIONS = { .baudrate = 57600, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = 0 }; #if BOARD == UC3L_EK scif_osc32_opt_t opt = { /* * 2-pin Crystal connected to XIN32/XOUT32 and high current * mode. */ SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, /* oscillator startup time */ AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC, /* * select alternate xin32_2 and xout32_2 for 32kHz crystal * oscillator */ true, /* disable the 1kHz output */ false, /* enable the 32kHz output */ true }; #else scif_osc32_opt_t opt; opt.mode = SCIF_OSC_MODE_2PIN_CRYSTAL; opt.startup = AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC; #endif #if BOARD == UC3L_EK /* * Note: on the AT32UC3L-EK board, there is no crystal/external clock * connected to the OSC0 pinout XIN0/XOUT0. We shall then program the * DFLL and switch the main clock source to the DFLL. */ pcl_configure_clocks(&pcl_dfll_freq_param); /* * Note: since it is dynamically computing the appropriate field values * of the configuration registers from the parameters structure, this * function is not optimal in terms of code size. For a code size * optimal solution, it is better to create a new function from * pcl_configure_clocks_dfll0() and modify it to use preprocessor * computation from pre-defined target frequencies. */ #else pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP); #endif /* Start OSC_32KHZ */ scif_start_osc32(&opt, true); /* Assign GPIO pins to USART0. */ gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0])); /* Initialize USART in RS232 mode */ usart_init_rs232(EXAMPLE_USART, &USART_OPTIONS, FPBA); /* Welcome message */ usart_write_line(EXAMPLE_USART, "\x1B[2J\x1B[H\r\nATMEL\r\n"); usart_write_line(EXAMPLE_USART, "AVR32 UC3 - AST example\r\n"); usart_write_line(EXAMPLE_USART, "AST 32 KHz oscillator program test.\r\n"); ast_calendar_t ast_calendar; ast_calendar.FIELD.sec = 0; ast_calendar.FIELD.min = 15; ast_calendar.FIELD.hour = 12; ast_calendar.FIELD.day = 5; ast_calendar.FIELD.month = 6; ast_calendar.FIELD.year = 9; /* Initialize the AST */ if (!ast_init_calendar(&AVR32_AST, AST_OSC_32KHZ, AST_PSEL_32KHZ_1HZ, ast_calendar)) { usart_write_line(EXAMPLE_USART, "Error initializing the AST\r\n"); while (1) { } } /* Enable the AST */ ast_enable(&AVR32_AST); volatile int i; while (1) { /* slow down operations */ for (i = 0; i < 10000; i++) { } gpio_tgl_gpio_pin(LED0_GPIO); /* Set cursor to the position (1; 5) */ usart_write_line(EXAMPLE_USART, "\x1B[5;1H"); ast_calendar = ast_get_calendar_value(&AVR32_AST); usart_write_line(EXAMPLE_USART, "Timer: "); ptemp = print_i(temp, ast_calendar.FIELD.sec); usart_write_line(EXAMPLE_USART, ptemp); usart_write_line(EXAMPLE_USART, " sec "); } }
/*! * \brief main function : do init and loop (poll if configured so) */ int main(void) { char temp[20]; char *ptemp; uint32_t ast_alarm; static const gpio_map_t USART_GPIO_MAP = { {EXAMPLE_USART_RX_PIN, EXAMPLE_USART_RX_FUNCTION}, {EXAMPLE_USART_TX_PIN, EXAMPLE_USART_TX_FUNCTION} }; /* USART options */ static const usart_options_t USART_OPTIONS = { .baudrate = 57600, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = 0 }; #if BOARD == UC3L_EK scif_osc32_opt_t opt = { /* 2-pin Crystal connected to XIN32/XOUT32 and high current * mode. */ SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, /* oscillator startup time */ AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC, /* select alternate xin32_2 and xout32_2 for 32kHz crystal * oscillator */ true, /* disable the 1kHz output */ false, /* enable the 32kHz output */ true }; #else scif_osc32_opt_t opt; opt.mode = SCIF_OSC_MODE_2PIN_CRYSTAL; opt.startup = AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC; #endif #if BOARD == UC3L_EK /* * Note: on the AT32UC3L-EK board, there is no crystal/external clock * connected to the OSC0 pinout XIN0/XOUT0. We shall then program the * DFLL and switch the main clock source to the DFLL. */ pcl_configure_clocks(&pcl_dfll_freq_param); /* * Note: since it is dynamically computing the appropriate field values * of the configuration registers from the parameters structure, this * function is not optimal in terms of code size. For a code size * optimal solution, it is better to create a new function from * pcl_configure_clocks_dfll0() and modify it to use preprocessor * computation from pre-defined target frequencies. */ #else pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP); #endif /* Start OSC_32KHZ */ scif_start_osc32(&opt, true); /* Assign GPIO pins to USART0. */ gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0])); /* Initialize USART in RS232 mode */ usart_init_rs232(EXAMPLE_USART, &USART_OPTIONS, FPBA); /* Welcome sentence // 2-pin Crystal and high current mode. */ /* Crystal is connected to XIN32/XOUT32. */ usart_write_line(EXAMPLE_USART, "\x1B[2J\x1B[H\r\nATMEL\r\n"); usart_write_line(EXAMPLE_USART, "AVR32 UC3 - AST example 2\r\n"); usart_write_line(EXAMPLE_USART, "AST 32 KHz oscillator counter example.\r\n"); usart_write_line(EXAMPLE_USART, "Alarm0 wakeup from static sleep mode every second.\r\n"); /* Using counter mode and set it to 0 */ unsigned long ast_counter = 0; /* Initialize the AST */ if (!ast_init_counter(&AVR32_AST, AST_OSC_32KHZ, AST_PSEL_32KHZ_1HZ, ast_counter)) { usart_write_line(EXAMPLE_USART, "Error initializing the AST\r\n"); while (1) { } } /* Alarm 0 sends a wakeup signal to the Power manager */ ast_enable_alarm_async_wakeup(&AVR32_AST, 0); /* Enable the AST */ ast_enable(&AVR32_AST); while (1) { /* disable alarm 0 */ ast_disable_alarm0(&AVR32_AST); /* ast_init_counter Set Alarm to current time+30 seconds */ ast_alarm = ast_counter + 1; ast_set_alarm0_value(&AVR32_AST, ast_alarm); /* Enable alarm 0 */ ast_enable_alarm0(&AVR32_AST); /* * Precautions when entering a sleep mode * Modules communicating with external circuits should normally * be disabled before entering a sleep mode that will stop the * module operation. * Make sure the USART dumps the last message completely before * turning it off. */ while (!usart_tx_empty(EXAMPLE_USART)) { } pcl_disable_module(EXAMPLE_USART_CLOCK_MASK); /* * Since we're going into a sleep mode deeper than IDLE, all HSB * masters must be stopped before entering the sleep mode. * Note: since we're not using the PDCA, we don't have to stop *it. */ /* * If there is a chance that any PB write operations are *incomplete, * the CPU should perform a read operation from any register on *the * PB bus before executing the sleep instruction. */ AVR32_INTC.ipr[0]; /* Dummy read */ /* Go into static sleep mode */ SLEEP(AVR32_PM_SMODE_STATIC); /* We're out of the static sleep mode now => re-enable the USART * module */ pcl_enable_module(EXAMPLE_USART_CLOCK_MASK); /* After wake up, clear the Alarm0 */ ast_clear_alarm_status_flag(&AVR32_AST, 0); /* Toggle Led0 */ gpio_tgl_gpio_pin(LED0_GPIO); /* Set cursor to the position (1; 6) */ usart_write_line(EXAMPLE_USART, "\x1B[6;1H"); ast_counter = ast_get_counter_value(&AVR32_AST); usart_write_line(EXAMPLE_USART, "Timer: "); ptemp = print_i(temp, ast_counter); usart_write_line(EXAMPLE_USART, ptemp); usart_write_line(EXAMPLE_USART, " sec "); } }
/** * \brief Initializes the ACIFB module with trigger * - Start the GCLK for ACIFB * - Initialize the trigger mode & compare interrupts for ACIFB * * \retval STATUS_OK Configuration OK * \retval ERR_TIMEOUT Timeout on configuring ACIFB module * \retval ERR_BUSY ACIFB module unable to configure the trigger */ static status_code_t ac_init() { /* struct genclk_config gcfg; */ uint32_t div = sysclk_get_pba_hz() / AC_GCLK_FREQUENCY; scif_gc_setup(AC_GCLK_ID, AC_GCLK_SRC, AVR32_GC_DIV_CLOCK, div); /* Now enable the generic clock */ scif_gc_enable(AC_GCLK_ID); /* GPIO pin/acifb - function map. */ static const gpio_map_t ACIFB_GPIO_MAP = { {EXAMPLE_ACIFBP_PIN, EXAMPLE_ACIFBP_FUNCTION}, {EXAMPLE_ACIFBN_PIN, EXAMPLE_ACIFBN_FUNCTION}, }; /* ACIFB Configuration */ const acifb_t acifb_opt = { .sut = 6, /* Resolution mode */ .actest = TESTMODE_OFF, .eventen = true }; /* ACIFB Channel Configuration */ const acifb_channel_t acifb_channel_opt = { /* Filter length */ .filter_len = 0, /* Hysteresis value */ .hysteresis_value = 0, /* Output event when ACOUT is zero? */ .event_negative = false, /* Output event when ACOUT is one? */ .event_positive = false, /* Set the positive input */ .positive_input = PI_ACP, /* Set the negative input */ .negative_input = NI_ACN, /* Set the comparator mode */ .mode = MODE_EVENT_TRIGGERED, /* Interrupt settings */ .interrupt_settings = IS_VINP_LT_VINN, /* Analog comparator channel number */ .ac_n = EXAMPLE_ACIFB_CHANNEL }; /* Enable Analog Comparator clock */ sysclk_enable_pba_module(SYSCLK_ACIFB); /* Disable pullup on ACIFB channel input pins */ gpio_disable_pin_pull_up(EXAMPLE_ACIFBP_PIN); gpio_disable_pin_pull_up(EXAMPLE_ACIFBN_PIN); /* Enable the ACIFB pins */ gpio_enable_module(ACIFB_GPIO_MAP, sizeof(ACIFB_GPIO_MAP) / sizeof(ACIFB_GPIO_MAP[0])); /* Configure the ACIFB peripheral */ acifb_setup_and_enable(acifb, &acifb_opt); /* Configure the ACIFB channel with interrupt & trigger */ acifb_channels_setup(acifb, &acifb_channel_opt, AC_NB_CHANNELS); /* Disable global interrupts */ cpu_irq_disable(); /* * Initialize the interrupt vectors * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_initialize_vectors(); /* * Register the ACIFB interrupt handler * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_register_handler(&ACIFB_interrupt_handler, AVR32_ACIFB_IRQ, AC_INTERRUPT_PRIORITY); /* Enable Analog Comparator Channel interrupt */ acifb_enable_comparison_interrupt(acifb, EXAMPLE_ACIFB_CHANNEL); /* Enable global interrupts */ cpu_irq_enable(); return STATUS_OK; } /* End of ac_init() */ /** * \brief Asynchronous Timer Initialization * - Start the 32KHz Oscillator * - Initializes the AST module with periodic trigger events * * \retval STATUS_OK Configuration OK * \retval ERR_BUSY Error in configuring the AST module */ static status_code_t ast_init() { /* Initial Count value to write in AST */ unsigned long ast_counter = 0; /* Set the prescaler to set a periodic trigger from AST */ avr32_ast_pir0_t pir = { .insel = AST_TRIGGER_PRESCALER }; /* Set the OSC32 parameters */ scif_osc32_opt_t osc32_opt = { .mode = SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, .startup = OSC32_STARTUP_8192, .pinsel = BOARD_OSC32_PINSEL, .en1k = false, .en32k = true }; /* Enable the 32KHz Oscillator */ scif_start_osc32(&osc32_opt, true); /* Enable the Peripheral Event System Clock */ sysclk_enable_hsb_module(SYSCLK_EVENT); /* Enable PBA clock for AST clock to switch its source */ sysclk_enable_pba_module(SYSCLK_AST); /* Initialize the AST in counter mode */ if (!ast_init_counter(&AVR32_AST, AST_CLOCK_SOURCE, AST_PRESCALER, ast_counter)) { return ERR_BUSY; } /* Initialize the periodic value register with the prescaler */ ast_set_periodic0_value(&AVR32_AST, pir); /* Enable the AST periodic event */ ast_enable_periodic0(&AVR32_AST); /* Clear All AST Interrupt request and clear SR */ ast_clear_all_status_flags(&AVR32_AST); /* Enable the AST */ ast_enable(&AVR32_AST); /* Disable PBA clock for AST after switching its source to OSC32 */ sysclk_disable_pba_module(SYSCLK_AST); return STATUS_OK; } /* End of ast_init() */ /** * \brief Low Power Configuration * Initializes the power saving measures to reduce power consumption * - Enable pull-ups on GPIO pins * - Disable the clocks to unwanted modules * - Disable internal voltage regulator when in 1.8V supply mode */ static void power_save_measures_init() { uint8_t i; uint32_t gpio_mask[AVR32_GPIO_PORT_LENGTH] = {0}; /* * Enable internal pull-ups on all unused GPIO pins * Note: Pull-ups on Oscillator or JTAG pins can be enabled only if they * are not used as an oscillator or JTAG pin respectively. */ for (i = 0; i < (sizeof(gpio_used_pins) / sizeof(uint32_t)); i++) { gpio_mask[gpio_used_pins[i] >> 5] |= 1 << (gpio_used_pins[i] & 0x1F); } for (i = 0; i < AVR32_GPIO_PORT_LENGTH; i++) { gpio_configure_group(i, ~(gpio_mask[i]), GPIO_PULL_UP | GPIO_DIR_INPUT); } /* Disable OCD clock which is not disabled by sysclk service */ sysclk_disable_cpu_module(SYSCLK_OCD); #if POWER_SUPPLY_MODE_1_8V /* * When using 1.8V Single supply mode, the Voltage Regulator can be * shut-down using the code below, in-order to save power. * See Voltage Regulator Calibration Register in datasheet for more *info. * CAUTION: When using 3.3V Single supply mode, the Voltage Regulator * cannot be shut-down and the application will hang in this loop. */ uint32_t tmp = (AVR32_SCIF.vregcr); tmp &= (~(1 << 5 | 1 << 18)); AVR32_SCIF.unlock = 0xAA000000 | AVR32_SCIF_VREGCR; AVR32_SCIF.vregcr = tmp; /* Wait until internal voltage regulator is disabled. */ while ((AVR32_SCIF.vregcr & 0x00040020)) { } #endif } /* End of power_save_measures_init() */
/** * \brief Initializes the ADCIFB module with trigger * - Initialize the trigger mode & compare interrupts for ADCIFB * * \retval STATUS_OK Configuration OK * \retval ERR_TIMEOUT Timeout on configuring ADCIFB module * \retval ERR_BUSY ADCIFB module unable to configure the trigger */ static status_code_t adc_init() { /* GPIO pin/adc - function map. */ static const gpio_map_t ADCIFB_GPIO_MAP = { {EXAMPLE_ADCIFB_PIN, EXAMPLE_ADCIFB_FUNCTION} }; /* ADCIFB Configuration */ adcifb_opt_t adcifb_opt = { /* Resolution mode */ .resolution = AVR32_ADCIFB_ACR_RES_10BIT, /* Channels Sample & Hold Time in [0,15] */ .shtim = ADC_SAMPLE_HOLD_TIME, /* ADC Clock Prescaler */ .ratio_clkadcifb_clkadc = (sysclk_get_pba_hz()) / ADC_FREQUENCY, .startup = ADC_STARTUP_TIME, /* ADCIFB Sleep Mode enabled */ .sleep_mode_enable = true }; /* Disable pull up on ADCIFB channel input pin */ gpio_disable_pin_pull_up(EXAMPLE_ADCIFB_PIN); /* Enable the ADC pins */ gpio_enable_module(ADCIFB_GPIO_MAP, sizeof(ADCIFB_GPIO_MAP) / sizeof(ADCIFB_GPIO_MAP[0])); /* Enable ADCIFB clock */ sysclk_enable_pba_module(SYSCLK_ADCIFB); /* Configure the ADCIFB peripheral */ if (adcifb_configure(adcifb, &adcifb_opt)) { /* Error configuring the ADCIFB */ return ERR_TIMEOUT; } /* Configure the trigger for ADCIFB peripheral */ if (adcifb_configure_trigger(adcifb, AVR32_ADCIFB_TRGR_TRGMOD_EVT, 0)) { /* Error configuring the trigger for ADCIFB */ return ERR_BUSY; } /* Enable ADCIFB Channel 0 */ adcifb_channels_enable(adcifb, EXAMPLE_ADCIFB_CHANNEL); /* Disable global interrupts */ cpu_irq_disable(); /* * Initialize the interrupt vectors * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_initialize_vectors(); /* * Register the ADCIFB interrupt handler * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_register_handler(&ADCIFB_interrupt_handler, AVR32_ADCIFB_IRQ, ADC_INTERRUPT_PRIORITY); /* * Set the threshold value in CVR.LV register to generate interrupt * when the value detected is above the threshold. * 1.500 V with 10-bit resolution */ adcifb_set_high_compare_value(adcifb, ADC_COMPARE_VALUE); /* Enable the Analog Compare option in ADCIFB */ adcifb_enable_analog_compare_mode(adcifb); /* Enable the data ready interrupt for ADCIFB */ adcifb_enable_compare_gt_interrupt(adcifb); return STATUS_OK; } /* End of adc_init() */ /** * \brief Asynchronous Timer Initialization * - Start the 32KHz Oscillator * - Initializes the AST module with periodic trigger events * * \retval STATUS_OK Configuration OK * \retval ERR_TIMEOUT Error in configuring the AST module */ static status_code_t ast_init() { /* Initial Count value to write in AST */ unsigned long ast_counter = 0; /* Set the prescaler to set a periodic trigger from AST */ avr32_ast_pir0_t pir = { .insel = AST_TRIGGER_PRESCALER }; /* Set the OSC32 parameters */ scif_osc32_opt_t osc32_opt = { .mode = SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, .startup = OSC32_STARTUP_8192, .pinsel = BOARD_OSC32_PINSEL, .en1k = false, .en32k = true }; /* Enable the 32KHz Oscillator */ scif_start_osc32(&osc32_opt, true); /* Enable the Peripheral Event System Clock */ sysclk_enable_hsb_module(SYSCLK_EVENT); /* Enable PBA clock for AST clock to switch its source */ sysclk_enable_pba_module(SYSCLK_AST); /* Initialize the AST in counter mode */ if (!ast_init_counter(&AVR32_AST, AST_CLOCK_SOURCE, AST_PRESCALER, ast_counter)) { return ERR_TIMEOUT; } /* Initialize the periodic value register with the prescaler */ ast_set_periodic0_value(&AVR32_AST, pir); /* Enable the AST periodic event */ ast_enable_periodic0(&AVR32_AST); /* Clear All AST Interrupt request and clear SR */ ast_clear_all_status_flags(&AVR32_AST); /* Enable the AST */ ast_enable(&AVR32_AST); /* Disable PBA clock for AST after switching its source to OSC32 */ sysclk_disable_pba_module(SYSCLK_AST); return STATUS_OK; } /* End of ast_init() */ /** * \brief Low Power Configuration * Initializes the power saving measures to reduce power consumption * - Enable pullups on GPIO pins * - Disable the clocks to unused modules * - Disable internal voltage regulator when in 1.8V supply mode */ static void power_save_measures_init() { uint8_t i; uint32_t gpio_mask[AVR32_GPIO_PORT_LENGTH] = {0}; /* * Enable internal pull-ups on all unused GPIO pins * Note: Pull-ups on Oscillator or JTAG pins can be enabled only if they * are not used as an oscillator or JTAG pin respectively. */ for (i = 0; i < (sizeof(gpio_used_pins) / sizeof(uint32_t)); i++) { gpio_mask[gpio_used_pins[i] >> 5] |= 1 << (gpio_used_pins[i] & 0x1F); } for (i = 0; i < AVR32_GPIO_PORT_LENGTH; i++) { gpio_configure_group(i, ~(gpio_mask[i]), GPIO_PULL_UP | GPIO_DIR_INPUT); } /* Disable OCD clock which is not disabled by sysclk service */ sysclk_disable_cpu_module(SYSCLK_OCD); #if POWER_SUPPLY_MODE_1_8V /* * When using 1.8V Single supply mode, the Voltage Regulator can be * shut-down using the code below, in-order to save power. * See Voltage Regulator Calibration Register in datasheet for more *info. * CAUTION: When using 3.3V Single supply mode, the Voltage Regulator * cannot be shut-down and the application will hang in this loop. */ uint32_t tmp = (AVR32_SCIF.vregcr); tmp &= (~(1 << 5 | 1 << 18)); AVR32_SCIF.unlock = 0xAA000000 | AVR32_SCIF_VREGCR; AVR32_SCIF.vregcr = tmp; /* Wait until internal voltage regulator is disabled. */ while ((AVR32_SCIF.vregcr & 0x00040020)) { } #endif } /* End of power_save_measures_init() */
static status_code_t ast_init() { /* Initial Count value to write in AST */ unsigned long ast_counter = 0; /* Set the prescaler to set a periodic trigger from AST */ avr32_ast_pir0_t pir = { .insel = AST_TRIGGER_PRESCALER }; /* Set the OSC32 parameters */ scif_osc32_opt_t osc32_opt = { #if BOARD_OSC32_IS_XTAL .mode = SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, #else .mode = SCIF_OSC_MODE_EXT_CLK, #endif .startup = OSC32_STARTUP_8192, .pinsel = BOARD_OSC32_PINSEL, .en1k = false, .en32k = true }; /* Enable the 32KHz Oscillator */ scif_start_osc32(&osc32_opt, true); /* Enable the Peripheral Event System Clock */ sysclk_enable_hsb_module(SYSCLK_EVENT); /* Enable PBA clock for AST clock to switch its source */ sysclk_enable_pba_module(SYSCLK_AST); /* Initialize the AST in counter mode */ if (!ast_init_counter(&AVR32_AST, AST_CLOCK_SOURCE, AST_PRESCALER, ast_counter)) { return ERR_BUSY; /* Check AST timer */ } /* Initialize the periodic value register with the prescaler */ ast_set_periodic0_value(&AVR32_AST, pir); /* Enable the AST periodic event */ ast_enable_periodic0(&AVR32_AST); /* Clear All AST Interrupt request and clear SR */ ast_clear_all_status_flags(&AVR32_AST); /* Enable the AST */ ast_enable(&AVR32_AST); /* Disable PBA clock for AST after switching its source to OSC32 */ sysclk_disable_pba_module(SYSCLK_AST); return STATUS_OK; } /* End of ast_init() */ #endif /** * \brief Low Power Configuration * Initializes the power saving measures to reduce power consumption * - Enable pull ups on GPIO pins * - Disable the clocks to unwanted modules * - Disable internal voltage regulator when in 1.8V supply mode */ void power_save_measures_init() { uint8_t i; uint32_t gpio_mask[AVR32_GPIO_PORT_LENGTH] = {0}; /* * Enable internal pull-ups on all unused GPIO pins * Note: Pull-ups on Oscillator or JTAG pins can be enabled only if they * are not used as an oscillator or JTAG pin respectively. */ for (i = 0; i < (sizeof(gpio_used_pins) / sizeof(uint32_t)); i++) { gpio_mask[gpio_used_pins[i] >> 5] |= 1 << (gpio_used_pins[i] & 0x1F); } for (i = 0; i < AVR32_GPIO_PORT_LENGTH; i++) { gpio_configure_group(i, gpio_mask[i], GPIO_PULL_UP | GPIO_DIR_INPUT); } /* Disable OCD clock which is not disabled by sysclk service */ sysclk_disable_cpu_module(SYSCLK_OCD); #if POWER_SUPPLY_MODE_1_8V /* * When using 1.8V Single supply mode, the Voltage Regulator can be * shut-down using the code below, in-order to save power. * See Voltage Regulator Calibration Register in datasheet for more *info. * CAUTION: When using 3.3V Single supply mode, the Voltage Regulator * cannot be shut-down and the application will hang in this loop. */ uint32_t tmp = (AVR32_SCIF.vregcr); tmp &= (~(1 << 5)); AVR32_SCIF.unlock = 0xAA000000 | AVR32_SCIF_VREGCR; AVR32_SCIF.vregcr = tmp; /* Wait until internal voltage regulator is disabled. */ while ((AVR32_SCIF.vregcr & 0x20)) { } #endif } /* End of power_save_measures_init() */
/** * \brief main function */ int main(void) { static const gpio_map_t USART_GPIO_MAP = { {EXAMPLE_USART_RX_PIN, EXAMPLE_USART_RX_FUNCTION}, {EXAMPLE_USART_TX_PIN, EXAMPLE_USART_TX_FUNCTION} }; // USART options static const usart_options_t USART_OPTIONS = { .baudrate = 57600, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = 0 }; #if BOARD == UC3L_EK scif_osc32_opt_t opt_osc32 = { // 2-pin Crystal and high current mode SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, // oscillator startup time AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC, /* * select the alternate xin32_2 and xout32_2 for the * 32kHz crystal oscillator */ true, // disable the 1kHz output false, // enable the 32kHz output true }; #else scif_osc32_opt_t opt_osc32 = { // 2-pin crystal mode .mode = SCIF_OSC_MODE_2PIN_CRYSTAL, // startup time .startup = AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC }; #endif // Set system clock sysclk_init(); // Start OSC_32KHZ scif_start_osc32(&opt_osc32,true); // Assign GPIO pins to USART0. gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0])); // Initialize USART in RS232 mode usart_init_rs232(EXAMPLE_USART, &USART_OPTIONS, FPBA); // Welcome message usart_write_line(EXAMPLE_USART, "\x1B[2J\x1B[H\r\nATMEL\r\n"); usart_write_line(EXAMPLE_USART, "AVR UC3 - FREQM example\r\n"); #ifndef INTERRUPT_MODE_SUPPORT uint32_t result; status_code_t status; uint32_t duration = 128; usart_write_line(EXAMPLE_USART, "/*** Normal Mode ***/\r\n"); freqm_enable(); status = freqm_write_config(AVR32_FREQM_REF_OSC32, AVR32_FREQM_CPU, duration); if (status == ERR_TIMEOUT) { usart_write_line(EXAMPLE_USART, "FREQM Module Config Fail!"); while(true); } result = clock_measure(); usart_write_line(EXAMPLE_USART, "CPU Clock:\r\n"); display_result(OSC32K_FREQ_HZ, duration, result); usart_write_line(EXAMPLE_USART, "HSB Clock:\r\n"); freqm_set_clock_source(AVR32_FREQM_HSB); result = clock_measure(); display_result(OSC32K_FREQ_HZ, duration, result); usart_write_line(EXAMPLE_USART, "PBA Clock:\r\n"); freqm_set_clock_source(AVR32_FREQM_PBA); result = clock_measure(); display_result(OSC32K_FREQ_HZ, duration, result); usart_write_line(EXAMPLE_USART, "PBB Clock:\r\n"); freqm_set_clock_source(AVR32_FREQM_PBB); result = clock_measure(); display_result(OSC32K_FREQ_HZ, duration, result); pm_set_clk_domain_div(PM_CLK_DOMAIN_3,PM_CKSEL_DIVRATIO_16); usart_write_line(EXAMPLE_USART, "PBB Clock(Main clock/16):\r\n"); freqm_set_clock_source(AVR32_FREQM_PBB); result = clock_measure(); display_result(OSC32K_FREQ_HZ, duration, result); usart_write_line(EXAMPLE_USART, "Test Complete!\r\n"); while (true) { /* * Force a NOP instruction for an eventual placement of a debug * session breakpoint. */ asm("nop\n"); } #else INTC_init_interrupts(); INTC_register_interrupt(&freqm_int_handler, AVR32_FREQM_IRQ, AVR32_INTC_INT0); freqm_enable_measurement_done_int(); cpu_irq_enable(); usart_write_line(EXAMPLE_USART, "/*** Interrupt Mode ***/\r\n"); uint32_t duration = 128; uint32_t result; status_code_t status; freqm_enable(); status = freqm_write_config(AVR32_FREQM_REF_OSC32, AVR32_FREQM_CPU, duration); if (status == ERR_TIMEOUT) { usart_write_line(EXAMPLE_USART, "FREQM Module Config Fail!"); while(true); } freqm_start(); while(true) { if(flag == 0) { result =(uint32_t)(((F32)value / duration) * OSC32K_FREQ_HZ); usart_write_line(EXAMPLE_USART, "CPU Clock:\r\n"); display_result(OSC32K_FREQ_HZ, duration, result); usart_write_line(EXAMPLE_USART, "Test Complete!\r\n"); flag = 1; } /* * Force a NOP instruction for an eventual placement of a debug * session breakpoint. */ asm("nop\n"); }; #endif return 0; }