summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/pmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/arm/atsam/libraries/libchip/source/pmc.c')
-rw-r--r--c/src/lib/libbsp/arm/atsam/libraries/libchip/source/pmc.c597
1 files changed, 0 insertions, 597 deletions
diff --git a/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/pmc.c b/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/pmc.c
deleted file mode 100644
index 08df61ef8a..0000000000
--- a/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/pmc.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/* ---------------------------------------------------------------------------- */
-/* Atmel Microcontroller Software Support */
-/* SAM Software Package License */
-/* ---------------------------------------------------------------------------- */
-/* Copyright (c) 2015, Atmel Corporation */
-/* */
-/* All rights reserved. */
-/* */
-/* Redistribution and use in source and binary forms, with or without */
-/* modification, are permitted provided that the following condition is met: */
-/* */
-/* - Redistributions of source code must retain the above copyright notice, */
-/* this list of conditions and the disclaimer below. */
-/* */
-/* Atmel's name may not be used to endorse or promote products derived from */
-/* this software without specific prior written permission. */
-/* */
-/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
-/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
-/* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
-/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
-/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
-/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
-/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
-/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
-/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-/* ---------------------------------------------------------------------------- */
-
-/** \addtogroup pmc_module Working with PMC
- * The PMC driver provides the Interface to configure the Power Management
- * Controller (PMC).
- *
- * \section Usage
- * <ul>
- * <li> Enables/Disable the clock of a peripheral by using
- * PMC_EnablePeripheral() and PMC_DisablePeripheral().</li>
- * <li> Enables/Disable the clock of all peripherals by using
- * PMC_EnableAllPeripherals() and PMC_DisableAllPeripherals().</li>
- * <li> Get status of a peripheral using PMC_IsPeriphEnabled().</li>
- * <li> Manage the clocks using PMC_EnableExtOsc(), PMC_DisableExtOsc(),
- * PMC_SelectExtOsc(), PMC_SelectExtBypassOsc(), PMC_EnableIntRC4_8_12MHz(),
- * PMC_DisableIntRC4_8_12MHz(), PMC_SetPllaClock(), PMC_SetMckSelection(),
- * PMC_DisableAllClocks(), PMC_ConfigureMckWithPlla(),
- * PMC_EnableXT32KFME() and PMC_ConfigurePCK2().</li>
- *
- * </ul>
- * For more accurate information, please look at the PMC section of the Datasheet.
- *
- * Related files :\n
- * \ref pmc.c\n
- * \ref pmc.h.\n
-*/
-
-/**
-* \file
-*
-* \section Purpose
-*
-* Interface for configuring and using Power Management Controller (PMC)
-* peripherals.
-*
-*/
-
-/**
- * \file
- *
- * Implementation of Power Management Controller (PMC).
- *
- */
-
-/*----------------------------------------------------------------------------
- * Headers
- *----------------------------------------------------------------------------*/
-
-#include "chip.h"
-
-#include <assert.h>
-
-/*----------------------------------------------------------------------------
- * Local definitions
- *----------------------------------------------------------------------------*/
-
-#define MASK_STATUS0 0xFFFFFFFC
-#define MASK_STATUS1 0xFFFFFFFF
-
-/*----------------------------------------------------------------------------
- * Local functions
- *----------------------------------------------------------------------------*/
-/**
- * \brief Switch MCK to PLLA clock.
- */
-static void _PMC_SwitchMck2PllaClock(void)
-
-{
- /* Select PLLA as input clock for MCK */
- PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_PLLA_CLK;
-
- /* Wait until the master clock is established */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-}
-
-/**
- * \brief Switch MCK to main clock.
- */
-static void _PMC_SwitchMck2MainClock(void)
-{
- /* Select Main Oscillator as input clock for MCK */
- PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
-
- /* Wait until the master clock is established */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-
- PMC->PMC_MCKR = PMC_MCKR_CSS_MAIN_CLK;
-
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-}
-
-/**
- * \brief Switch MCK to slow clock.
- */
-static void _PMC_SwitchMck2SlowClock(void)
-{
- /* Select Slow Clock as input clock for MCK */
- PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_SLOW_CLK;
-
- /* Wait until the master clock is established */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-}
-
-/**
- * \brief Set prescaler for MCK.
- *
- * \param prescaler Master Clock prescaler
- */
-static void _PMC_SetMckPrescaler(uint32_t prescaler)
-{
- /* Change MCK Prescaler divider in PMC_MCKR register */
- PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_PRES_Msk) | prescaler;
-
- /* Wait until the master clock is established */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-}
-/*----------------------------------------------------------------------------
- * Exported functions
- *----------------------------------------------------------------------------*/
-
-/**
- * \brief Enables the clock of a peripheral. The peripheral ID is used
- * to identify which peripheral is targeted.
- *
- * \note The ID must NOT be shifted (i.e. 1 << ID_xxx).
- *
- * \param id Peripheral ID (ID_xxx).
- */
-void PMC_EnablePeripheral(uint32_t dwId)
-{
- assert(dwId < 63);
-
- if (dwId < 32) {
- if ((PMC->PMC_PCSR0 & ((uint32_t)1 << dwId)) == ((uint32_t)1 << dwId)) {
- TRACE_DEBUG("PMC_EnablePeripheral: clock of peripheral" \
- " %u is already enabled\n\r", (unsigned int)dwId);
- } else
- PMC->PMC_PCER0 = 1 << dwId;
- } else {
- dwId -= 32;
-
- if ((PMC->PMC_PCSR1 & ((uint32_t)1 << dwId)) == ((uint32_t)1 << dwId)) {
- TRACE_DEBUG("PMC_EnablePeripheral: clock of peripheral" \
- " %u is already enabled\n\r", (unsigned int)(dwId + 32));
- } else
- PMC->PMC_PCER1 = 1 << dwId;
- }
-}
-
-/**
- * \brief Disables the clock of a peripheral. The peripheral ID is used
- * to identify which peripheral is targeted.
- *
- * \note The ID must NOT be shifted (i.e. 1 << ID_xxx).
- *
- * \param id Peripheral ID (ID_xxx).
- */
-void PMC_DisablePeripheral(uint32_t dwId)
-{
- assert(dwId < 63);
-
- if (dwId < 32) {
- if ((PMC->PMC_PCSR0 & ((uint32_t)1 << dwId)) != ((uint32_t)1 << dwId)) {
- TRACE_DEBUG("PMC_DisablePeripheral: clock of peripheral" \
- " %u is not enabled\n\r", (unsigned int)dwId);
- } else
- PMC->PMC_PCDR0 = 1 << dwId;
- } else {
- dwId -= 32;
-
- if ((PMC->PMC_PCSR1 & ((uint32_t)1 << dwId)) != ((uint32_t)1 << dwId)) {
- TRACE_DEBUG("PMC_DisablePeripheral: clock of peripheral"
- " %u is not enabled\n\r", (unsigned int)(dwId + 32));
- } else
- PMC->PMC_PCDR1 = 1 << dwId;
- }
-}
-
-/**
- * \brief Enable all the periph clock via PMC.
- */
-void PMC_EnableAllPeripherals(void)
-{
- PMC->PMC_PCER0 = MASK_STATUS0;
-
- while ((PMC->PMC_PCSR0 & MASK_STATUS0) != MASK_STATUS0);
-
- PMC->PMC_PCER1 = MASK_STATUS1;
-
- while ((PMC->PMC_PCSR1 & MASK_STATUS1) != MASK_STATUS1);
-
- TRACE_DEBUG("Enable all periph clocks\n\r");
-}
-
-/**
- * \brief Disable all the periph clock via PMC.
- */
-void PMC_DisableAllPeripherals(void)
-{
- PMC->PMC_PCDR0 = MASK_STATUS0;
-
- while ((PMC->PMC_PCSR0 & MASK_STATUS0) != 0);
-
- PMC->PMC_PCDR1 = MASK_STATUS1;
-
- while ((PMC->PMC_PCSR1 & MASK_STATUS1) != 0);
-
- TRACE_DEBUG("Disable all periph clocks\n\r");
-}
-
-/**
- * \brief Get Periph Status for the given peripheral ID.
- *
- * \param id Peripheral ID (ID_xxx).
- */
-uint32_t PMC_IsPeriphEnabled(uint32_t dwId)
-{
- assert(dwId < ID_PERIPH_COUNT);
-
- if (dwId < 32)
- return (PMC->PMC_PCSR0 & (1 << dwId));
- else
- return (PMC->PMC_PCSR1 & (1 << (dwId - 32)));
-}
-
-
-/**
- * \brief Enable external oscillator as main clock input.
- */
-void PMC_EnableExtOsc(void)
-{
- uint32_t read_MOR;
-
- /* Before switching MAIN OSC on external crystal : enable it and don't disable
- * at the same time RC OSC in case of if MAIN OSC is still using RC OSC
- */
-
- read_MOR = PMC->CKGR_MOR;
- read_MOR &= ~CKGR_MOR_MOSCRCF_Msk;
- /* reset MOSCRCF field in MOR register before select RC 12MHz */
- read_MOR |= (CKGR_MOR_KEY_PASSWD
- | CKGR_MOR_MOSCRCF_12_MHz
- | CKGR_MOR_MOSCXTEN
- | CKGR_MOR_MOSCRCEN
- | CKGR_MOR_MOSCXTST(DEFAUTL_MAIN_OSC_COUNT));
- /* enable external crystal - enable RC OSC */
-
- PMC->CKGR_MOR = read_MOR;
-
- while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
-
- /* wait end of RC oscillator stabilization */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-
- read_MOR |= CKGR_MOR_MOSCSEL;
- /* select external crystal */
-
- PMC->CKGR_MOR = read_MOR;
-
- while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
-
- /* Wait end of Main Oscillator Selection */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-}
-
-/**
- * \brief Disable external 12MHz oscillator.
- */
-void PMC_DisableExtOsc(void)
-{
- uint32_t read_MOR;
-
- read_MOR = PMC->CKGR_MOR;
- read_MOR &= ~CKGR_MOR_MOSCXTEN; /* disable main xtal osc */
- PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | read_MOR;
-
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-}
-
-/**
- * \brief Select external OSC.
- */
-void PMC_SelectExtOsc(void)
-{
- /* switch from internal RC 12 MHz to external OSC 12 MHz */
- /* wait Main XTAL Oscillator stabilisation*/
- if ((PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) == CKGR_MOR_MOSCSEL) {
- PMC_DisableIntRC4_8_12MHz();
- return;
- }
-
- /* enable external OSC 12 MHz */
- PMC->CKGR_MOR |= CKGR_MOR_MOSCXTEN | CKGR_MOR_KEY_PASSWD;
-
- /* wait Main CLK Ready */
- while (!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY));
-
- /* switch MAIN clock to external OSC 12 MHz*/
- PMC->CKGR_MOR |= CKGR_MOR_MOSCSEL | CKGR_MOR_KEY_PASSWD;
-
- /* wait MAIN clock status change for external OSC 12 MHz selection*/
- while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
-
- /* in case where MCK is running on MAIN CLK */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-
- PMC_DisableIntRC4_8_12MHz();
-}
-
-
-/**
- * \brief Select external OSC.
- */
-void PMC_SelectExtBypassOsc(void)
-{
- volatile uint32_t timeout;
-
- if ((PMC->CKGR_MOR & CKGR_MOR_MOSCXTBY) != CKGR_MOR_MOSCXTBY) {
- PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD |
- CKGR_MOR_MOSCRCEN |
- CKGR_MOR_MOSCXTST(0xFF) |
- CKGR_MOR_MOSCXTBY;
- PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL;
-
- /* wait MAIN clock status change for external OSC 12 MHz selection*/
- while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
-
- // Check if an external clock is provided
- for (timeout = 0; timeout < 0xffff; timeout++);
-
- while (!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY));
- }
-}
-
-/**
- * \brief Enable internal 4/8/12MHz fast RC as main clock input.
- *
- * \param freqSelect fast RC frequency (FAST_RC_4MHZ, FAST_RC_8MHZ,
- * FAST_RC_12MHZ).
- */
-void PMC_EnableIntRC4_8_12MHz(uint32_t freqSelect)
-{
- /* Enable Fast RC oscillator but DO NOT switch to RC now */
- PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN);
-
- /* Wait the Fast RC to stabilize */
- while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
-
- /* Change Fast RC oscillator frequency */
- PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) |
- CKGR_MOR_KEY_PASSWD | freqSelect;
-
- /* Wait the Fast RC to stabilize */
- while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
-
- /* Switch to Fast RC */
- PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) |
- CKGR_MOR_KEY_PASSWD;
-
- /* wait MAIN clock status change for Fast RC oscillator */
- while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
-
- /* in case where MCK is running on MAIN CLK */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-
-}
-
-/**
- * \brief Disable internal 4/8/12MHz fast RC.
- */
-void PMC_DisableIntRC4_8_12MHz(void)
-{
- uint32_t read_MOR;
-
- read_MOR = PMC->CKGR_MOR;
-
- read_MOR &= ~CKGR_MOR_MOSCRCF_Msk; /* reset MOSCRCF field in MOR register */
- read_MOR &= ~CKGR_MOR_MOSCRCEN; /* disable fast RC */
- PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | read_MOR;
-
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-}
-
-/**
- * \brief Configure PLLA clock by giving MUL and DIV.
- * Disable PLLA when 'mul' set to 0.
- *
- * \param mul PLL multiplier factor.
- * \param div PLL divider factor.
- */
-void PMC_SetPllaClock(uint32_t mul, uint32_t div)
-{
- if (mul != 0) {
- /* Init PLL speed */
- PMC->CKGR_PLLAR = CKGR_PLLAR_ONE
- | CKGR_PLLAR_PLLACOUNT(DEFAUTL_PLLA_COUNT)
- | CKGR_PLLAR_MULA(mul - 1)
- | CKGR_PLLAR_DIVA(div);
-
- /* Wait for PLL stabilization */
- while (!(PMC->PMC_SR & PMC_SR_LOCKA));
- } else {
- PMC->CKGR_PLLAR = CKGR_PLLAR_ONE; /* disable PLL A */
- }
-}
-
-/**
- * \brief Selection of Master Clock.
- *
- * \param clockSource Master Clock source.
- * \param prescaler Master Clock prescaler.
- *
- * \note
- * The PMC_MCKR register must not be programmed in a single write
- * operation (see. Product Data Sheet).
- */
-void PMC_SetMckSelection(uint32_t clockSource, uint32_t prescaler)
-{
- switch (clockSource) {
- case PMC_MCKR_CSS_SLOW_CLK :
- _PMC_SwitchMck2SlowClock();
- _PMC_SetMckPrescaler(prescaler);
- break;
-
- case PMC_MCKR_CSS_MAIN_CLK :
- _PMC_SwitchMck2MainClock();
- _PMC_SetMckPrescaler(prescaler);
- break;
-
- case PMC_MCKR_CSS_PLLA_CLK :
- _PMC_SetMckPrescaler(prescaler);
- _PMC_SwitchMck2PllaClock();
- break;
- }
-}
-
-/**
- * \brief Disable all clocks.
- */
-void PMC_DisableAllClocks(void)
-{
- uint32_t read_reg;
-
- PMC->PMC_SCDR = PMC_SCDR_PCK0 | PMC_SCDR_PCK1 | PMC_SCDR_PCK2 | PMC_SCDR_PCK3 |
- PMC_SCDR_PCK4 | PMC_SCDR_PCK5 | PMC_SCDR_PCK6; /* disable PCK */
-
- _PMC_SwitchMck2MainClock();
-
- PMC->CKGR_PLLAR = PMC->CKGR_PLLAR & ~CKGR_PLLAR_MULA_Msk; /* disable PLL A */
-
- _PMC_SwitchMck2SlowClock();
-
- read_reg = PMC->CKGR_MOR;
- read_reg = (read_reg & ~CKGR_MOR_MOSCRCEN) | CKGR_MOR_KEY_PASSWD;
- /* disable RC OSC */
-
- PMC->CKGR_MOR = read_reg;
-
- PMC_DisableAllPeripherals(); /* disable all peripheral clocks */
-}
-
-/**
- * \brief Configure PLLA as clock input for MCK.
- *
- * \param mul PLL multiplier factor (not shifted, don't minus 1).
- * \param div PLL divider factor (not shifted).
- * \param prescaler Master Clock prescaler (shifted as in register).
- */
-void PMC_ConfigureMckWithPlla(uint32_t mul, uint32_t div, uint32_t prescaler)
-{
- /* First, select Main OSC as input clock for MCK */
- _PMC_SwitchMck2MainClock();
-
- /* Then, Set PLLA clock */
- PMC_SetPllaClock(mul, div);
-
- /* Wait until the master clock is established for the case we already
- turn on the PLL */
- while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
-
- /* Finally, select PllA as input clock for MCK */
- PMC_SetMckSelection(PMC_MCKR_CSS_PLLA_CLK, prescaler);
-}
-
-
-/**
- * \brief Configure PLLA as clock input for MCK.
- *
- * \param mul PLL multiplier factor (not shifted, don't minus 1).
- * \param div PLL divider factor (not shifted).
- * \param prescaler Master Clock prescaler (shifted as in register).
- */
-void PMC_EnableXT32KFME(void)
-{
-
- uint32_t read_MOR;
-
- /* Before switching MAIN OSC on external crystal : enable it and don't
- disable at the same time RC OSC in case of if MAIN OSC is still using
- RC OSC */
-
- read_MOR = PMC->CKGR_MOR;
-
- read_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_XT32KFME);
- /* enable external crystal - enable RC OSC */
-
- PMC->CKGR_MOR = read_MOR;
-
-}
-
-/**
- * \brief Configure PLLA as clock input for MCK.
- *
- * \param mul PLL multiplier factor (not shifted, don't minus 1).
- * \param div PLL divider factor (not shifted).
- * \param prescaler Master Clock prescaler (shifted as in register).
- */
-void PMC_ConfigurePCK0(uint32_t MasterClk, uint32_t prescaler)
-{
- PMC->PMC_SCDR = PMC_SCDR_PCK0; /* disable PCK */
-
- while ((PMC->PMC_SCSR)& PMC_SCSR_PCK0);
-
- PMC->PMC_PCK[0] = MasterClk | prescaler;
- PMC->PMC_SCER = PMC_SCER_PCK0;
-
- while (!((PMC->PMC_SR) & PMC_SR_PCKRDY0));
-
-}
-
-
-/**
- * \brief Configure PLLA as clock input for MCK.
- *
- * \param mul PLL multiplier factor (not shifted, don't minus 1).
- * \param div PLL divider factor (not shifted).
- * \param prescaler Master Clock prescaler (shifted as in register).
- */
-void PMC_ConfigurePCK1(uint32_t MasterClk, uint32_t prescaler)
-{
- PMC->PMC_SCDR = PMC_SCDR_PCK1; /* disable PCK */
-
- while ((PMC->PMC_SCSR)& PMC_SCSR_PCK1);
-
- PMC->PMC_PCK[1] = MasterClk | prescaler;
- PMC->PMC_SCER = PMC_SCER_PCK1;
-
- while (!((PMC->PMC_SR) & PMC_SR_PCKRDY1));
-
-}
-
-/**
- * \brief Configure PLLA as clock input for MCK.
- *
- * \param mul PLL multiplier factor (not shifted, don't minus 1).
- * \param div PLL divider factor (not shifted).
- * \param prescaler Master Clock prescaler (shifted as in register).
- */
-void PMC_ConfigurePCK2(uint32_t MasterClk, uint32_t prescaler)
-{
- PMC->PMC_SCDR = PMC_SCDR_PCK2; /* disable PCK */
-
- while ((PMC->PMC_SCSR)& PMC_SCSR_PCK2);
-
- PMC->PMC_PCK[2] = MasterClk | prescaler;
- PMC->PMC_SCER = PMC_SCER_PCK2;
-
- while (!((PMC->PMC_SR) & PMC_SR_PCKRDY2));
-
-}