SAMV71 Xplained Ultra Software Package 1.4

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2012, 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  * \page pmc_clock_switching PMC Clock Switching Example
00032  *
00033  * \section Purpose
00034  * This example shows how to switch system clock from one to another (PLLA, 
00035  * SLCK, MAINCK) or change to fast RC.
00036  *
00037  * \section Requirements
00038  *
00039  * This package can be used with SAM V71 Xplained Ultra board.
00040  *
00041  * \section Description
00042  *
00043  * Upon startup, the program configure PIOs for DBGU, PCK and buttons. The baud
00044  * rate of DBGU is configured as 2400 bps. The application prints the current 
00045  * configuration (except 32Khz slow clock ) and waits for button pressed or 
00046  * input from PC terminal application to switch the system clock to next 
00047  * configuration. PCK1 Outputs can be selected from the clocks provided by the 
00048  * clock (PLLA, SLCK, MAINCK) and driven on the pin PCK
00049  * (Peripheral B).
00050  * After the clock switches, the PCK1 output signal can be measured by scope
00051  * compared with the clock configuration.
00052  *
00053  * <ul>
00054  * <li> The Clock Generator integrates a 32,768 Hz low-power oscillator.
00055  * The user can select the crystal oscillator to be the slow clock source,  
00056  * as it provides a more accurate frequency. The command is made by function 
00057  * PmcSlowClockSwitchXtalOsc().</li>
00058  * <li> The Master Clock is selected from one of the clocks provided by the  
00059  * Clock Generator. 
00060  * Selecting the Slow Clock provides a Slow Clock signal to the whole device. 
00061  * Selecting the Main Clock saves power consumption of the PLLs.
00062  * Function _PmcMasterClockSelection() describes the detail how to switch master
00063  * clock between difference source.</li>
00064  * </ul>
00065  * \section Usage
00066  *
00067  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00068  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00069  * -# On the computer, open and configure a terminal application
00070  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00071  *   - 2400 baud rates
00072  *   - 8 bits of data
00073  *   - No parity
00074  *   - 1 stop bit
00075  *   - No flow control
00076  * -# Start the application.
00077  * -# In the terminal window, the following text should appear:
00078  *    \code
00079  *     -- PMC clock Switching Example xxx --
00080  *     -- SAMxxxxx-xx
00081  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00082  *    \endcode
00083  * -# Press one of the buttons listed in the menu to perform the corresponding 
00084  *    action or type "'" to do the same thing if no button is available.
00085  *
00086  * \section References
00087  * - pmc_clock_switching/main.c
00088  * - pio.h
00089  * - pio_it.h
00090  */
00091 
00092 /**
00093  * \file
00094  *
00095  * This file contains all the specific code for the pmc clock switching example.
00096  */
00097 
00098 /*----------------------------------------------------------------------------
00099  *        Headers
00100  *----------------------------------------------------------------------------*/
00101 
00102 #include "board.h"
00103 
00104 #include <stdint.h>
00105 #include <stdio.h>
00106 #include <stdarg.h>
00107 
00108 /*----------------------------------------------------------------------------
00109  *        Local definitions
00110  *----------------------------------------------------------------------------*/
00111 
00112 /** Baud rate used for hints */
00113 #define TEST_BAUDRATE   2400
00114 
00115 /*----------------------------------------------------------------------------
00116  *        Local variables
00117  *----------------------------------------------------------------------------*/
00118 
00119 /** Pin PCK1 (PIO_PD31B_PCK1 Peripheral C) */
00120 const Pin pinPCK = PIN_PCK0;
00121 
00122 /** No push button, monitor DBGU RX */
00123 const char* strWaitHint =
00124 "-I- Press ` to switch next clock configuration...\n\r";
00125 
00126 /** Mutual semaphore. */
00127 static volatile uint8_t inTesting = 0;
00128 
00129 /** Clock backup values */
00130 static uint32_t masterClk;
00131 static uint32_t pllaClk;
00132 static uint32_t masterClkDivision;
00133 static uint32_t pllMultiplier;
00134 static uint32_t masterClkPrescaler;
00135 
00136 /*----------------------------------------------------------------------------
00137  *        Local functions
00138  *----------------------------------------------------------------------------*/
00139 static void waitKey(void)
00140 {
00141     printf( "-I- Press any key to switch next clock configuration...\n\r");
00142     while ( 1 )
00143     {
00144         if(DBG_GetChar()!= 0) break;
00145     }
00146 }
00147 
00148 static void _DumpPmcConfiguration(void)
00149 {
00150     uint8_t ucChar[5];
00151     printf( "\n\r========================= PMC ==========================\n\r" );
00152     printf( "Main clock\n\r");
00153     ucChar[0] = ((PMC->CKGR_MOR & CKGR_MOR_MOSCSEL ) == CKGR_MOR_MOSCSEL) ? 
00154             ' ' : 'X';
00155     ucChar[1] = ((PMC->CKGR_MOR & CKGR_MOR_MOSCSEL ) == CKGR_MOR_MOSCSEL) ? 
00156             'X' : ' ';
00157     printf("  On-Chip 12MHz RC oscillator[%c] 12MHz crystal oscillator[%c]\n\r", 
00158             ucChar[0], ucChar[1]);
00159   
00160     printf("  PLLA Multiplier=%u PLLA clock=%uMHz\n\r", 
00161             (unsigned int)pllMultiplier, (unsigned int)(pllaClk/1000000));
00162     printf("Master clock\n\r");
00163     ucChar[0] = ((PMC->PMC_MCKR & PMC_MCKR_CSS_Msk ) == PMC_MCKR_CSS_SLOW_CLK) ? 
00164             'X' : ' ';
00165     ucChar[1] = ((PMC->PMC_MCKR & PMC_MCKR_CSS_Msk ) == PMC_MCKR_CSS_MAIN_CLK) ? 
00166             'X' : ' ';
00167     ucChar[2] = ((PMC->PMC_MCKR & PMC_MCKR_CSS_Msk ) == PMC_MCKR_CSS_PLLA_CLK) ? 
00168             'X' : ' ';
00169     ucChar[3] = ((PMC->PMC_MCKR & PMC_MCKR_CSS_Msk ) == PMC_MCKR_CSS_UPLL_CLK) ? 
00170             'X' : ' ';
00171     printf("  SLOW_CLK [%c], MAIN_CLK[%c], PLLA_CLK[%c] UPLL_CLK[%c] \n\r",
00172             ucChar[0],ucChar[1],ucChar[2],ucChar[3]);
00173     printf("  masterClkPrescaler=%u, Master clock=%uMHz \n\r", 
00174             (unsigned int)masterClkPrescaler, (unsigned int)masterClk/1000000);
00175     printf("Programmable clock\n\r");
00176     ucChar[0] = ((PMC->PMC_PCK[1] & PMC_PCK_CSS_Msk ) == PMC_PCK_CSS_SLOW_CLK) ? 
00177             'X' : ' ';
00178     ucChar[1] = ((PMC->PMC_PCK[1] & PMC_PCK_CSS_Msk ) == PMC_PCK_CSS_MAIN_CLK) ? 
00179             'X' : ' ';
00180     ucChar[2] = ((PMC->PMC_PCK[1] & PMC_PCK_CSS_Msk ) == PMC_PCK_CSS_PLLA_CLK) ? 
00181             'X' : ' ';
00182     ucChar[3] = ((PMC->PMC_PCK[1] & PMC_PCK_CSS_Msk ) == PMC_PCK_CSS_UPLL_CLK) ? 
00183             'X' : ' ';
00184     ucChar[4] = ((PMC->PMC_PCK[1] & PMC_PCK_CSS_Msk ) == PMC_PCK_CSS_MCK) ? 
00185             'X' : ' ';
00186     printf("  SLOW_CLK [%c], MAIN_CLK[%c], PLLA_CLK[%c] UPLL_CLK[%c] MCK_CLK[%c]\n\r",
00187             ucChar[0],ucChar[1],ucChar[2],ucChar[3],ucChar[4]);
00188     printf( "==============================================================\n\r" );
00189 }
00190 
00191 /**
00192  * \brief Configure DBUG with given master clock, and Configure PCK with given
00193  *  divider source of master clock and prescaler.
00194  *
00195  * \param css  The master clock divider source.
00196  * \param pres Master Clock prescaler.
00197  * \param clk frequency of the master clock (in Hz).
00198  */
00199 static void _ConfigureDbguAndPck( uint32_t css, uint32_t pres, uint32_t clk )
00200 {
00201     /* Configure DBGU baud rate as 1200 bps (except slow clock)*/
00202     if ( clk > 32768 ) {
00203         DBG_Configure( TEST_BAUDRATE, clk ) ;
00204     }
00205     /* Disable programmable clock 1 output */
00206     REG_PMC_SCDR = PMC_SCER_PCK0;
00207     /* Enable the DAC master clock */
00208     PMC->PMC_PCK[0] = css | pres;
00209     /* Enable programmable clock 1 output */
00210     REG_PMC_SCER = PMC_SCER_PCK0;
00211     /* Wait for the PCKRDY1 bit to be set in the PMC_SR register*/
00212     while ((REG_PMC_SR & PMC_SR_PCKRDY0) == 0 );
00213     Wait(50);
00214 }
00215 
00216 
00217 static void _calcPmcParam(void)
00218 {
00219     uint32_t onChipRC;
00220     if (PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) {
00221         pllMultiplier = (PMC->CKGR_PLLAR & CKGR_PLLAR_MULA_Msk) >> CKGR_PLLAR_MULA_Pos;
00222         pllaClk = BOARD_MAINOSC * (pllMultiplier + 1);
00223         switch (PMC->PMC_MCKR & PMC_MCKR_MDIV_Msk) 
00224         {
00225             case PMC_MCKR_MDIV_EQ_PCK: masterClkDivision = 1; break;
00226             case PMC_MCKR_MDIV_PCK_DIV2: masterClkDivision = 2; break;
00227             case PMC_MCKR_MDIV_PCK_DIV4: masterClkDivision = 4; break;
00228             case PMC_MCKR_MDIV_PCK_DIV3: masterClkDivision = 3; break;
00229             default: masterClkDivision = 3;
00230         }
00231         masterClkPrescaler = 1 << ((PMC->PMC_MCKR & PMC_MCKR_PRES_Msk) >> 
00232                     PMC_MCKR_PRES_Pos);
00233         masterClk = pllaClk / masterClkDivision / masterClkPrescaler;
00234     }
00235     else {
00236         onChipRC = (PMC->CKGR_MOR & CKGR_MOR_MOSCRCF_Msk);
00237         masterClk = ((onChipRC == CKGR_MOR_MOSCRCF_12_MHz)? 12 :
00238                 ((onChipRC == CKGR_MOR_MOSCRCF_8_MHz) ? 8 : 4)) * 1000000;
00239     }
00240 }
00241 
00242 /*----------------------------------------------------------------------------
00243  *         Global functions
00244  *----------------------------------------------------------------------------*/
00245 /**
00246  * \brief Application entry point for pmc_clock switch example.
00247  *
00248  * \return Unused (ANSI-C compatibility).
00249  */
00250 extern int main( void )
00251 {
00252     /* Disable watchdog */
00253     WDT_Disable( WDT );
00254     
00255     /* Enable I and D cache */
00256     SCB_EnableICache();
00257     SCB_EnableDCache();
00258 
00259     DBG_Configure( TEST_BAUDRATE, BOARD_MCK ) ;
00260 
00261     /* Output example information */
00262     printf("-- PMC Clock Switching Example %s --\n\r", SOFTPACK_VERSION);
00263     printf("-- %s\n\r", BOARD_NAME);
00264     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00265     /* Configure PCK as peripheral */
00266     PIO_Configure(&pinPCK, 1);
00267     TimeTick_Configure();
00268 
00269     _calcPmcParam();
00270     _ConfigureDbguAndPck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES(0), masterClk);
00271     printf("\n\r --- Current PMC clock from start-up configuration --- \n\r");
00272     _DumpPmcConfiguration();
00273     printf("-I- Please measure external 12MHz main clock on PCK1 ...\n\r");
00274     waitKey();
00275 
00276     printf("-I- Please measure external PLL/32 clock on PCK1 ...\n\r");
00277     _ConfigureDbguAndPck(PMC_PCK_CSS_PLLA_CLK, (31 << PMC_PCK_PRES_Pos), masterClk);
00278     waitKey();
00279 
00280     printf("\n\r --- Change PLL clock --- \n\r");
00281     PMC_ConfigureMckWithPlla(0xE, 0x1, PMC_MCKR_PRES_CLK_1);
00282     _calcPmcParam();
00283     _ConfigureDbguAndPck(PMC_PCK_CSS_PLLA_CLK, (31 << PMC_PCK_PRES_Pos), masterClk);
00284     _DumpPmcConfiguration();
00285     printf("-I- Please measure external PLL/32 clock on PCK1 ...\n\r");
00286     waitKey();
00287 
00288     printf("\n\r-I- Switch to On-chip 8MHz RC oscillator  \n\r");
00289     PMC_SetMckSelection(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1);
00290     PMC_EnableIntRC4_8_12MHz(CKGR_MOR_MOSCRCF_8_MHz);
00291     PMC_SetMckSelection(PMC_MCKR_CSS_MAIN_CLK, PMC_MCKR_PRES_CLK_1);
00292     _calcPmcParam();
00293     _ConfigureDbguAndPck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES(0), masterClk);
00294     printf("-I- Please measure on-chip 8MHz main clock on PCK1 ...\n\r");
00295     waitKey();
00296 
00297     printf("\n\r-I- Switch to On-chip 12MHz RC oscillator  \n\r");
00298     PMC_SetMckSelection(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1);
00299     PMC_EnableIntRC4_8_12MHz(CKGR_MOR_MOSCRCF_12_MHz);
00300     PMC_SetMckSelection(PMC_MCKR_CSS_MAIN_CLK, PMC_MCKR_PRES_CLK_1);
00301     _calcPmcParam();
00302     _ConfigureDbguAndPck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES(0), masterClk);
00303     printf("-I- Please measure on-chip 12MHz main clock on PCK1 ...\n\r");
00304     waitKey();
00305     printf("\n\r-I- Switch to slow clock  \n\r");
00306     printf("-I- Please measure slow clock on PCK1 ...\n\r");
00307     printf("-I- The end \n\r");
00308     PMC_SetMckSelection(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1);
00309     _ConfigureDbguAndPck(PMC_PCK_CSS_SLOW_CLK, PMC_PCK_PRES(0), masterClk);
00310     return 0;
00311 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines