SAMV71 Xplained Ultra Software Package 1.5

main.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
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 SAMV71 Xplained Ultra board or SAME70 Xplained 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 board.
00068  *     Please refer to the Getting Started with SAM V71/E70 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 rate
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         if (DBG_GetChar()!= 0)
00144             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         case PMC_MCKR_MDIV_EQ_PCK:
00225             masterClkDivision = 1;
00226             break;
00227         case PMC_MCKR_MDIV_PCK_DIV2:
00228             masterClkDivision = 2;
00229             break;
00230         case PMC_MCKR_MDIV_PCK_DIV4:
00231             masterClkDivision = 4;
00232             break;
00233         case PMC_MCKR_MDIV_PCK_DIV3:
00234             masterClkDivision = 3;
00235             break;
00236         default:
00237             masterClkDivision = 3;
00238         }
00239         masterClkPrescaler = 1 << ((PMC->PMC_MCKR & PMC_MCKR_PRES_Msk) >>
00240                     PMC_MCKR_PRES_Pos);
00241         masterClk = pllaClk / masterClkDivision / masterClkPrescaler;
00242     } else {
00243         onChipRC = (PMC->CKGR_MOR & CKGR_MOR_MOSCRCF_Msk);
00244         masterClk = ((onChipRC == CKGR_MOR_MOSCRCF_12_MHz)? 12 :
00245                 ((onChipRC == CKGR_MOR_MOSCRCF_8_MHz) ? 8 : 4)) * 1000000;
00246     }
00247 }
00248 
00249 /*----------------------------------------------------------------------------
00250  *         Global functions
00251  *----------------------------------------------------------------------------*/
00252 /**
00253  * \brief Application entry point for pmc_clock switch example.
00254  *
00255  * \return Unused (ANSI-C compatibility).
00256  */
00257 extern int main( void )
00258 {
00259     /* Disable watchdog */
00260     WDT_Disable(WDT);
00261 
00262     /* Enable I and D cache */
00263     SCB_EnableICache();
00264     SCB_EnableDCache();
00265 
00266     DBG_Configure(TEST_BAUDRATE, BOARD_MCK);
00267 
00268     /* Output example information */
00269     printf("-- PMC Clock Switching Example %s --\n\r", SOFTPACK_VERSION);
00270     printf("-- %s\n\r", BOARD_NAME);
00271     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME);
00272     /* Configure PCK as peripheral */
00273     PIO_Configure(&pinPCK, 1);
00274     TimeTick_Configure();
00275 
00276     _calcPmcParam();
00277     _ConfigureDbguAndPck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES(0), masterClk);
00278     printf("\n\r --- Current PMC clock from start-up configuration --- \n\r");
00279     _DumpPmcConfiguration();
00280     printf("-I- Please measure external 12MHz main clock on PCK1 ...\n\r");
00281     waitKey();
00282 
00283     printf("-I- Please measure external PLL/32 clock on PCK1 ...\n\r");
00284     _ConfigureDbguAndPck(PMC_PCK_CSS_PLLA_CLK, (31 << PMC_PCK_PRES_Pos), masterClk);
00285     waitKey();
00286 
00287     printf("\n\r --- Change PLL clock --- \n\r");
00288     PMC_ConfigureMckWithPlla(0xE, 0x1, PMC_MCKR_PRES_CLK_1);
00289     _calcPmcParam();
00290     _ConfigureDbguAndPck(PMC_PCK_CSS_PLLA_CLK, (31 << PMC_PCK_PRES_Pos), masterClk);
00291     _DumpPmcConfiguration();
00292     printf("-I- Please measure external PLL/32 clock on PCK1 ...\n\r");
00293     waitKey();
00294 
00295     printf("\n\r-I- Switch to On-chip 8MHz RC oscillator  \n\r");
00296     PMC_SetMckSelection(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1);
00297     PMC_EnableIntRC4_8_12MHz(CKGR_MOR_MOSCRCF_8_MHz);
00298     PMC_SetMckSelection(PMC_MCKR_CSS_MAIN_CLK, PMC_MCKR_PRES_CLK_1);
00299     _calcPmcParam();
00300     _ConfigureDbguAndPck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES(0), masterClk);
00301     printf("-I- Please measure on-chip 8MHz main clock on PCK1 ...\n\r");
00302     waitKey();
00303 
00304     printf("\n\r-I- Switch to On-chip 12MHz RC oscillator  \n\r");
00305     PMC_SetMckSelection(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1);
00306     PMC_EnableIntRC4_8_12MHz(CKGR_MOR_MOSCRCF_12_MHz);
00307     PMC_SetMckSelection(PMC_MCKR_CSS_MAIN_CLK, PMC_MCKR_PRES_CLK_1);
00308     _calcPmcParam();
00309     _ConfigureDbguAndPck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES(0), masterClk);
00310     printf("-I- Please measure on-chip 12MHz main clock on PCK1 ...\n\r");
00311     waitKey();
00312     printf("\n\r-I- Switch to slow clock  \n\r");
00313     printf("-I- Please measure slow clock on PCK1 ...\n\r");
00314     printf("-I- The end \n\r");
00315     PMC_SetMckSelection(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1);
00316     _ConfigureDbguAndPck(PMC_PCK_CSS_SLOW_CLK, PMC_PCK_PRES(0), masterClk);
00317     return 0;
00318 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines