SAM3S8/SD8 Software Package: libraries/libboard_sam3s-ek2/source/clock.c Source File

SAM3S8/SD8 Software Package 1.2

# clock.c

    00001 /* ----------------------------------------------------------------------------
    00002  *         ATMEL Microcontroller Software Support
    00003  * ----------------------------------------------------------------------------
    00004  * Copyright (c) 2009, 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  *        Headers
    00032  *----------------------------------------------------------------------------*/
    00033
    00034 #include "board.h"
    00035
    00036 /*----------------------------------------------------------------------------
    00037  *        Types
    00038  *----------------------------------------------------------------------------*/
    00039
    00040 /*
    00041  * \brief Describes a possible clock configuration (processor clock & master clock),
    00042  * including the necessary register values.
    00043  */
    00044 typedef struct _ClockConfiguration
    00045 {
    00046
    00047     /** Processor clock frequency (in MHz). */
    00048     uint16_t pck;
    00049     /** Master clock frequency (in MHz). */
    00050     uint16_t mck;
    00051     /** CKGR_PLL reqister value. */
    00052     uint32_t pllr;
    00053     /** PMC_MCKR register value. */
    00054     uint32_t mckr;
    00055 } ClockConfiguration ;
    00056
    00057 /*----------------------------------------------------------------------------
    00058  *        Local variables
    00059  *----------------------------------------------------------------------------*/
    00060
    00061 /* Clock configurations for the AT91SAM3S4-EK */
    00062 #define CKGR_MUL_SHIFT         16
    00063 #define CKGR_PLLCOUNT_SHIFT     8
    00064 #define CKGR_DIV_SHIFT          0
    00065
    00066 /* Clock configuration for the AT91SAM3S */
    00067 static const ClockConfiguration clockConfigurations[] = {
    00068
    00069     /* PCK = 24 MHz, MCK = 24 MHz
    00070      * PCK = 12000000 * (7+1) / 2 / 2 = 24 MHz
    00071      */
    00072     {24, 24, (CKGR_PLLAR_STUCKTO1 | (7 << CKGR_MUL_SHIFT) \
    00073         | (0x3f << CKGR_PLLCOUNT_SHIFT) \
    00074         | (2 << CKGR_DIV_SHIFT)),
    00075         ( PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)},
    00076     /* PCK = 48 MHz, MCK = 48 MHz
    00077      * PCK = 12000000 * (7+1) / 1 / 2 = 48 MHz
    00078      */
    00079     {48, 48, (CKGR_PLLAR_STUCKTO1 | (7 << CKGR_MUL_SHIFT) \
    00080         | (0x3f << CKGR_PLLCOUNT_SHIFT) \
    00081         | (1 << CKGR_DIV_SHIFT)),
    00082         ( PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)},
    00083     /* PCK = 64 MHz, MCK = 64 MHz
    00084      * PCK = 12000000 * (15+1) / 3 / 1 = 64 MHz
    00085      */
    00086     {64, 64, (CKGR_PLLAR_STUCKTO1 | (15 << CKGR_MUL_SHIFT) \
    00087         | (0x3f << CKGR_PLLCOUNT_SHIFT) \
    00088         | (3 << CKGR_DIV_SHIFT)),
    00089         ( PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)}
    00090 };
    00091
    00092 /* Number of available clock configurations */
    00093 #define NB_CLOCK_CONFIGURATION (sizeof(clockConfigurations)/sizeof(clockConfigurations[0]))
    00094
    00095 /* Current clock configuration */
    00096 uint32_t currentConfig = 0; /* 0 have to be the default configuration */
    00097
    00098 /*----------------------------------------------------------------------------
    00099  *        Exported functions
    00100  *----------------------------------------------------------------------------*/
    00101
    00102 /**
    00103  * \brief Sets the specified clock configuration.
    00104  *
    00105  * \param configuration  Index of the configuration to set.
    00106  */
    00107 void CLOCK_SetConfig(uint8_t configuration)
    00108 {
    00109     TRACE_DEBUG("Setting clock configuration #%d ... ", configuration);
    00110     currentConfig = configuration;
    00111
    00112     /* Switch to main oscillator in two operations */
    00113     PMC->PMC_MCKR = (PMC->PMC_MCKR & (uint32_t)~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
    00114     while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
    00115
    00116     /* Configure PLL */
    00117     PMC->CKGR_PLLAR = clockConfigurations[configuration].pllr;
    00118     while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0);
    00119
    00120     /* Configure master clock in two operations */
    00121     PMC->PMC_MCKR = (clockConfigurations[configuration].mckr & (uint32_t)~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
    00122     while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
    00123     PMC->PMC_MCKR = clockConfigurations[configuration].mckr;
    00124     while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
    00125
    00126     /* UART reconfiguration */
    00127     UART_Configure(115200, clockConfigurations[configuration].mck*1000000);
    00128     TRACE_DEBUG("done.\n\r");
    00129 }
    00130
    00131 /**
    00132  * \brief Display the user menu on the terminal.
    00133  */
    00134 void CLOCK_DisplayMenu(void)
    00135 {
    00136     uint32_t i;
    00137
    00138     printf("\n\rMenu Clock configuration:\n\r");
    00139     for (i = 0; i < NB_CLOCK_CONFIGURATION; i++) {
    00140
    00141         printf("  %u: Set PCK = %3u MHz, MCK = %3u MHz   %s\n\r",
    00142                (unsigned int)i,
    00143                (unsigned int)clockConfigurations[i].pck,
    00144                (unsigned int)clockConfigurations[i].mck,
    00145                (currentConfig==i)?"(curr)":"");
    00146     }
    00147 }
    00148
    00149 /**
    00150  * \brief Get the current MCK
    00151  */
    00152 uint16_t CLOCK_GetCurrMCK(void)
    00153 {
    00154     return clockConfigurations[currentConfig].mck;
    00155 }
    00156
    00157 /**
    00158  * \brief Get the current PCK
    00159  */
    00160 uint16_t CLOCK_GetCurrPCK(void)
    00161 {
    00162     return clockConfigurations[currentConfig].pck;
    00163 }
    00164
    00165 /**
    00166  * \brief Change clock configuration.
    00167  */
    00168 void CLOCK_UserChangeConfig(void)
    00169 {
    00170     uint8_t key = 0;
    00171
    00172     while (1)
    00173     {
    00174         CLOCK_DisplayMenu();
    00175         key = UART_GetChar();
    00176
    00177         if ((key >= '0') && (key <= ('0' + NB_CLOCK_CONFIGURATION - 1)))
    00178         {
    00179             CLOCK_SetConfig(key - '0');
    00180             break;
    00181         }
    00182     }
    00183 }
    00184

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines