OSStatus platform_mcu_powersave_init(void) { #ifndef MICO_DISABLE_MCU_POWERSAVE #error Not working currently, uncomment MICO_DISABLE_MCU_POWERSAVE in platform_config.h /* Initialise all pins to be input pull-up to save power */ ioport_enable_port( IOPORT_PIOA, 0xffffffffU ); ioport_set_port_mode( IOPORT_PIOA, 0xffffffffU, IOPORT_MODE_PULLUP ); ioport_set_port_dir( IOPORT_PIOA, 0xffffffffU, IOPORT_DIR_INPUT ); ioport_enable_port( IOPORT_PIOB, 0xffffffffU ); ioport_set_port_mode( IOPORT_PIOB, 0xffffffffU, IOPORT_MODE_PULLUP ); ioport_set_port_dir( IOPORT_PIOB, 0xffffffffU, IOPORT_DIR_INPUT ); NVIC_DisableIRQ( RTT_IRQn ); NVIC_ClearPendingIRQ( RTT_IRQn ); NVIC_EnableIRQ( RTT_IRQn ); pmc_set_fast_startup_input( PMC_FSMR_RTTAL ); rtt_init( RTT, RTT_CLOCK_PRESCALER ); rtt_write_alarm_time( RTT, 64000 ); #endif /* MICO_DISABLE_MCU_POWERSAVE */ return kNoErr; }
int main(void) { enum sleepmgr_mode current_sleep_mode = SLEEPMGR_ACTIVE; /* * Initialize the synchronous clock system to the default configuration * set in conf_clock.h. * \note All non-essential peripheral clocks are initially disabled. */ sysclk_init(); /* * Initialize the resources used by this example to the default * configuration set in conf_board.h */ board_init(); /* * Turn the activity status LED on to inform the user that the device * is active. */ ioport_set_pin_level(LED_ACTIVITY_STATUS_PIN, LED_STATUS_ON); rtt_init(RTT, 32768); /* Enable RTT interrupt */ NVIC_DisableIRQ(RTT_IRQn); NVIC_ClearPendingIRQ(RTT_IRQn); NVIC_SetPriority(RTT_IRQn, 0); NVIC_EnableIRQ(RTT_IRQn); rtt_enable_interrupt(RTT, RTT_MR_ALMIEN); /* Set wakeup source to rtt_alarm */ pmc_set_fast_startup_input(PMC_FSMR_RTTAL); #if (!SAMG) supc_set_wakeup_mode(SUPC, SUPC_WUMR_RTTEN_ENABLE); #endif /* Initialize the sleep manager, lock initial mode. */ sleepmgr_init(); sleepmgr_lock_mode(current_sleep_mode); while (1) { rtt_write_alarm_time(RTT, rtt_read_timer_value(RTT) + SLEEP_TIME); /* * Turn the activity status LED off to inform the user that the * device is in a sleep mode. */ ioport_set_pin_level(LED_ACTIVITY_STATUS_PIN, LED_STATUS_OFF); /* * Go to sleep in the deepest allowed sleep mode (i.e. no * deeper than the currently locked sleep mode). */ sleepmgr_enter_sleep(); /* * Turn the activity status LED on to inform the user that the * device is active. */ ioport_set_pin_level(LED_ACTIVITY_STATUS_PIN, LED_STATUS_ON); /* Unlock the current sleep mode. */ sleepmgr_unlock_mode(current_sleep_mode); /* Add a 3s delay. */ delay_s(ACTIVE_TIME); /* Lock the next sleep mode. */ ++current_sleep_mode; if ((current_sleep_mode >= SLEEPMGR_NR_OF_MODES)) { current_sleep_mode = SLEEPMGR_ACTIVE; } sleepmgr_lock_mode(current_sleep_mode); } }
/** * \brief Test GPBR read/write interfaces. * * \param test Current test case. */ static void run_gpbr_test(const struct test_case *test) { uint32_t ul_read_value = 0; uint32_t ul_test_page_addr = TEST_PAGE_ADDRESS; uint32_t *ul_back_mode_flag_addr = (uint32_t *) ul_test_page_addr; uint32_t ul_normal_mode_flag = NORMAL_MODE_FLAG; uint32_t ul_backup_mode_flag = BACKUP_MODE_FLAG; uint8_t uc_write_success_flag = 1; /* Initialize flash: 6 wait states for flash writing. */ flash_init(FLASH_ACCESS_MODE_128, FLASH_WAIT_STATE_NBR); /* Unlock flash page. */ flash_unlock(ul_test_page_addr, ul_test_page_addr + IFLASH_PAGE_SIZE - 1, NULL, NULL); if ((*ul_back_mode_flag_addr) == BACKUP_MODE_FLAG) { /* Read the data from GPBR0 */ ul_read_value = gpbr_read(GPBR0); #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV70 || SAMV71 || SAME70 || SAMS70) /* Erase flag page */ flash_erase_page(ul_test_page_addr, IFLASH_ERASE_PAGES_8); /* Clear backup mode flag */ if (flash_write(ul_test_page_addr, (uint8_t *)&ul_normal_mode_flag, sizeof(uint32_t), 0) != FLASH_RC_OK) { uc_write_success_flag = 0; } #else /* Clear backup mode flag */ if (flash_write(ul_test_page_addr, (uint8_t *)&ul_normal_mode_flag, sizeof(uint32_t), 1) != FLASH_RC_OK) { uc_write_success_flag = 0; } #endif /* Return test result */ test_assert_true(test, (ul_read_value == GPBR_UNIT_TEST_CONST_DATA) && uc_write_success_flag, "Test GPBR: GPBR write error!"); /* Clear GPBR 0 */ gpbr_write(GPBR0, 0); return; } /* Write the data to the backup register 0 */ gpbr_write(GPBR0, GPBR_UNIT_TEST_CONST_DATA); /* Enable RTT wake up */ supc_set_wakeup_mode(SUPC, SUPC_WUMR_RTTEN); /* Configure RTT */ gpbr_test_configure_rtt(); /* Wait for RTT alarm event */ rtt_write_alarm_time(RTT, RTT_WAIT_TIME); #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV70 || SAMV71 || SAME70 || SAMS70) /* Erase flag page */ if(flash_erase_page(ul_test_page_addr, IFLASH_ERASE_PAGES_8) != FLASH_RC_OK) printf("erase page failed!\r\n"); /* Write backup mode flag */ if (flash_write(ul_test_page_addr, (uint8_t *) & ul_backup_mode_flag, sizeof(uint32_t), 0) != FLASH_RC_OK) { /* Flag write failed, return error */ test_assert_true(test, 0, "Test GPBR: GPBR write error!"); } #else /* Write backup mode flag */ if (flash_write(ul_test_page_addr, (uint8_t *) & ul_backup_mode_flag, sizeof(uint32_t), 1) != FLASH_RC_OK) { /* Flag write failed, return error */ test_assert_true(test, 0, "Test GPBR: GPBR write error!"); } #endif /* Enter backup mode */ pmc_enable_backupmode(); #if (!(SAM4S) && !(SAM4E) && !(SAM4N) && !(SAM4C) && !(SAM4CP) && !(SAM4CM) && !(SAMV70) && !(SAMV71) && !(SAME70) && !(SAMS70)) supc_enable_backup_mode(SUPC); #endif /* We should never reach here */ test_assert_true(test, 0, "Test GPBR: GPBR write error!"); }
/** * \brief Application entry point for RTT example. * * Initialize the RTT, display the current time and allow the user to * perform several actions: clear the timer, set an alarm, etc. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint8_t c; /* Initialize the SAM system */ sysclk_init(); board_init(); /* Configure console UART */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Configure RTT */ configure_rtt(); /* Initialize state machine */ g_uc_state = STATE_MAIN_MENU; g_uc_alarmed = 0; refresh_display(); /* User input loop */ while (1) { /* Wait for user input */ while (uart_read(CONSOLE_UART, &c)); /* Main menu mode */ if (g_uc_state == STATE_MAIN_MENU) { /* Reset timer */ if (c == 'r') { configure_rtt(); refresh_display(); } else if (c == 's') { /* Set alarm */ g_uc_state = STATE_SET_ALARM; g_ul_new_alarm = 0; refresh_display(); } else { /* Clear alarm */ if ((c == 'c') && g_uc_alarmed) { g_uc_alarmed = 0; refresh_display(); } } } else if (g_uc_state == STATE_SET_ALARM) { /* Set alarm mode */ /* Number */ if ((c >= '0') && (c <= '9')) { g_ul_new_alarm = g_ul_new_alarm * 10 + c - '0'; refresh_display(); } else if (c == ASCII_BS) { uart_write(CONSOLE_UART, c); g_ul_new_alarm /= 10; refresh_display(); } else if (c == ASCII_CR) { /* Avoid newAlarm = 0 case */ if (g_ul_new_alarm != 0) { rtt_write_alarm_time(RTT, g_ul_new_alarm); } g_uc_state = STATE_MAIN_MENU; refresh_display(); } } } }
static unsigned long wait_mode_power_down_hook( unsigned long delay_ms ) { bool jtag_enabled = ( ( CoreDebug ->DHCSR & CoreDebug_DEMCR_TRCENA_Msk ) != 0 ) ? true : false; bool jtag_delay_elapsed = ( mico_get_time() > JTAG_DEBUG_SLEEP_DELAY_MS ) ? true : false; uint32_t elapsed_cycles = 0; /* Criteria to enter WAIT mode * 1. Clock needed counter is 0 and no JTAG debugging * 2. Clock needed counter is 0, in JTAG debugging session, and MiCO system tick has progressed over 3 seconds. * This is to give OpenOCD enough time to poke the JTAG tap before the CPU enters WAIT mode. */ if ( ( samg5x_clock_needed_counter == 0 ) && ( ( jtag_enabled == false ) || ( ( jtag_enabled == true ) && ( jtag_delay_elapsed == true ) ) ) ) { uint32_t total_sleep_cycles; uint32_t total_delay_cycles; /* Start real-time timer */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); /* Start atomic operation */ DISABLE_INTERRUPTS; /* Ensure deep sleep bit is enabled, otherwise system doesn't go into deep sleep */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Disable SysTick */ SysTick->CTRL &= ( ~( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk ) ); /* End atomic operation */ ENABLE_INTERRUPTS; /* Expected total time CPU executing in this function (including WAIT mode time) */ total_sleep_cycles = MS_TO_CYCLES( delay_ms ); /* Total cycles in WAIT mode loop */ total_delay_cycles = ( total_sleep_cycles / RTT_MAX_CYCLES + 1 ) * RC_OSC_DELAY_CYCLES + WAIT_MODE_ENTER_DELAY_CYCLES + WAIT_MODE_EXIT_DELAY_CYCLES; if ( total_sleep_cycles > total_delay_cycles ) { /* Adjust total sleep cycle to exclude exit delay */ total_sleep_cycles -= WAIT_MODE_EXIT_DELAY_CYCLES; /* Prepare platform specific settings before entering powersave */ // platform_enter_powersave(); ///* Prepare WLAN bus before entering powersave */ //platform_bus_enter_powersave(); /* Disable brownout detector */ supc_disable_brownout_detector( SUPC ); /* Backup system I/0 functions and set all to GPIO to save power */ system_io_backup_value = matrix_get_system_io(); matrix_set_system_io( 0x0CF0 ); /* Switch Master Clock to Main Clock (internal fast RC oscillator) */ pmc_switch_mck_to_mainck( PMC_PCK_PRES_CLK_1 ); /* Switch on internal fast RC oscillator, switch Main Clock source to internal fast RC oscillator and disables external fast crystal */ pmc_switch_mainck_to_fastrc( CKGR_MOR_MOSCRCF_8_MHz ); /* Disable external fast crystal */ pmc_osc_disable_xtal( 0 ); /* Disable PLLA */ pmc_disable_pllack( ); /* This above process introduces certain delay. Add delay to the elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); while ( wake_up_interrupt_triggered == false && elapsed_cycles < total_sleep_cycles ) { uint32_t current_sleep_cycles = total_sleep_cycles - elapsed_cycles; /* Start real-time timer and alarm */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); rtt_write_alarm_time( RTT, ( current_sleep_cycles > RTT_MAX_CYCLES ) ? RTT_MAX_CYCLES - RC_OSC_DELAY_CYCLES : current_sleep_cycles - RC_OSC_DELAY_CYCLES ); __asm("wfi"); /* Enter WAIT mode */ //pmc_enable_waitmode(); /* Clear wake-up status */ rtt_get_status( RTT ); /* Add sleep time to the elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); } /* Re-enable real-time timer to time clock reinitialisation delay */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); /* Reinit fast clock. This takes ~19ms, but the timing has been compensated */ init_clocks(); /* Disable unused clock to save power */ pmc_osc_disable_fastrc(); /* Restore system I/O pins */ matrix_set_system_io( system_io_backup_value ); /* Restore WLAN bus */ //platform_bus_exit_powersave(); // /* Restore platform-specific settings */ // platform_exit_powersave(); /* Add clock reinitialisation delay to elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); /* Disable RTT to save power */ RTT->RTT_MR = (uint32_t)( 1 << 20 ); } } /* Start atomic operation */ DISABLE_INTERRUPTS; /* Switch SysTick back on */ SysTick->CTRL |= ( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk ); /* Clear flag indicating interrupt triggered by wake up pin */ wake_up_interrupt_triggered = false; /* End atomic operation */ ENABLE_INTERRUPTS; /* Return total time in milliseconds */ return CYCLES_TO_MS( elapsed_cycles ); }