SAMV71 Xplained Ultra Software Package 1.3

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2011, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 
00030 
00031 /**
00032  * \page low_power Low-power Example
00033  *
00034  * \section Purpose
00035  * This example allows to measure the consumption of the core in different modes
00036  * (sleep mode, wait mode, backup mode).
00037  *
00038  * \section Requirements
00039  *
00040  * This package can be used with SAM V71 Xplained Ultra board, and should run on 
00041  * flash.
00042  *
00043  * \section Description
00044  *
00045  * At start-up, the program configures all the PIOs as input to avoid parasite
00046  * consumption. Then a menu is displayed. It allows user to enter in a mode to 
00047  * measure consumption.
00048  *
00049  * \section Usage
00050  *
00051  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00052  * Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00053  * -# On the computer, open and configure a terminal application
00054  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00055  *   - 115200 baud rate
00056  *   - 8 bits of data
00057  *   - No parity
00058  *   - 1 stop bit
00059  *   - No flow control
00060  * -# Start the application.
00061  * -# In the terminal window, the following text should appear:
00062  *    \code
00063  *     -- Low_power Example xxx --
00064  *     -- xxxxxx-xx
00065  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00066  *    \endcode
00067  * -# Press one of the keys listed in the menu to perform the corresponding action.
00068  *
00069  * \section References
00070  * - low_power/main.c
00071  */
00072 
00073 /**
00074  * \file
00075  *
00076  * This file contains all the specific code for the low-power example.
00077  */
00078 
00079 /*----------------------------------------------------------------------------
00080  *        Headers
00081  *----------------------------------------------------------------------------*/
00082 
00083 #include "board.h"
00084 
00085 #include <stdint.h>
00086 #include <stdio.h>
00087 
00088 /*----------------------------------------------------------------------------
00089  *        Local definitions
00090  *----------------------------------------------------------------------------*/
00091 
00092 /* (SCR) Sleep deep bit */
00093 #define SCR_SLEEPDEEP   (0x1 <<  2)
00094 
00095 #define CONSOLE_EDBG 
00096 
00097 /*----------------------------------------------------------------------------
00098  *        Local variables
00099  *----------------------------------------------------------------------------*/
00100 /* Wakeup PIN Index definition */
00101 const uint32_t gWakeUpPinId = (1 << 6);
00102 
00103 /*----------------------------------------------------------------------------
00104  *        Local functions
00105  *----------------------------------------------------------------------------*/
00106 
00107 #if defined CONSOLE_EDBG
00108 /**
00109  * \brief USART ISR for wakeup from sleep mode
00110  */
00111 void USART1_Handler(void)
00112 {
00113     USART_GetChar(USART1);
00114 }
00115 #else
00116 void UART0_Handler(void)
00117 {
00118     UART_GetChar(UART0);
00119 }
00120 #endif
00121 
00122 /**
00123  * \brief Initialize the chip.
00124  */
00125 static void _InitChip( void )
00126 {
00127     /* All PIO in input mode */
00128     PIOA -> PIO_ODR = 0xFFFFFFFF;
00129     PIOB -> PIO_ODR = 0xFFFFFFFF;
00130     PIOC -> PIO_ODR = 0xFFFFFFFF;
00131     PIOD -> PIO_ODR = 0xFFFFFFFF;
00132     PIOE -> PIO_ODR = 0xFFFFFFFF;
00133 
00134     PIOA ->PIO_PPDDR = 0xFFFFFFFF;     // pulldown disable
00135     PIOA ->PIO_PUDR = 0xFFFFFFFF;      // pullup   disable
00136     PIOA ->PIO_PPDER =  0;             // pulldown Enable
00137     PIOA ->PIO_PUER = 0xFFFFFFFF;      // pullup   Enable
00138 
00139     PIOB ->PIO_PPDDR = 0xFFFFFFFF;     // pulldown disable
00140     PIOB ->PIO_PUDR = 0xFFFFFFFF;      // pullup   disable
00141     PIOB ->PIO_PPDER = 0x0;            // pulldown Enable
00142     PIOB ->PIO_PUER = 0xFFFFFFFF;      // pullup   Enable
00143 
00144     PIOC ->PIO_PPDDR = 0xFFFFFFFF;     // pulldown disable
00145     PIOC ->PIO_PUDR = 0xFFFFFFFF;      // pullup   disable
00146     PIOC ->PIO_PPDER =  0;             // pulldown Enable
00147     PIOC ->PIO_PUER = 0xFFFFFFFF;      // pullup   Enable
00148 
00149     PIOD ->PIO_PPDDR = 0xFFFFFFFF;     // pulldown disable
00150     PIOD ->PIO_PUDR = 0xFFFFFFFF;      // pullup   disable
00151     PIOD ->PIO_PPDER =  0;             // pulldown Enable
00152     PIOD ->PIO_PUER = 0xFFFFFFFF;      // pullup   Enable
00153 
00154     PIOE ->PIO_PPDDR = 0xFFFFFFFF;     // pulldown disable
00155     PIOE ->PIO_PUDR = 0xFFFFFFFF;      // pullup   disable
00156     PIOE ->PIO_PPDER =  0;             // pulldown Enable
00157     PIOE ->PIO_PUER = 0xFFFFFFFF;      // pullup   Enable
00158 
00159     SUPC->SUPC_MR |= SUPC_MR_KEY_PASSWD | ((SUPC -> SUPC_MR) &( ~(1u <<17))) ;
00160 
00161     /* Disable UTMI PLL clock */
00162     PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN;
00163 
00164     /* Disable PCK */
00165     PMC->PMC_SCDR = 0xFFFFFFFF;
00166 
00167     /* Disable all the peripheral clocks */
00168     PMC_DisableAllPeripherals();
00169 }
00170 
00171 /**
00172  * \brief Sets the wake-up inputs for fast start-up mode registers.
00173  *
00174  * \param inputs  Wake up inputs to enable.
00175  */
00176 static void _SetFastStartupInput( uint32_t dwInputs )
00177 {
00178     PMC->PMC_FSMR &= (uint32_t)~0xFFF00000;
00179     PMC->PMC_FSMR |= dwInputs ;
00180 }
00181 
00182 /**
00183  * \brief Enter Wait Mode.
00184  * Enter condition: WFE + (SLEEPDEEP bit = 0) + (LPM bit = 1)
00185  */
00186 static void enterWaitMode( void )
00187 {
00188     printf( "-I- Enter in Wait Mode\n\r" );
00189     printf( "-I- Press WAKE UP button to wakeup\n\r" ) ;
00190     /* Configure 4Mhz fast RC oscillator */
00191     /* First switch MCK to Slow clock  */
00192     PMC_SetMckSelection(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES(0));
00193     /* Then, enable Fast RC */
00194     PMC_EnableIntRC4_8_12MHz(CKGR_MOR_MOSCRCF_4_MHz);
00195     /* Then, Switch MCK to main clock  */
00196     PMC_SetMckSelection(PMC_MCKR_CSS_MAIN_CLK, PMC_PCK_PRES(0));
00197     /* Disable unused clock to save power (optional) */
00198     PMC_SetPllaClock(0, 0);
00199 
00200     /* Set wakeup input for fast start-up */
00201     _SetFastStartupInput( gWakeUpPinId ) ;
00202     /* Configure the FLPM field in the PMC Fast Start-up Mode Register(PMC_FSMR).*/
00203     PMC->PMC_FSMR |= PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN  | PMC_FSMR_LPM;
00204     /* Set Flash Wait State at 0*/
00205     EFC->EEFC_FMR = EEFC_FMR_FWS(0);
00206     /*  No SLEEPDEEP */
00207     SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP ;
00208     /* Set the WAITMODE bit in PMC Clock Generator Main Oscillator 
00209         Register (CKGR_MOR)*/
00210     PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD  | CKGR_MOR_WAITMODE;
00211     /* Wait for MCKRDY = 1 in the PMC Status Register (PMC_SR) */
00212     while( !(PMC->PMC_SR & PMC_SR_MCKRDY ) );
00213     __WFE() ;
00214 
00215     /* Restore previous clock and DBG */
00216     PMC_SetMckSelection(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1);
00217     LowLevelInit();
00218     DBG_Configure(115200, BOARD_MCK);
00219 
00220     printf( "-I- Exit Wait Mode\n\r" ) ;
00221 }
00222 
00223 /**
00224  * \brief Test Sleep Mode
00225  */
00226 static void enterSleepMode( void )
00227 {
00228     printf( "-I- Enter in Sleep Mode\n\r" ) ;
00229     printf( "-I- Press any key to wakeup\n\r" ) ;
00230     /* The purpose of sleep mode is to optimize power consumption of the 
00231         device versus response time. 
00232        In this mode, only the core clock is stopped. The peripheral clocks can 
00233        be enabled. 
00234        The current consumption in this mode is application-dependent.*/
00235     PMC->PMC_FSMR &= (uint32_t)~PMC_FSMR_LPM ;
00236     SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP ;
00237 
00238     /* Processor wake-up is triggered by an interrupt if the WFI instruction 
00239         of the Cortex-M processor is used.*/
00240 #if defined CONSOLE_EDBG
00241     NVIC_ClearPendingIRQ(USART1_IRQn);
00242     NVIC_EnableIRQ(USART1_IRQn);
00243     USART_EnableIt(USART1,UART_IER_RXRDY);
00244 #else
00245     NVIC_ClearPendingIRQ(UART0_IRQn);
00246     NVIC_EnableIRQ(UART0_IRQn);
00247     UART_EnableIt(UART0,UART_IER_RXRDY);
00248 #endif
00249 
00250     /* This mode is entered using the instruction Wait for Interrupt (WFI).*/
00251     __WFI() ;
00252     printf("-I- Processor wake-up is triggered by an interrupt \n\r");
00253     printf("-I- Exit Sleep Mode\n\r" ) ;
00254 }
00255 
00256 /**
00257  * \brief Test Backup Mode.
00258  */
00259 static void enterBackupMode( void )
00260 {
00261     printf( "-I- Enter in Backup Mode\n\r" ) ;
00262     printf( "-I- Press WAKE UP button to wakeup\n\r" ) ;
00263     /* Enable the PIO for wake-up */
00264     SUPC->SUPC_WUIR = (gWakeUpPinId << 16) | gWakeUpPinId ;
00265     PMC->PMC_FSMR   = PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN | gWakeUpPinId;
00266     /* Set the SLEEPDEEP bit of Cortex-M processor. */
00267     SCB->SCR |= SCR_SLEEPDEEP ;
00268     /* Set the VROFF bit of SUPC_CR. */
00269     SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG;
00270     SUPC->SUPC_WUMR = (1<<12)  ;   
00271     /* Wake Up Input 2 and 4 (L_CLICK and R_CLICK) Enable + (0) high to low 
00272         level Transition. Exit from Backup mode occurs as a result of one of 
00273         the following enabled wake-up events:
00274         WKUPEN0-13 pins (level transition, configurable denouncing)
00275         Supply Monitor alarm
00276         RTC alarm
00277         RTT alarm */
00278     printf("-I- Processor wake-up is triggered by WAKEUP button \n\r");
00279     printf("-I- Exit backup Mode\n\r" ) ;
00280     while(1);
00281 }
00282 
00283 /**
00284  * \brief Display test Core menu.
00285  */
00286 static void _DisplayMenuCore( void )
00287 {
00288     printf( "\n\r" ) ;
00289     printf( "===========================================================\n\r" ) ;
00290     printf( "Menu: press a key to select low power mode.\n\r" ) ;
00291     printf( "===========================================================\n\r" ) ;
00292     printf( "Configure:\n\r" ) ;
00293     printf( "  S : Sleep mode\n\r" ) ;
00294     printf( "  W : Wait mode\n\r" );
00295     printf( "  B : Backup mode\n\r" );
00296 }
00297 
00298 
00299 /**
00300  * \brief Test Core consumption
00301  */
00302 static void lowPowerMode( void )
00303 {
00304     uint8_t ucKey;
00305 
00306     while ( 1 ) {
00307         _DisplayMenuCore() ;
00308         ucKey = DBG_GetChar();
00309         switch ( ucKey )
00310         {
00311         case 's' :
00312         case 'S' :
00313             enterSleepMode() ;
00314             break ;
00315 
00316         case 'w' :
00317         case 'W' :
00318             enterWaitMode();
00319             break ;
00320 
00321         case 'b' :
00322         case 'B' :
00323             enterBackupMode();
00324             break ;
00325 
00326         default :
00327             printf( "This menu does not exist !\n\r" ) ;
00328             break ;
00329         } /* switch */
00330     }
00331 }
00332 
00333 /**
00334  * \brief Application entry point for low-power example.
00335  *
00336  * \return Unused (ANSI-C compatibility).
00337  */
00338 int main(void)
00339 {
00340     /* Disable watchdog */
00341     WDT_Disable( WDT ) ;
00342 
00343     /* Enable I and D cache */
00344     SCB_EnableICache();
00345     SCB_EnableDCache();
00346 
00347     /* initialize the chip for the power consumption test */
00348     _InitChip() ;
00349 
00350     /* Output example information */
00351     printf( "\n\r\n\r\n\r" ) ;
00352     printf( "-- Low-power Example %s --\n\r", SOFTPACK_VERSION ) ;
00353     printf( "-- %s\n\r", BOARD_NAME ) ;
00354     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00355 
00356     /* Test core consumption */
00357     lowPowerMode();
00358     return 0 ;
00359 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines