/** * \brief Test backup mode. * * \note To test backup mode, the program must run out of flash. */ static void test_backup_mode(void) { puts(STRING_BACKUP); /* Wait for the transmission done before changing clock */ while (!uart_is_tx_empty(CONSOLE_UART)) { } /* GPBR0 is for recording times of entering into backup mode */ gpbr_write(GPBR0, gpbr_read(GPBR0) + 1); /* Enable the PIO for wake-up */ example_set_wakeup_from_backup_mode(); /* Switch MCK to slow clock */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* Disable unused clock to save power */ pmc_osc_disable_xtal(0); example_disable_pll(); /* Enter into backup mode */ pmc_enable_backupmode(); /* Note: The core will reset when exiting from backup mode. */ }
/** * \brief Initialize the chip for low power test. */ static void init_chip(void) { /* Wait for the transmission done before changing clock */ while (!uart_is_tx_empty(CONSOLE_UART)) { } /* Disable all the peripheral clocks */ pmc_disable_all_periph_clk(); /* Disable brownout detector */ supc_disable_brownout_detector(SUPC); /* Initialize the specific board */ init_specific_board(); }
/** * \brief Test wait mode. */ static void test_wait_mode(void) { puts(STRING_WAIT); #if SAMG55 /* Wait for the transmission done before changing clock */ while (!usart_is_tx_empty(CONSOLE_UART)) { } #else /* Wait for the transmission done before changing clock */ while (!uart_is_tx_empty(CONSOLE_UART)) { } #endif /* Configure fast RC oscillator */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); #if (SAMG) pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); #else pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); #endif pmc_switch_mck_to_mainck(PMC_PCK_PRES_CLK_1); #if (SAMG) g_ul_current_mck = 8000000; /* 8MHz */ #else g_ul_current_mck = 4000000; /* 4MHz */ #endif /* Disable unused clock to save power */ pmc_osc_disable_xtal(0); example_disable_pll(); /* Set wakeup input for fast startup */ example_set_wakeup_from_wait_mode(); /* Enter into wait Mode */ pmc_enable_waitmode(); /* Set default clock and re-configure UART */ set_default_working_clock(); reconfigure_console(g_ul_current_mck, CONF_UART_BAUDRATE); puts("Exit from wait Mode.\r"); }
/** * \brief Application entry point for RTC tamper example. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t ul_read_value[8] = {0, 0 ,0, 0, 0, 0, 0, 0}; uint32_t ul_hour0, ul_minute0, ul_second0; uint32_t ul_year0, ul_month0, ul_day0, ul_week0; uint32_t ul_hour1, ul_minute1, ul_second1; uint32_t ul_year1, ul_month1, ul_day1, ul_week1; uint32_t tmp_src0, tmp_src1, tmp_cnt; uint8_t uc_key; /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Default RTC configuration, 24-hour mode */ rtc_set_hour_mode(RTC, 0); rtc_set_waveform(RTC, RTC_OUT_CHN, RTC_OUT_SRC); if(rstc_get_reset_cause(RSTC) == RSTC_SR_RSTTYP_BackupReset) { /* Read the data from GPBR0 ~ 7 */ ul_read_value[0] = gpbr_read(GPBR0); ul_read_value[1] = gpbr_read(GPBR1); ul_read_value[2] = gpbr_read(GPBR2); ul_read_value[3] = gpbr_read(GPBR3); ul_read_value[4] = gpbr_read(GPBR4); ul_read_value[5] = gpbr_read(GPBR5); ul_read_value[6] = gpbr_read(GPBR6); ul_read_value[7] = gpbr_read(GPBR7); if((ul_read_value[0] == 0) && (ul_read_value[1] == 0) && (ul_read_value[2] == 0) && (ul_read_value[3] == 0) && (ul_read_value[4] == 0) && (ul_read_value[5] == 0) && (ul_read_value[6] == 0) && (ul_read_value[7] == 0)) { printf("The backup register is cleared when tamper event happen!\r\n"); } else { printf("The backup register is not cleared when tamper event happen!\r\n"); } /* Retrieve tamper date and time */ rtc_get_tamper_time(RTC, &ul_hour0, &ul_minute0, &ul_second0, 0); rtc_get_tamper_date(RTC, &ul_year0, &ul_month0, &ul_day0, &ul_week0, 0); rtc_get_tamper_time(RTC, &ul_hour1, &ul_minute1, &ul_second1, 1); rtc_get_tamper_date(RTC, &ul_year1, &ul_month1, &ul_day1, &ul_week1, 1); tmp_cnt = rtc_get_tamper_event_counter(RTC); tmp_src0 = rtc_get_tamper_source(RTC, 0); tmp_src1 = rtc_get_tamper_source(RTC, 1); printf("The first tamper event TMP%u happen in %02u:%02u:%02u,%02u/%02u/%04u\r\n", (unsigned int)tmp_src0, (unsigned int)ul_hour0, (unsigned int)ul_minute0, (unsigned int)ul_second0, (unsigned int)ul_month0, (unsigned int)ul_day0, (unsigned int)ul_year0); printf("The last tamper event TMP%u happen in %02u:%02u:%02u,%02u/%02u/%04u\r\n", (unsigned int)tmp_src1, (unsigned int)ul_hour1, (unsigned int)ul_minute1, (unsigned int)ul_second1, (unsigned int)ul_month1, (unsigned int)ul_day1, (unsigned int)ul_year1); printf("The tamper event counter is %u \r\n", (unsigned int)tmp_cnt); } printf("Press any key to Enter Backup Mode!\r\n"); while (uart_read(CONSOLE_UART, &uc_key)); /* Write the data to the backup register GPBR0 ~ 7 */ gpbr_write(GPBR0, GPBR_CONST_DATA); gpbr_write(GPBR1, GPBR_CONST_DATA); gpbr_write(GPBR2, GPBR_CONST_DATA); gpbr_write(GPBR3, GPBR_CONST_DATA); gpbr_write(GPBR4, GPBR_CONST_DATA); gpbr_write(GPBR5, GPBR_CONST_DATA); gpbr_write(GPBR6, GPBR_CONST_DATA); gpbr_write(GPBR7, GPBR_CONST_DATA); /* Enable TMP0 and TMP2 low power debouncer and clear GPBR when event happen */ supc_set_wakeup_mode(SUPC, SUPC_WUMR_LPDBCEN0_ENABLE | SUPC_WUMR_LPDBCCLR_ENABLE | SUPC_WUMR_LPDBCEN2_ENABLE | SUPC_WUMR_LPDBC_2_RTCOUT0); /* Enable TMP0 and TMP2 wake-up input and set input type*/ supc_set_wakeup_inputs(SUPC, SUPC_WUIR_WKUPEN0_ENABLE | SUPC_WUIR_WKUPEN14_ENABLE, SUPC_WUIR_WKUPT0_LOW | SUPC_WUIR_WKUPT14_LOW); printf("Enter Backup Mode!\r\n"); printf("Please press button TMP0 or TMP2 to wake up!\r\n\r\n"); /* Ensure TX is done before enter backup mode */ while (!uart_is_tx_empty(CONSOLE_UART)) { } /* Enter backup mode */ pmc_enable_backupmode(); while (1) { } }
/** * \brief Change clock configuration. * * \param p_uc_str Hint string to be output on console before changing clock. */ static void user_change_clock(uint8_t *p_uc_str) { uint8_t uc_key; uint32_t ul_id; /* Print menu */ puts(CLOCK_LIST_MENU); while (uart_read(CONSOLE_UART, &uc_key)) { } printf("Select option is: %c\n\r\n\r", uc_key); if (p_uc_str) { puts((char const *)p_uc_str); } while (!uart_is_tx_empty(CONSOLE_UART)) { } if ((uc_key >= MIN_CLOCK_FAST_RC_ITEM) && (uc_key <= MAX_CLOCK_FAST_RC_ITEM)) { ul_id = uc_key - MIN_CLOCK_FAST_RC_ITEM; /* Save current clock */ g_ul_current_mck = g_fastrc_clock_list[ul_id][0]; /* Switch MCK to Slow clock */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* Switch mainck to fast RC */ pmc_osc_enable_fastrc(CKGR_MOR_MOSCRCF_8_MHz); pmc_switch_mainck_to_fastrc(g_fastrc_clock_list[ul_id][1]); /* Switch MCK to mainck */ pmc_switch_mck_to_mainck(g_fastrc_clock_list[ul_id][2]); /* Disable unused clock to save power */ pmc_osc_disable_xtal(0); example_disable_pll(); } else if ((uc_key >= MIN_CLOCK_PLL_ITEM) && (uc_key <= MAX_CLOCK_PLL_ITEM)) { ul_id = uc_key - MIN_CLOCK_PLL_ITEM; /* Save current clock */ g_ul_current_mck = g_pll_clock_list[ul_id][0]; #if (SAMG) /* Switch MCK to main clock */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_1); #else /* Switch MCK to slow clock */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* Switch mainck to external xtal */ pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US); #endif /* Configure PLL and switch clock */ example_switch_clock(g_pll_clock_list[ul_id][1], PLL_COUNT, g_pll_clock_list[ul_id][2], g_pll_clock_list[ul_id][3]); #if (!SAMG) /* Disable unused clock to save power */ pmc_osc_disable_fastrc(); #endif } else { puts("Clock is not changed.\r"); } }
/** * \brief Application entry point for pmc_clock switch example. * * \return Unused (ANSI-C compatibility). */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Configure PCK */ ioport_set_pin_mode(GCLK_PIN, GCLK_PIN_MUX); ioport_disable_pin(GCLK_PIN); /* Configure the push button */ configure_buttons(); puts("-I- Press Button "BUTTON_NAME" to continue.\r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("\n\r-I- Switch 8Mhz fast RC oscillator to be the source of the main clock \n\r" "-I- The master clock is main clock divided by 2\n\r" "-I- From now on, the UART baud rate is 2400bps. So please change the terminal setting before the next clock switch\r\n" "-I- Press Button "BUTTON_NAME" to switch next clock configuration... \r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* First switch to slow clock */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); #if (SAM3S || SAM4S || SAM4C) /* Then cut the PLL B */ pmc_disable_pllbck(); #endif /* Switch the mainck clock to the Fast RC, parameter '1' stands for 8Mhz */ pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); /* And finalize by switching to Fast RC */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_2); /* The clock source for the UART is the PCK, so the uart needs re-configuration */ config_uart_and_pck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES_CLK_2, (CHIP_FREQ_MAINCK_RC_8MHZ / 2)); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("\n\r-I- Switch the XTAL 32K crystal oscillator to be the source of the slow clock\n\r" "-I- The master clock is slow clock\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration after it has been measured.\r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Enable the External 32K oscillator */ pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); /* If a new value for CSS field corresponds to Main Clock or Slow Clock, * program the CSS field first. */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* The clock source for the UART is the PCK, so the uart needs *re-configuration. */ config_uart_and_pck(PMC_PCK_CSS_SLOW_CLK, PMC_PCK_PRES_CLK_1, BOARD_FREQ_SLCK_XTAL); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } /* Switch the mainck to the Fast RC, parameter '2' stands for 12Mhz */ pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); /* If a new value for CSS field corresponds to Main Clock or Slow Clock, * program the CSS field first. */ pmc_switch_mck_to_mainck(PMC_PCK_PRES_CLK_1); /* The clock source for the UART is the PCK, so the uart needs * re-configuration. */ config_uart_and_pck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES_CLK_1, CHIP_FREQ_MAINCK_RC_12MHZ); puts("\n\r-I- Switch 12Mhz fast RC oscillator to be the source of the main clock\n\r" "-I- The master clock is the main clock\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration after it has been measured.\r\n"); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } #if SAM4C puts("-I- Switch to 8.192Mhz PLLA clock as the source of the master clock \n\r" "-I- The master clock is PLLA clock divided by 2 \n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration... \r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Enable the PLLA clock, the mainck equals 32.768K * 250 = 8.192Mhz */ pmc_enable_pllack((250 - 1), 0x3f, 1); #else puts("-I- Switch to 128Mhz PLLA clock as the source of the master clock \n\r" "-I- The master clock is PLLA clock divided by 2 \n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration... \r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Enable the PLLA clock, the mainck equals 12Mhz * (32-1+1) / 3 = 128Mhz */ pmc_enable_pllack((32 - 1), 0x3f, 3); #endif /* If a new value for CSS field corresponds to PLL Clock, Program the PRES * field first. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_2); /* Delay for a while */ /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Then program the CSS field. */ pmc_switch_mck_to_pllack(PMC_MCKR_PRES_CLK_2); /* The clock source for the UART is the PCK, so the uart needs * re-configuration */ config_uart_and_pck(PMC_PCK_CSS_PLLA_CLK, PMC_PCK_PRES_CLK_2, PMC_CLOCK_SWITCHING_EXAMPLE_FIXED_PLLA/2); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("\n\r-I- Switch the XTAL 32K crystal oscillator to be the source of the slow clock\n\r" "-I- The master clock is slow clock\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration...\r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Switch slow clck to extern 32k xtal */ pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); /* Delay for a while to make sure the clock is stable */ /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* If a new value for CSS field corresponds to Main Clock or Slow Clock, * program the CSS field first. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_2); /* Switch the mck to sclk but keep the PRES field same */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_2); /* Then program the PRES field. */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* The clock source for the UART is the PCK, so the uart needs * re-configuration */ config_uart_and_pck(PMC_PCK_CSS_SLOW_CLK, PMC_PCK_PRES_CLK_1, BOARD_FREQ_SLCK_XTAL); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } /* Switch mainck to external xtal */ pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US); /* If a new value for CSS field corresponds to Main Clock or Slow Clock, * program the CSS field first. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_1); /* Then program the PRES field. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_16); /* The clock source for the UART is the PCK, so the uart needs * re-configuration. */ config_uart_and_pck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES_CLK_16, (BOARD_FREQ_MAINCK_XTAL / 16)); #if SAM4C puts("\n\r-I- Switch the external 8MHz crystal oscillator to be the source of the main clock\n\r" "-I- The master clock is main clock divided by 16\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration...\r\n"); #else puts("\n\r-I- Switch the external 12MHz crystal oscillator to be the source of the main clock\n\r" "-I- The master clock is main clock divided by 16\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration...\r\n"); #endif #if (SAM3S || SAM4S || SAM4C) for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("-I- Switch to 96Mhz PLLB clock as the source of the master clock\n\r" "-I- The master clock is PLLB clock divided by 2 \r"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; #if SAM4C /* Enable the PLLB clock, the mainck equals (8Mhz * (11+1) / 1) = 96Mhz * with the initialize counter be 0x3f */ pmc_enable_pllbck(11, 0x3f, 1); #else /* Enable the PLLB clock, the mainck equals (12Mhz * (7+1) / 1) = 96Mhz * with the initialize counter be 0x3f */ pmc_enable_pllbck(7, 0x3f, 1); #endif /* If a new value for CSS field corresponds to PLL Clock, Program the PRES * field first. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_2); /* Then program the CSS field. */ pmc_switch_mck_to_pllbck(PMC_MCKR_PRES_CLK_2); /* The clock source for the UART is the PCK, so the uart needs * re-configuration. */ #if SAM4C config_uart_and_pck(PMC_PCK_CSS_PLLB_CLK, PMC_PCK_PRES_CLK_2, (BOARD_FREQ_MAINCK_XTAL * 12 / 2)); #else config_uart_and_pck(PMC_PCK_CSS_PLLB_CLK, PMC_PCK_PRES_CLK_2, (BOARD_FREQ_MAINCK_XTAL * 8 / 2)); #endif puts("-I- Press Button "BUTTON_NAME" to switch next clock configuration...\r\n"); #endif for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("\r\n\r\n-I- Done.\r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; while (1) { } }