static void sysclk_init_pll(void) { struct pll_config pllcfg; switch (CONFIG_PLL0_SOURCE) { case PLL_SRC_RC2MHZ: break; case PLL_SRC_RC32MHZ: osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); break; case PLL_SRC_XOSC: osc_enable(OSC_ID_XOSC); osc_wait_ready(OSC_ID_XOSC); break; default: //unhandled_case(CONFIG_PLL0_SOURCE); break; } pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); }
/** * \brief Enable clock for the USB module * * \pre CONFIG_USBCLK_SOURCE must be defined. * * \param frequency The required USB clock frequency in MHz: * \arg \c 6 for 6 MHz * \arg \c 48 for 48 MHz */ void sysclk_enable_usb(uint8_t frequency) { uint8_t prescaler; Assert((frequency == 6) || (frequency == 48)); /* * Enable or disable prescaler depending on if the USB frequency is 6 * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. */ if (frequency == 6) { prescaler = CLK_USBPSDIV_8_gc; } else { prescaler = 0; } /* * Switch to the system clock selected by the user. */ switch (CONFIG_USBCLK_SOURCE) { case USBCLK_SRC_RCOSC: if (!osc_is_ready(OSC_ID_RC32MHZ)) { osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); #ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF) { osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); } osc_enable_autocalibration(OSC_ID_RC32MHZ, CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); #endif } ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) | CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm); break; #ifdef CONFIG_PLL0_SOURCE case USBCLK_SRC_PLL: pll_enable_config_defaults(0); ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); break; #endif default: Assert(false); break; } sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); }
/** * \brief Run PICOUART 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); /* Enable osc32 oscillator*/ if (!osc_is_ready(OSC_ID_OSC32)) { osc_enable(OSC_ID_OSC32); osc_wait_ready(OSC_ID_OSC32); } /* Disable all AST wake enable bits for safety since the AST is reset only by a POR. */ 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); ast_disable_wakeup(AST, AST_WAKEUP_ALARM); ast_disable_wakeup(AST, AST_WAKEUP_PER); ast_disable_wakeup(AST, AST_WAKEUP_OVF); ast_disable(AST); /* Configurate the USART to board monitor */ bm_init(); /* Define all the test cases. */ DEFINE_TEST_CASE(picouart_test, NULL, run_picouart_test, NULL, "SAM PICOUART wakeup test."); DEFINE_TEST_CASE(getversion_test, NULL, run_getversion_test, NULL, "SAM get version test."); /* Put test case addresses in an array. */ DEFINE_TEST_ARRAY(picouart_tests) = { &getversion_test, &picouart_test, }; /* Define the test suite. */ DEFINE_TEST_SUITE(picouart_suite, picouart_tests, "SAM PICOUART driver test suite"); /* Run all tests in the test suite. */ test_suite_run(&picouart_suite); while (1) { /* Busy-wait forever. */ } }
void sysclk_init(void) { /* 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)) { sysclk_set_prescalers(CONFIG_SYSCLK_CPU_DIV, CONFIG_SYSCLK_PBA_DIV, CONFIG_SYSCLK_PBB_DIV); } /* Switch to system clock selected by user */ switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_RCSYS: /* Already running from RCOSC */ break; #ifdef BOARD_OSC0_HZ case 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(BOARD_OSC0_HZ); sysclk_set_source(SYSCLK_SRC_OSC0); break; #endif #ifdef CONFIG_PLL0_SOURCE case 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()); sysclk_set_source(SYSCLK_SRC_PLL0); break; } #endif default: Assert(false); break; } /* If the user has specified clock masks, enable only requested clocks */ #if defined(CONFIG_SYSCLK_INIT_CPUMASK) AVR32_PM.cpumask = SYSCLK_INIT_MINIMAL_CPUMASK | CONFIG_SYSCLK_INIT_CPUMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBAMASK) AVR32_PM.pbamask = SYSCLK_INIT_MINIMAL_PBAMASK | CONFIG_SYSCLK_INIT_PBAMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBBMASK) AVR32_PM.pbbmask = SYSCLK_INIT_MINIMAL_PBBMASK | CONFIG_SYSCLK_INIT_PBBMASK; #endif #if defined(CONFIG_SYSCLK_INIT_HSBMASK) AVR32_PM.hsbmask = SYSCLK_INIT_MINIMAL_HSBMASK | CONFIG_SYSCLK_INIT_HSBMASK; #endif #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = true; #endif }
/** * Initialize the AST as event generator. */ static void init_ast(void) { struct ast_config ast_conf; /* 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); /* Configure the AST with counter mode and set counter to 0 */ 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); /* Enable period enent of AST */ ast_write_periodic0_value(AST, AST_PSEL_32KHZ_1HZ); ast_enable_event(AST, AST_EVENT_PER); }
/** * Execute the application binary * * \param addr Application start address. * \return If success, no return; * 1 - address alignment error; * 2 - address not executable. */ static uint8_t _app_exec(void *addr) { uint32_t i; /* Check parameters */ if ((uint32_t)addr & 0x7F) { return 1; } if ((uint32_t)addr > CM_SRAM_END) { return 2; } __disable_irq(); /* Disable SysTick */ SysTick->CTRL = 0; /* Disable IRQs & clear pending IRQs */ for (i = 0; i < 8; i++) { NVIC->ICER[i] = 0xFFFFFFFF; NVIC->ICPR[i] = 0xFFFFFFFF; } /* Switch clock to slow RC */ osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(SYSCLK_PRES_1); /* Switch clock to fast RC */ osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(SYSCLK_PRES_1); /* Modify vector table location */ __DSB(); __ISB(); SCB->VTOR = ((uint32_t)addr & SCB_VTOR_TBLOFF_Msk); __DSB(); __ISB(); __enable_irq(); /* Jump to application */ jump_to_app(addr); /* Never be here */ return 0; }
/** * \brief Test Pll and DFLL (if have) * * This test enables pll/dfll source clock, sets its mul and div * factor, and then enables it. Check if it's locked after max * startup time. * * \param test Current test case. */ static void run_pll_dfll_test(const struct test_case *test) { uint32_t wait; bool status; /* avoid Cppcheck Warning */ UNUSED(wait); UNUSED(status); #if (defined CONFIG_PLL0_SOURCE) || (defined CONFIG_PLL1_SOURCE) struct pll_config pllcfg; #endif #ifdef CONFIG_PLL0_SOURCE pll_enable_source(CONFIG_PLL0_SOURCE); pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, PLL0); for (wait = 0; wait < PLL_MAX_STARTUP_CYCLES; wait++) { //waiting PLL0 lock __asm__("nop"); }; status = pll_is_locked(PLL0); test_assert_true(test, status, "PLL0 can't be locked"); #endif #ifdef CONFIG_PLL1_SOURCE pll_enable_source(CONFIG_PLL1_SOURCE); pll_config_defaults(&pllcfg, 1); pll_enable(&pllcfg, PLL1); for (wait = 0; wait < PLL_MAX_STARTUP_CYCLES; wait++) { //waiting PLL1 lock __asm__("nop"); }; status = pll_is_locked(PLL1); test_assert_true(test, status, "PLL1 can't be locked"); #endif #ifdef CONFIG_DFLL0_SOURCE struct dfll_config dfllcfg; osc_enable(OSC_ID_RCSYS); osc_wait_ready(OSC_ID_RCSYS); dfll_config_defaults(&dfllcfg, 0); dfll_enable_closed_loop(&dfllcfg, 0); for (wait = 0; wait < DFLL_MAX_LOCK_CYCLES; wait++) { //waiting DFLL lock __asm__("nop"); }; status = dfll_is_fine_locked(0); test_assert_true(test, status, "DFLL can't be locked"); #endif }
/* Override the default definition of vPortSetupTimerInterrupt() that is weakly defined in the FreeRTOS Cortex-M3 port layer with a version that configures the asynchronous timer (AST) to generate the tick interrupt. */ void vPortSetupTimerInterrupt( void ) { struct ast_config ast_conf; /* Ensure the AST can bring the CPU out of sleep mode. */ sleepmgr_lock_mode( SLEEPMGR_RET ); /* Ensure the 32KHz oscillator is enabled. */ if( osc_is_ready( OSC_ID_OSC32 ) == pdFALSE ) { osc_enable( OSC_ID_OSC32 ); osc_wait_ready( OSC_ID_OSC32 ); } /* Enable the AST itself. */ ast_enable( AST ); ast_conf.mode = AST_COUNTER_MODE; /* Simple up counter. */ ast_conf.osc_type = AST_OSC_32KHZ; ast_conf.psel = 0; /* No prescale so the actual frequency is 32KHz/2. */ ast_conf.counter = 0; ast_set_config( AST, &ast_conf ); /* The AST alarm interrupt is used as the tick interrupt. Ensure the alarm status starts clear. */ ast_clear_interrupt_flag( AST, AST_INTERRUPT_ALARM ); /* Enable wakeup from alarm 0 in the AST and power manager. */ ast_enable_wakeup( AST, AST_WAKEUP_ALARM ); bpm_enable_wakeup_source( BPM, ( 1 << BPM_BKUPWEN_AST ) ); /* Tick interrupt MUST execute at the lowest interrupt priority. */ NVIC_SetPriority( AST_ALARM_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY); ast_enable_interrupt( AST, AST_INTERRUPT_ALARM ); NVIC_ClearPendingIRQ( AST_ALARM_IRQn ); NVIC_EnableIRQ( AST_ALARM_IRQn ); /* Automatically clear the counter on interrupt. */ ast_enable_counter_clear_on_alarm( AST, portAST_ALARM_CHANNEL ); /* Start with the tick active and generating a tick with regular period. */ ast_write_alarm0_value( AST, ulAlarmValueForOneTick ); ast_write_counter_value( AST, 0 ); /* See the comments where xMaximumPossibleSuppressedTicks is declared. */ xMaximumPossibleSuppressedTicks = ULONG_MAX / ulAlarmValueForOneTick; }
static void ctrl_sam3ucfg_cb(void) { switch(udd_g_ctrlreq.req.wValue & 0xFF) { /* Turn on slow clock */ case 0x01: osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; /* Turn off slow clock */ case 0x02: pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); break; /* Jump to ROM-resident bootloader */ case 0x03: /* Turn off connected stuff */ board_power(0); /* Clear ROM-mapping bit. */ efc_perform_command(EFC0, EFC_FCMD_CGPB, 1); /* Disconnect USB (will kill connection) */ udc_detach(); /* With knowledge that I will rise again, I lay down my life. */ while (RSTC->RSTC_SR & RSTC_SR_SRCMP); RSTC->RSTC_CR |= RSTC_CR_KEY(0xA5) | RSTC_CR_PERRST | RSTC_CR_PROCRST; while(1); break; #ifdef PLATFORMCW1180 /* 0xA0 starts CW1180 Specific Commands */ case 0xA0: enable_lcd(); redraw_background(); break; #endif /* Oh well, sucks to be you */ default: break; } }
void sysclk_init(void) { sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV,CONFIG_SYSCLK_PSBCDIV); //* Replace osc_user_calibration(OSC_ID_RC32MHZ,cal); DFLLRC32M.CALA=0x40; DFLLRC32M.CALB=0x23; osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); //* Replace osc_enable_autocalibration(CONFIG_OSC_AUTOCAL,CONFIG_OSC_AUTOCAL_REF_OSC); OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); // Calibrate 32MRC at 48MHz using USB SOF // 48MHz/1kHz=0xBB80 DFLLRC32M.COMP1=0x80; DFLLRC32M.COMP2=0xBB; OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; DFLLRC32M.CTRL |= DFLL_ENABLE_bm; }
void sysclk_init_opt(void) { sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV,CONFIG_SYSCLK_PSBCDIV); /* Loads 48MHz internal RC calibration value */ DFLLRC32M.CALA=nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSCA)); DFLLRC32M.CALB=nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSC)); osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); // Calibrate 32MRC at 48MHz using USB SOF // 48MHz/1kHz=0xBB80 DFLLRC32M.COMP1=0x80; DFLLRC32M.COMP2=0xBB; OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; DFLLRC32M.CTRL |= DFLL_ENABLE_bm; }
static void config_ast(void) { struct ast_config ast_conf; /* 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; /* * Using counter mode and set it to 0. * Initialize the AST. */ if (!ast_set_config(AST, &ast_conf)) { printf("Error initializing the AST\r\n"); while (1) { } } /* First clear alarm status. */ ast_clear_interrupt_flag(AST, AST_INTERRUPT_ALARM); /* Enable wakeup from alarm0. */ ast_enable_wakeup(AST, AST_WAKEUP_ALARM); /* Set callback for alarm0. */ ast_set_callback(AST, AST_INTERRUPT_ALARM, ast_alarm_callback, AST_ALARM_IRQn, 1); /* Disable first interrupt for alarm0. */ ast_disable_interrupt(AST, AST_INTERRUPT_ALARM); }
/** * \brief Run AST driver unit tests. */ 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 }; sysclk_init(); board_init(); stdio_serial_init(CONF_TEST_USART, &usart_serial_options); /* Enable osc32 oscillator*/ if (!osc_is_ready(OSC_ID_OSC32)) { osc_enable(OSC_ID_OSC32); osc_wait_ready(OSC_ID_OSC32); } /* Define all the test cases. */ DEFINE_TEST_CASE(alarm_test, NULL, run_alarm_test, NULL, "SAM AST alarm interrupt and wakeup test."); DEFINE_TEST_CASE(periodic_test, NULL, run_periodic_test, NULL, "SAM AST periodic interrupt and wakeup test."); /* Put test case addresses in an array. */ DEFINE_TEST_ARRAY(ast_tests) = { &alarm_test, &periodic_test, }; /* Define the test suite. */ DEFINE_TEST_SUITE(ast_suite, ast_tests, "SAM AST driver test suite"); /* Run all tests in the test suite. */ test_suite_run(&ast_suite); while (1) { /* Busy-wait forever. */ } }
/** * \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 }
void sysclk_init(void) { struct pll_config pllcfg; /* Set a flash wait state depending on the new cpu frequency */ system_init_flash(sysclk_get_cpu_hz()); /* Config system clock setting */ switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_SLCK_RC: osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_SLCK_XTAL: osc_enable(OSC_SLCK_32K_XTAL); osc_wait_ready(OSC_SLCK_32K_XTAL); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_SLCK_BYPASS: osc_enable(OSC_SLCK_32K_BYPASS); osc_wait_ready(OSC_SLCK_32K_BYPASS); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_MAINCK_4M_RC: /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ break; case SYSCLK_SRC_MAINCK_8M_RC: osc_enable(OSC_MAINCK_8M_RC); osc_wait_ready(OSC_MAINCK_8M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_MAINCK_12M_RC: osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_MAINCK_XTAL: osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_MAINCK_BYPASS: osc_enable(OSC_MAINCK_BYPASS); osc_wait_ready(OSC_MAINCK_BYPASS); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; #ifdef CONFIG_PLL0_SOURCE case SYSCLK_SRC_PLLACK: pll_enable_source(CONFIG_PLL0_SOURCE); pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); break; #endif case SYSCLK_SRC_UPLLCK: pll_enable_source(CONFIG_PLL1_SOURCE); pll_config_defaults(&pllcfg, 1); pll_enable(&pllcfg, 1); pll_wait_for_lock(1); pmc_switch_mck_to_upllck(CONFIG_SYSCLK_PRES); break; } /* Update the SystemFrequency variable */ SystemCoreClockUpdate(); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = 1; #endif }
/** * \brief Switch between various system clock sources and prescalers at * run time. * * \return Unused (ANSI-C compatibility). */ int main(void) { struct genclk_config gcfg; sysclk_init(); board_init(); /* Setup SysTick Timer for 1 msec interrupts */ if (SysTick_Config(SystemCoreClock / 1000)) { while (1); // Capture error } /* Enable PIO module related clock */ sysclk_enable_peripheral_clock(PIN_PUSHBUTTON_1_ID); /* Configure specific CLKOUT pin */ ioport_set_pin_mode(GCLK_PIN, GCLK_PIN_MUX); ioport_disable_pin(GCLK_PIN); /* Configure the output clock source and frequency */ genclk_config_defaults(&gcfg, GCLK_ID); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_PLLACK); genclk_config_set_divider(&gcfg, GENCLK_PCK_PRES_1); genclk_enable(&gcfg, GCLK_ID); while (1) { /* * Initial state. */ wait_for_switches(); /* * Divide MCK frequency by 2. */ sysclk_set_prescalers(SYSCLK_PRES_2); genclk_config_set_divider(&gcfg, GENCLK_PCK_PRES_2); genclk_enable(&gcfg, GCLK_ID); wait_for_switches(); #ifdef BOARD_NO_32K_XTAL /* * Switch to the slow clock with all prescalers disabled. */ sysclk_set_source(SYSCLK_SRC_SLCK_RC); sysclk_set_prescalers(SYSCLK_PRES_1); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_SLCK_RC); genclk_config_set_divider(&gcfg, GENCLK_PCK_PRES_1); genclk_enable(&gcfg, GCLK_ID); osc_disable(OSC_MAINCK_XTAL); wait_for_switches(); #endif /* * Switch to internal 8 MHz RC. */ /* Switch to slow clock before switch main clock */ sysclk_set_source(SYSCLK_SRC_SLCK_RC); osc_enable(OSC_MAINCK_8M_RC); osc_wait_ready(OSC_MAINCK_8M_RC); sysclk_set_source(SYSCLK_SRC_MAINCK_8M_RC); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_MAINCK_8M_RC); genclk_enable(&gcfg, GCLK_ID); wait_for_switches(); #if BOARD_FREQ_MAINCK_XTAL /* * Switch to external crystal (8MHz or 12MHz, depend on the board). */ osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); sysclk_set_source(SYSCLK_SRC_MAINCK_XTAL); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_MAINCK_XTAL); genclk_enable(&gcfg, GCLK_ID); osc_disable(OSC_MAINCK_8M_RC); wait_for_switches(); #endif /* * Go back to the initial state and start over. */ sysclk_init(); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_PLLACK); genclk_config_set_divider(&gcfg, GENCLK_PCK_PRES_1); genclk_enable(&gcfg, GCLK_ID); } }
void sysclk_init(void) { /* Set flash wait state to max in case the below clock switching. */ system_init_flash(CHIP_FREQ_CPU_MAX); /* Config system clock setting */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) { osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) { osc_enable(OSC_SLCK_32K_XTAL); osc_wait_ready(OSC_SLCK_32K_XTAL); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) { osc_enable(OSC_SLCK_32K_BYPASS); osc_wait_ready(OSC_SLCK_32K_BYPASS); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) { /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) { osc_enable(OSC_MAINCK_8M_RC); osc_wait_ready(OSC_MAINCK_8M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) { osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) { osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) { osc_enable(OSC_MAINCK_BYPASS); osc_wait_ready(OSC_MAINCK_BYPASS); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } #ifdef CONFIG_PLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) { struct pll_config pllcfg; pll_enable_source(CONFIG_PLL0_SOURCE); pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); } #endif /* Update the SystemFrequency variable */ SystemCoreClockUpdate(); /* Set a flash wait state depending on the new cpu frequency */ system_init_flash(sysclk_get_cpu_hz()); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = 1; #endif }
/*! * \brief main function : do init and loop (poll if configured so) */ int main(void) { uint8_t key; struct picouart_dev_inst dev_inst; struct picouart_config config; struct ast_config ast_conf; /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ printf("\r\n"); printf("-- PICOUART Example 1 --\r\n"); printf("-- %s\r\n", BOARD_NAME); printf("-- Compiled: %s %s --\r\n", __DATE__, __TIME__); printf("-- IMPORTANT: This example requires a board " "monitor firmware version V1.3 or greater.\r\n"); /* Enable osc32 oscillator*/ if (!osc_is_ready(OSC_ID_OSC32)) { osc_enable(OSC_ID_OSC32); osc_wait_ready(OSC_ID_OSC32); } /* Disable all AST wake enable bits for safety since the AST is reset only by a POR. */ 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); ast_disable_wakeup(AST, AST_WAKEUP_ALARM); ast_disable_wakeup(AST, AST_WAKEUP_PER); ast_disable_wakeup(AST, AST_WAKEUP_OVF); ast_disable(AST); /* Config the push button */ config_buttons(); /* Configurate the USART to board monitor */ bm_init(); sysclk_enable_hsb_module(SYSCLK_PBA_BRIDGE); sysclk_enable_peripheral_clock(BM_USART_USART); /* Init the PICOUART */ picouart_get_config_defaults(&config); picouart_init(&dev_inst, PICOUART, &config); /* Enable the PICOUART */ picouart_enable(&dev_inst); /* PICOUART and EIC can wakeup the device */ config_wakeup(); /* Display menu */ display_menu(); while (1) { scanf("%c", (char *)&key); switch (key) { case 'h': display_menu(); break; case 's': if (bm_flag) { printf("Switch off the board monitor to wake up..\r\n"); bm_flag = false; } else { printf("Switch on the board monitor to wake up..\r\n"); bm_flag = true; } break; case '0': printf("Enter Sleep mode with start bit wakeup.\r\n"); config.action = PICOUART_ACTION_WAKEUP_ON_STARTBIT; picouart_set_config(&dev_inst, &config); if (bm_flag) { printf("Board monitor will send frame after 3 seconds.\r\n"); bm_send_picouart_frame('A', 3000); } /* Wait for the printf operation to finish before setting the device in a power save mode. */ delay_ms(30); bpm_sleep(BPM, BPM_SM_SLEEP_2); printf("--Exit Sleep mode.\r\n\r\n"); break; case '1': printf("Enter Retention mode with full frame wakeup.\r\n"); config.action = PICOUART_ACTION_WAKEUP_ON_FULLFRAME; picouart_set_config(&dev_inst, &config); if (bm_flag) { printf("Board monitor will send frame after 3 seconds.\r\n"); bm_send_picouart_frame('T', 3000); } /* Wait for the printf operation to finish before setting the device in a power save mode. */ delay_ms(30); bpm_sleep(BPM, BPM_SM_RET); printf("--Exit Retention mode.\r\n\r\n"); break; case '2': printf("Enter backup mode with character match wakeup.\r\n"); config.action = PICOUART_ACTION_WAKEUP_ON_MATCH; config.match = 'L'; picouart_set_config(&dev_inst, &config); if (bm_flag) { printf("Board monitor will send frame after 3 seconds.\r\n"); bm_send_picouart_frame('L', 3000); } /* Wait for the printf operation to finish before setting the device in a power save mode. */ delay_ms(30); bpm_sleep(BPM, BPM_SM_BACKUP); break; default: break; } } }
/** * \brief main function : do init and loop */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ printf("-- AST Example 1 in Calendar Mode --\r\n"); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); printf("Config AST with 32 KHz oscillator.\r\n"); /* Enable osc32 oscillator*/ if (!osc_is_ready(OSC_ID_OSC32)) { osc_enable(OSC_ID_OSC32); osc_wait_ready(OSC_ID_OSC32); } struct ast_calendar calendar; calendar.FIELD.sec = 0; calendar.FIELD.min = 15; calendar.FIELD.hour = 12; calendar.FIELD.day = 20; calendar.FIELD.month = 9; calendar.FIELD.year = 14; /* Enable the AST */ ast_enable(AST); struct ast_config ast_conf; ast_conf.mode = AST_CALENDAR_MODE; ast_conf.osc_type = AST_OSC_32KHZ; ast_conf.psel = AST_PSEL_32KHZ_1HZ; ast_conf.calendar = calendar; /* Initialize the AST */ if (!ast_set_config(AST, &ast_conf)) { printf("Error initializing the AST\r\n"); while (1) { } } while (1) { /* slow down operations */ delay_s(1); ioport_toggle_pin_level(LED0_GPIO); /* Output the calendar */ calendar = ast_read_calendar_value(AST); printf("\r"); printf("Calendar: Year:%02u Month:%02u Day:%02u, %02uh%02um%02us ", (unsigned int)calendar.FIELD.year, (unsigned int)calendar.FIELD.month, (unsigned int)calendar.FIELD.day, (unsigned int)calendar.FIELD.hour, (unsigned int)calendar.FIELD.min, (unsigned int)calendar.FIELD.sec); } }
int main(void) { sysclk_init(); board_init(); /* Enable one wait state for flash access */ flashcalw_set_wait_state(1); /* * Configure systick for 200ms (CPU frequency / 5) at startup time. * * Note: CPU frequency will be changed with below clock switching. */ if (SysTick_Config(sysclk_get_cpu_hz() / 5)) { while (1) { /* Capture error */ } } while (1) { struct dfll_config dcfg; struct pll_config pcfg; /* avoid Cppcheck Warning */ UNUSED(pcfg); /* * Initial state: Running from RC80M with all * prescalers set to 2 (Divide frequency by 4). */ wait_for_switches(); /* * Divide CPU frequency by 8. This will make the LED * blink half as fast. */ sysclk_set_prescalers(3, 3, 3, 3, 3); wait_for_switches(); /* * Switch to the DFLL running at ~48 MHz in Open Loop * mode, with the CPU running at ~48 MHz. */ dfll_config_init_open_loop_mode(&dcfg); dfll_config_tune_for_target_hz(&dcfg, 48000000); dfll_enable_open_loop(&dcfg, 0); sysclk_set_prescalers(1, 1, 1, 1, 1); sysclk_set_source(SYSCLK_SRC_DFLL); osc_disable(OSC_ID_RC80M); wait_for_switches(); /* * Switch to the slow clock with all prescalers * disabled. */ sysclk_set_source(SYSCLK_SRC_RCSYS); sysclk_set_prescalers(0, 0, 0, 0, 0); dfll_disable_open_loop(0); wait_for_switches(); /* * Switch to the RCFAST clock with all prescalers * disabled. */ osc_enable(OSC_ID_RCFAST); sysclk_set_prescalers(0, 0, 0, 0, 0); osc_wait_ready(OSC_ID_RCFAST); sysclk_set_source(SYSCLK_SRC_RCFAST); wait_for_switches(); /* * Switch to the RC1M clock with all prescalers * disabled. */ osc_enable(OSC_ID_RC1M); sysclk_set_prescalers(0, 0, 0, 0, 0); osc_wait_ready(OSC_ID_RC1M); sysclk_set_source(SYSCLK_SRC_RC1M); osc_disable(OSC_ID_RCFAST); wait_for_switches(); /* * Switch to external OSC0, if available. */ #ifdef BOARD_OSC0_HZ osc_enable(OSC_ID_OSC0); osc_wait_ready(OSC_ID_OSC0); sysclk_set_source(SYSCLK_SRC_OSC0); osc_disable(OSC_ID_RC1M); wait_for_switches(); /* * Switch to PLL0 running at 96 MHz. Use OSC0 as the * source */ pll_config_init(&pcfg, PLL_SRC_OSC0, 1, 96000000 / BOARD_OSC0_HZ); pll_enable(&pcfg, 0); sysclk_set_prescalers(2, 2, 2, 2, 2); pll_wait_for_lock(0); sysclk_set_source(SYSCLK_SRC_PLL0); wait_for_switches(); #endif /* * Switch to the DFLL, using the 32 kHz oscillator as a * reference if available, or failing that, the 115 kHz * RCSYS oscillator. */ #ifdef BOARD_OSC32_HZ osc_enable(OSC_ID_OSC32); dfll_config_init_closed_loop_mode(&dcfg, GENCLK_SRC_OSC32K, 1, CONFIG_DFLL0_FREQ / BOARD_OSC32_HZ); osc_wait_ready(OSC_ID_OSC32); #else dfll_config_init_closed_loop_mode(&dcfg, GENCLK_SRC_RCSYS, 1, CONFIG_DFLL0_FREQ / OSC_RCSYS_NOMINAL_HZ); #endif dfll_enable_closed_loop(&dcfg, 0); sysclk_set_prescalers(1, 1, 1, 1, 1); dfll_wait_for_fine_lock(0); sysclk_set_source(SYSCLK_SRC_DFLL); #ifdef BOARD_OSC0_HZ osc_disable(OSC_ID_OSC0); #endif wait_for_switches(); /* * Go back to the initial state and start over. */ osc_enable(OSC_ID_RC80M); sysclk_set_prescalers(2, 2, 2, 2, 2); osc_wait_ready(OSC_ID_RC80M); sysclk_set_source(SYSCLK_SRC_RC80M); dfll_disable_closed_loop(0); #ifdef BOARD_OSC32_HZ osc_disable(OSC_ID_OSC32); #endif } }
void sysclk_init(void) { uint8_t *reg = (uint8_t *)&PR.PRGEN; uint8_t i; #ifdef CONFIG_OSC_RC32_CAL uint16_t cal; #endif bool need_rc2mhz = false; /* Turn off all peripheral clocks that can be turned off. */ for (i = 0; i <= SYSCLK_PORT_F; i++) { *(reg++) = 0xff; } /* Set up system clock prescalers if different from defaults */ if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, CONFIG_SYSCLK_PSBCDIV); } #if (CONFIG_OSC_RC32_CAL==48000000UL) MSB(cal) = nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSC)); LSB(cal) = nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSCA)); /* * If a device has an uncalibrated value in the * production signature row (early sample part), load a * sane default calibration value. */ if (cal == 0xFFFF) { cal = 0x2340; } osc_user_calibration(OSC_ID_RC32MHZ,cal); #endif /* * Switch to the selected initial system clock source, unless * the default internal 2 MHz oscillator is selected. */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { need_rc2mhz = true; } else { switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_RC32MHZ: osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); #ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF) { osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); } osc_enable_autocalibration(OSC_ID_RC32MHZ, CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); #endif break; case SYSCLK_SRC_RC32KHZ: osc_enable(OSC_ID_RC32KHZ); osc_wait_ready(OSC_ID_RC32KHZ); break; case SYSCLK_SRC_XOSC: osc_enable(OSC_ID_XOSC); osc_wait_ready(OSC_ID_XOSC); break; #ifdef CONFIG_PLL0_SOURCE case SYSCLK_SRC_PLL: if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { need_rc2mhz = true; } pll_enable_config_defaults(0); break; #endif default: //unhandled_case(CONFIG_SYSCLK_SOURCE); return; } ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); } if (need_rc2mhz) { #ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); osc_enable_autocalibration(OSC_ID_RC2MHZ, CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); #endif } else { osc_disable(OSC_ID_RC2MHZ); } #ifdef CONFIG_RTC_SOURCE sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); #endif }
void sysclk_init(void) { uint8_t *reg = (uint8_t *)&PR.PRGEN; uint8_t i; #ifdef CONFIG_OSC_RC32_CAL uint16_t cal; #endif /* Turn off all peripheral clocks that can be turned off. */ for (i = 0; i <= SYSCLK_PORT_F; i++) { *(reg++) = 0xff; } /* Set up system clock prescalers if different from defaults */ if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, CONFIG_SYSCLK_PSBCDIV); } #if (CONFIG_OSC_RC32_CAL==48000000UL) MSB(cal) = nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSC)); LSB(cal) = nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSCA)); /* * If a device has an uncalibrated value in the * production signature row (early sample part), load a * sane default calibration value. * * MODIFIED 16-7-2012 by C.DOGGEN: * - commented the if statement, otherwise the USART won't work * - don't know exactly the problem, but this seems to be a workaround. */ if (cal == 0xFFFF) { cal = 0x2340; } osc_user_calibration(OSC_ID_RC32MHZ,cal); #endif /* * Switch to the selected initial system clock source, unless * the default internal 2 MHz oscillator is selected. */ if (CONFIG_SYSCLK_SOURCE != SYSCLK_SRC_RC2MHZ) { bool need_rc2mhz = false; switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_RC32MHZ: osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); break; case SYSCLK_SRC_RC32KHZ: osc_enable(OSC_ID_RC32KHZ); osc_wait_ready(OSC_ID_RC32KHZ); break; case SYSCLK_SRC_XOSC: osc_enable(OSC_ID_XOSC); osc_wait_ready(OSC_ID_XOSC); break; #ifdef CONFIG_PLL0_SOURCE case SYSCLK_SRC_PLL: if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { need_rc2mhz = true; } pll_enable_config_defaults(0); break; #endif default: //unhandled_case(CONFIG_SYSCLK_SOURCE); return; } ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); #ifdef CONFIG_OSC_AUTOCAL osc_enable_autocalibration(CONFIG_OSC_AUTOCAL,CONFIG_OSC_AUTOCAL_REF_OSC); if (CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ || CONFIG_OSC_AUTOCAL_REF_OSC == OSC_ID_RC2MHZ) { need_rc2mhz = true; } #endif if (!need_rc2mhz) { osc_disable(OSC_ID_RC2MHZ); } } }
void sysclk_init(void) { struct pll_config pllcfg; /* Set a flash wait state depending on the new cpu frequency */ system_init_flash(sysclk_get_cpu_hz()); /* Config system clock setting */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) { osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) { osc_enable(OSC_SLCK_32K_XTAL); osc_wait_ready(OSC_SLCK_32K_XTAL); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) { osc_enable(OSC_SLCK_32K_BYPASS); osc_wait_ready(OSC_SLCK_32K_BYPASS); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) { /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) { osc_enable(OSC_MAINCK_8M_RC); osc_wait_ready(OSC_MAINCK_8M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) { osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) { osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) { osc_enable(OSC_MAINCK_BYPASS); osc_wait_ready(OSC_MAINCK_BYPASS); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } #ifdef CONFIG_PLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) { pll_enable_source(CONFIG_PLL0_SOURCE); // Source is mainck, select source for mainck if (CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_4M_RC || CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_8M_RC || CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_12M_RC) { pmc_mainck_osc_select(0); while(!pmc_osc_is_ready_mainck()); # ifndef CONFIG_PLL1_SOURCE pmc_osc_disable_main_xtal(); # endif } else if (CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_XTAL || CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_BYPASS) { pmc_mainck_osc_select(CKGR_MOR_MOSCSEL); while(!pmc_osc_is_ready_mainck()); } pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); } #endif else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_UPLLCK) { pll_enable_source(CONFIG_PLL1_SOURCE); pll_config_defaults(&pllcfg, 1); pll_enable(&pllcfg, 1); pll_wait_for_lock(1); pmc_switch_mck_to_upllck(CONFIG_SYSCLK_PRES); } /* Update the SystemFrequency variable */ SystemCoreClockUpdate(); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = 1; #endif }
/** * \brief Test watchdog for all cases. * * \note Because MCU will be reset serval times druing the test, * to simplify the design, only one test case but with many test stages. * * \param test Current test case. */ static void run_wdt_test_all(const struct test_case *test) { struct wdt_dev_inst wdt_inst; struct wdt_config wdt_cfg; uint32_t wdt_window_ms = 0; uint32_t wdt_timeout_ms = 0; uint32_t wdt_ut_stage; /* Get test stage */ wdt_ut_stage = (uint32_t)(*(uint32_t *)WDT_UT_TAG_ADDR); if (is_wdt_reset()) { /* Check if the reset is as expected */ switch (wdt_ut_stage) { case WDT_UT_STAGE_START: test_assert_true(test, 0, "Unexpected watchdog reset at start stage!"); break; case WDT_UT_STAGE_RST_MCU: /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_BM_NORMAL; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); break; case WDT_UT_STAGE_BM_NORMAL: test_assert_true(test, 0, "Unexpected watchdog reset at basic mode!"); break; case WDT_UT_STAGE_BM_TIMEOUT_RST: /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_WM_NORMAL; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); break; case WDT_UT_STAGE_WM_NORMAL: test_assert_true(test, 0, "Unexpected watchdog reset at window mode!"); break; case WDT_UT_STAGE_WM_TIMEBAN_RST: /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_WM_TIMEOUT_RST; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); break; case WDT_UT_STAGE_WM_TIMEOUT_RST: /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_END; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); break; case WDT_UT_STAGE_END: test_assert_true(test, 0, "Unexpected watchdog reset at end stage!"); break; default: test_assert_true(test, 0, "Unexpected watchdog reset!"); break; } } else { /* First WDT unit test start at here, set stage flag */ wdt_ut_stage = WDT_UT_STAGE_START; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); } /* * ---- Test reset MCU by the WDT ---- */ if (wdt_ut_stage == WDT_UT_STAGE_START) { bool ret; /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_RST_MCU; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); /* Reset MCU by the watchdog. */ ret = wdt_reset_mcu(); test_assert_false(test, ret, "Can't reset MCU by the WDT: failed!"); /* The code should not go to here */ test_assert_true(test, 0, "Reset MCU by the WDT: failed!"); } /* * ---- Test the WDT in basic mode ---- */ if ((wdt_ut_stage & WDT_UT_STAGE_MASK) == WDT_UT_STAGE_BM) { /* * Intialize the watchdog in basic mode: * - Use default configuration. * - But change timeout period to 0.57s * (Ttimeout = 2pow(PSEL+1) / Fclk_cnt = 65535 / 115000). */ wdt_get_config_defaults(&wdt_cfg); wdt_cfg.timeout_period = WDT_PERIOD_65536_CLK; wdt_timeout_ms = 570; wdt_init(&wdt_inst, WDT, &wdt_cfg); wdt_enable(&wdt_inst); wdt_clear(&wdt_inst); mdelay(wdt_timeout_ms / 2); wdt_clear(&wdt_inst); /* The code should reach here */ test_assert_true(test, 1, "Clear the WDT in basic mode: passed."); /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_BM_TIMEOUT_RST; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); /* Wait for the WDT reset */ mdelay(wdt_timeout_ms * 2); /* The code should not go to here, disable watchdog for default */ wdt_disable(&wdt_inst); test_assert_true(test, 0, "No WDT reset happened in basic mode!"); } /* * ---- Test the WDT in window mode ---- */ if ((wdt_ut_stage & WDT_UT_STAGE_MASK) == WDT_UT_STAGE_WM) { /* Enable WDT clock source if need */ if (BPM->BPM_PMCON & BPM_PMCON_CK32S) { /* Enable 32K RC oscillator */ if (!osc_is_ready(OSC_ID_RC32K)) { osc_enable(OSC_ID_RC32K); osc_wait_ready(OSC_ID_RC32K); } } else { /* Enable external OSC32 oscillator */ if (!osc_is_ready(OSC_ID_OSC32)) { osc_enable(OSC_ID_OSC32); osc_wait_ready(OSC_ID_OSC32); } } /* * Intialize the watchdog in window mode: * - Use 32K oscillator as WDT clock source. * - Set timeout/timeban period to 0.5s * (Ttimeout = 2pow(PSEL+1) / Fclk_cnt = 16384 / 32768). */ wdt_get_config_defaults(&wdt_cfg); wdt_cfg.wdt_mode = WDT_MODE_WINDOW; wdt_cfg.clk_src = WDT_CLK_SRC_32K; wdt_cfg.window_period = WDT_PERIOD_16384_CLK; wdt_cfg.timeout_period = WDT_PERIOD_16384_CLK; wdt_window_ms = 500; wdt_timeout_ms = 500; wdt_init(&wdt_inst, WDT, &wdt_cfg); wdt_enable(&wdt_inst); mdelay(wdt_window_ms + wdt_timeout_ms / 10); wdt_clear(&wdt_inst); /* The code should reach here */ test_assert_true(test, 1, "Clear the WDT in window mode: passed."); if (wdt_ut_stage == WDT_UT_STAGE_WM_NORMAL) { /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_WM_TIMEBAN_RST; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); /* Clear the WDT in time ban window */ wdt_clear(&wdt_inst); /* The WDT reset should happen */ mdelay(50); } else if (wdt_ut_stage == WDT_UT_STAGE_WM_TIMEOUT_RST) { /* Wait for the WDT reset when timeout */ mdelay(wdt_window_ms); mdelay(wdt_timeout_ms * 2); } /* The code should not go to here, disable watchdog for default */ wdt_disable(&wdt_inst); test_assert_true(test, 0, "No WDT reset happened in window mode!"); } /* * ---- Check if all test are OK ---- */ if (wdt_ut_stage == WDT_UT_STAGE_END) { test_assert_true(test, 1, "All test stages done for WDT."); /* Clear flash content */ wdt_ut_stage = 0xFFFFFFFFu; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); } else { test_assert_true(test, 0, "WDT test stopped with unexpected stages."); } }