/** * \brief Event Button Init. */ void event_button_init(void) { // Structure holding the configuration parameters // of the EIC module. struct eic_line_config eic_line_conf; // Initialize EIC Controller sysclk_enable_peripheral_clock(EIC); // Enable level-triggered interrupt. eic_line_conf.eic_mode = EIC_MODE_EDGE_TRIGGERED; // Interrupt will trigger on low-level. eic_line_conf.eic_level = EIC_LEVEL_LOW_LEVEL; // Edge on falling edge eic_line_conf.eic_edge = EIC_EDGE_FALLING_EDGE; // Enable filter. eic_line_conf.eic_filter = EIC_FILTER_DISABLED; // For Wake Up mode, initialize in asynchronous mode eic_line_conf.eic_async = EIC_ASYNCH_MODE; // Enable clock for EIC controller eic_enable(EIC); // Init the EIC controller with the options eic_line_set_config(EIC, GPIO_PUSH_BUTTON_EIC_LINE, &eic_line_conf); // Init the callback eic_line_set_callback(EIC, GPIO_PUSH_BUTTON_EIC_LINE, eic5_callback, EIC_5_IRQn, 1); // Enable the EIC line eic_line_enable(EIC, GPIO_PUSH_BUTTON_EIC_LINE); // EIC can wake the device from backup mode bpm_enable_wakeup_source(BPM, BPM_BKUP_WAKEUP_SRC_EIC | BPM_BKUP_WAKEUP_SRC_AST); // EIC can wake the device from backup mode bpm_enable_backup_pin(BPM, 1 << GPIO_PUSH_BUTTON_EIC_LINE); // Retain I/O lines after wakeup from backup bpm_disable_io_retention(BPM); bpm_enable_io_retention(BPM); bpm_enable_fast_wakeup(BPM); sysclk_disable_peripheral_clock(EIC); event_pbEvent = false; // Initialize WDT Controller sysclk_enable_peripheral_clock(WDT); enable_wdt(); }
/** * \brief Run BPM driver unit tests. */ int main(void) { struct ast_config ast_conf; const usart_serial_options_t usart_serial_options = { .baudrate = CONF_TEST_BAUDRATE, .charlength = CONF_TEST_CHARLENGTH, .paritytype = CONF_TEST_PARITY, .stopbits = CONF_TEST_STOPBITS }; sysclk_init(); board_init(); stdio_serial_init(CONF_TEST_USART, &usart_serial_options); /* Initialize AST for all tests */ /* Enable osc32 oscillator*/ if (!osc_is_ready(OSC_ID_OSC32)) { osc_enable(OSC_ID_OSC32); osc_wait_ready(OSC_ID_OSC32); } /* Enable the AST. */ ast_enable(AST); ast_conf.mode = AST_COUNTER_MODE; ast_conf.osc_type = AST_OSC_32KHZ; ast_conf.psel = AST_PSEL_32KHZ_1HZ; ast_conf.counter = 0; ast_set_config(AST, &ast_conf); /* Set periodic 0 to interrupt after 1/16 second in counter mode. */ ast_clear_interrupt_flag(AST, AST_INTERRUPT_PER); ast_write_periodic0_value(AST, AST_PSEL_32KHZ_1HZ - 2); ast_set_callback(AST, AST_INTERRUPT_PER, ast_per_callback, AST_PER_IRQn, 1); ast_enable_wakeup(AST, AST_WAKEUP_PER); /* AST can wakeup the device */ bpm_enable_wakeup_source(BPM, (1 << BPM_BKUPWEN_AST)); /** * Retain I/O lines after wakeup from backup. * Disable to undo the previous retention state then enable. */ bpm_disable_io_retention(BPM); bpm_enable_io_retention(BPM); /* Enable fast wakeup */ bpm_enable_fast_wakeup(BPM); /* Define all the test cases. */ DEFINE_TEST_CASE(backup_test, NULL, run_backup_test, NULL, "Backup Power Manager, Backup mode & wakeup."); DEFINE_TEST_CASE(ps_test, NULL, run_ps_test, NULL, "Backup Power Manager, Power Scaling."); DEFINE_TEST_CASE(ret_test, NULL, run_ret_test, NULL, "Backup Power Manager, Retention mode & wakeup."); DEFINE_TEST_CASE(wait_test, NULL, run_wait_test, NULL, "Backup Power Manager, Wait mode & wakeup."); DEFINE_TEST_CASE(sleep_3_test, NULL, run_sleep_3_test, NULL, "Backup Power Manager, Sleep mode 3 & wakeup."); DEFINE_TEST_CASE(sleep_2_test, NULL, run_sleep_2_test, NULL, "Backup Power Manager, Sleep mode 2 & wakeup."); DEFINE_TEST_CASE(sleep_1_test, NULL, run_sleep_1_test, NULL, "Backup Power Manager, Sleep mode 1 & wakeup."); DEFINE_TEST_CASE(sleep_0_test, NULL, run_sleep_0_test, NULL, "Backup Power Manager, Sleep mode 0 & wakeup."); /* Put test case addresses in an array. */ DEFINE_TEST_ARRAY(bpm_tests) = { &backup_test, &ps_test, &ret_test, &wait_test, &sleep_3_test, &sleep_2_test, &sleep_1_test, &sleep_0_test, }; /* Define the test suite. */ DEFINE_TEST_SUITE(bpm_suite, bpm_tests, "SAM BPM driver test suite"); /* Run all tests in the test suite. */ test_suite_run(&bpm_suite); /* Disable the AST */ ast_disable(AST); while (1) { /* Busy-wait forever. */ } }
void sysclk_init(void) { uint32_t ps_value = 0; bool is_fwu_enabled = false; #if CONFIG_HCACHE_ENABLE == 1 /* Enable HCACHE */ sysclk_enable_peripheral_clock(HCACHE); HCACHE->HCACHE_CTRL = HCACHE_CTRL_CEN_YES; while (!(HCACHE->HCACHE_SR & HCACHE_SR_CSTS_EN)); #endif /* Set up system clock dividers if different from defaults */ if ((CONFIG_SYSCLK_CPU_DIV > 0) || (CONFIG_SYSCLK_PBA_DIV > 0) || (CONFIG_SYSCLK_PBB_DIV > 0) || (CONFIG_SYSCLK_PBC_DIV > 0) || (CONFIG_SYSCLK_PBD_DIV > 0)) { sysclk_set_prescalers(CONFIG_SYSCLK_CPU_DIV, CONFIG_SYSCLK_PBA_DIV, CONFIG_SYSCLK_PBB_DIV, CONFIG_SYSCLK_PBC_DIV, CONFIG_SYSCLK_PBD_DIV ); } /* Automatically select best power scaling mode */ #ifdef CONFIG_FLASH_READ_MODE_HIGH_SPEED_ENABLE ps_value = BPM_PS_2; is_fwu_enabled = false; #elif (defined(CONFIG_PLL0_MUL) || defined(CONFIG_DFLL0_MUL) || defined(CONFIG_USBCLK_DIV)) /* USB/DFLL/PLL are not available in PS1 (BPM.PMCON.PS=1) mode */ ps_value = BPM_PS_0; is_fwu_enabled = false; #else if (sysclk_get_cpu_hz() <= FLASH_FREQ_PS1_FWS_1_MAX_FREQ) { ps_value = BPM_PS_1; if (sysclk_get_cpu_hz() > FLASH_FREQ_PS1_FWS_0_MAX_FREQ) { bpm_enable_fast_wakeup(BPM); is_fwu_enabled = true; } } else { ps_value = BPM_PS_0; } #endif /* Switch to system clock selected by user */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RCSYS) { /* Already running from RCSYS */ } #ifdef BOARD_OSC0_HZ else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_OSC0) { osc_enable(OSC_ID_OSC0); osc_wait_ready(OSC_ID_OSC0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_OSC0); } #endif #ifdef CONFIG_DFLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_DFLL) { dfll_enable_config_defaults(0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_DFLL); } #endif #ifdef CONFIG_PLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLL0) { pll_enable_config_defaults(0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_PLL0); } #endif else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC80M) { osc_enable(OSC_ID_RC80M); osc_wait_ready(OSC_ID_RC80M); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RC80M); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RCFAST) { osc_enable(OSC_ID_RCFAST); osc_wait_ready(OSC_ID_RCFAST); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RCFAST); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC1M) { osc_enable(OSC_ID_RC1M); osc_wait_ready(OSC_ID_RC1M); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RC1M); } else { Assert(false); } /* Automatically switch to low power mode */ bpm_configure_power_scaling(BPM, ps_value, BPM_PSCM_CPU_NOT_HALT); while ((bpm_get_status(BPM) & BPM_SR_PSOK) == 0); /* If the user has specified clock masks, enable only requested clocks */ irqflags_t const flags = cpu_irq_save(); #if defined(CONFIG_SYSCLK_INIT_CPUMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_CPUMASK - (uint32_t)PM); PM->PM_CPUMASK = SYSCLK_INIT_MINIMAL_CPUMASK | CONFIG_SYSCLK_INIT_CPUMASK; #endif #if defined(CONFIG_SYSCLK_INIT_HSBMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_HSBMASK - (uint32_t)PM); PM->PM_HSBMASK = SYSCLK_INIT_MINIMAL_HSBMASK | CONFIG_SYSCLK_INIT_HSBMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBAMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBAMASK - (uint32_t)PM); PM->PM_PBAMASK = SYSCLK_INIT_MINIMAL_PBAMASK | CONFIG_SYSCLK_INIT_PBAMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBBMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBBMASK - (uint32_t)PM); PM->PM_PBBMASK = SYSCLK_INIT_MINIMAL_PBBMASK | CONFIG_SYSCLK_INIT_PBBMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBCMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBCMASK - (uint32_t)PM); PM->PM_PBCMASK = SYSCLK_INIT_MINIMAL_PBCMASK | CONFIG_SYSCLK_INIT_PBCMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBDMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBDMASK - (uint32_t)PM); PM->PM_PBDMASK = SYSCLK_INIT_MINIMAL_PBDMASK | CONFIG_SYSCLK_INIT_PBDMASK; #endif cpu_irq_restore(flags); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = true; #endif }