/** * \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() */
/** * \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() */
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() */