/** * \brief Initialize SAM4E_XPRO board for low power test. */ void init_specific_board(void) { /* Disable all Extra functions in matrix except for SWD CLK/IO */ matrix_set_system_io(0x00001C30); /* Configure all PIOs as inputs to save power */ pio_set_input(PIOA, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOB, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOC, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOD, 0xFFFFFFFF, PIO_PULLUP); pio_set_input(PIOE, 0xFFFFFFFF, PIO_PULLUP); /* Disable USB Clock */ pmc_disable_udpck(); /* Disable pull-up on PHY */ pio_pull_up(PIOD, PIO_PD0 | PIO_PD4 | PIO_PD5 | PIO_PD6 | PIO_PD7, 0); /* Hold PHY in reset to avoid the clock output switching */ pio_set_output(PIOD, PIO_PD31, 0, 0, 0); /* Disable pull-up on VBUS */ pio_pull_up(PIOE, PIO_PE2, 0); /* Disable PIO pull-up for PB10(USB_DDM), PB11(USB_DDP) */ pio_pull_up(PIOB, PIO_PB10 | PIO_PB11, 0); /* Enable the PMC clocks of push button for wakeup */ pmc_enable_periph_clk(ID_PIOE); pio_handler_set_priority(PIOE, PIOE_IRQn, IRQ_PRIOR_PIO); }
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 ); }
// [main] int main(void) { //! [main_step_sys_init] /* Initialize the SAM system */ sysclk_init(); board_init(); //! [main_step_sys_init] #ifndef BOARD_NO_PUSHBUTTON_2 #if (SAMV71 || SAMV70 || SAMS70 || SAME70) if (GPIO_PUSH_BUTTON_2 == PIO_PB12_IDX) { matrix_set_system_io(matrix_get_system_io() | CCFG_SYSIO_SYSIO12); } ioport_set_pin_dir(GPIO_PUSH_BUTTON_2, IOPORT_DIR_INPUT); ioport_set_pin_mode(GPIO_PUSH_BUTTON_2, GPIO_PUSH_BUTTON_2_FLAGS); ioport_set_pin_sense_mode(GPIO_PUSH_BUTTON_2, GPIO_PUSH_BUTTON_2_SENSE); #endif #endif //! [main_step_console_init] /* Initialize the console uart */ configure_console(); //! [main_step_console_init] /* Output example information */ puts(STRING_HEADER); /* Configure systick for 1 ms */ puts("Configure system tick to get 1ms tick period.\r"); //! [main_step_systick_init] if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) { puts("-F- Systick configuration error\r"); while (1); } //! [main_step_systick_init] #ifndef BOARD_NO_LED_1 puts("Configure TC.\r"); //! [main_step_tc_init] configure_tc(); //! [main_step_tc_init] #endif puts("Configure buttons with debouncing.\r"); //! [main_step_btn_init] configure_buttons(); //! [main_step_btn_init] printf("Press %s to Start/Stop the %s blinking.\r\n", PUSHBUTTON_1_NAME, LED_0_NAME); #ifndef BOARD_NO_PUSHBUTTON_2 printf("Press %s to Start/Stop the %s blinking.\r\n", PUSHBUTTON_2_NAME, LED_1_NAME); #endif //! [main_step_loop] while (1) { /* Wait for LED to be active */ while (!g_b_led0_active); /* Toggle LED state if active */ if (g_b_led0_active) { ioport_toggle_pin_level(LED0_GPIO); printf("1 "); } /* Wait for 500ms */ mdelay(500); } //! [main_step_loop] }
int main(void) { uint32_t i; uint32_t ul_error; volatile uint32_t *p_test_page_data; uint32_t p_buffer[BUFFER_SIZE]; /* Initialize the system. */ sysclk_init(); board_init(); /* Configure UART for debug message output. */ configure_console(); /* Initialize flash: 6 wait states for flash writing. */ flash_init(FLASH_ACCESS_MODE_128, FLASH_WAIT_STATE_NBR); /* Configure Push Button. */ configure_button(); /* Output example information. */ puts(STRING_HEADER); puts("-I- Unlocking the whole flash.\r\n"); /* Unlock the whole flash. */ ul_error = flash_unlock(IFLASH_ADDR, (IFLASH_ADDR + IFLASH_SIZE - 1), 0, 0); if (FLASH_RC_OK != ul_error) { puts("Unlock internal flash failed.\r\n"); return 0; } /* Perform tests on the test page. */ p_test_page_data = (volatile uint32_t *)TEST_PAGE_ADDRESS; /* Write page with walking bit pattern (0x00000001, 0x00000002, ...). */ puts("-I- Writing test page with walking bit pattern.\r\n"); for (i = 0; i < BUFFER_SIZE; i++) { p_buffer[i] = 1 << (i % MAX_SHIFTING_NUMBER); } #if (SAM4E || SAM4C || SAMV71) /** * The EWP command can only be used in 8 KBytes sector for SAM4E, * so an erase command is requried before write operation. */ ul_error = flash_erase_sector(TEST_PAGE_ADDRESS); if (ul_error != FLASH_RC_OK) { printf("-F- Flash erase error %u\n\r", ul_error); return 0; } ul_error = flash_write(TEST_PAGE_ADDRESS, p_buffer, IFLASH_PAGE_SIZE, 0); #else ul_error = flash_write(TEST_PAGE_ADDRESS, p_buffer, IFLASH_PAGE_SIZE, 1); #endif if (FLASH_RC_OK != ul_error) { puts("Write the test page of internal flash failed.\r\n"); return 0; } /* Check page contents. */ puts("-I- Checking page contents.\r\n"); for (i = 0; i < BUFFER_SIZE; i++) { printf("."); if (p_test_page_data[i] != (1u << (i % MAX_SHIFTING_NUMBER))) { puts("The content in the test page isn't written correctly"); return 0; } } puts(" OK! \r\n"); /* Configure Erase pin NOT in Erase mode. */ puts("-I- Configure Erase pin in PIO mode.\r\n"); matrix_set_system_io(PIN_PIO_MODE_MSK); /** * Ask the user to close the erase jumper and then open it(200ms minimum). */ printf("-I- Please close the erase jumper and then open it "); printf("at least 200ms later.\r\n"); printf("Then press button %s to go on!\r\n", BUTTON_STRING); /* Wait until Push Button is pressed. */ while (!g_button_event) { } /** * Disable the PIO line interrupts to eliminate the wrong check of * key press. */ pio_disable_interrupt(PUSH_BUTTON_PIO, PUSH_BUTTON_PIN_MSK); g_button_event = 0; /* Read the page again, it should be unchanged. */ puts("-I- Reading the page\r\n"); for (i = 0; i < BUFFER_SIZE; i++) { printf("."); if (p_test_page_data[i] != (1u << (i % MAX_SHIFTING_NUMBER))) { puts("-F- Reading Error! \r\n"); return 0; } } puts("\r\n"); puts("Read OK! Erase is out of function!\r\n"); /* Configure Erase pin as Erase function. */ puts("-I- Configure Erase pin as Erase function\r\n"); matrix_set_system_io(PIN_ERASE_MODE_MSK); /** * Ask the user to close the erase jumper and then open it(200ms minimum). */ printf("-I- Please close the erase jumper and then open it "); printf("at least 200ms later.\r\n"); /** * Remind the users that after closing the erase jumper and then opening * it, codes are gone. */ printf("-I- As the internal flash has been erased and the code can't "); printf("be executed any more, users can press the reset button on EK "); printf("and will see there will be no output message any more.\r\n"); while (1) { } }