401 lines
13 KiB
C
401 lines
13 KiB
C
/*
|
|
* @brief LPC18xx/43xx clock driver
|
|
*
|
|
* @note
|
|
* Copyright(C) NXP Semiconductors, 2012
|
|
* All rights reserved.
|
|
*
|
|
* @par
|
|
* Software that is described herein is for illustrative purposes only
|
|
* which provides customers with programming information regarding the
|
|
* LPC products. This software is supplied "AS IS" without any warranties of
|
|
* any kind, and NXP Semiconductors and its licenser disclaim any and
|
|
* all warranties, express or implied, including all implied warranties of
|
|
* merchantability, fitness for a particular purpose and non-infringement of
|
|
* intellectual property rights. NXP Semiconductors assumes no responsibility
|
|
* or liability for the use of the software, conveys no license or rights under any
|
|
* patent, copyright, mask work right, or any other intellectual property rights in
|
|
* or to any products. NXP Semiconductors reserves the right to make changes
|
|
* in the software without notification. NXP Semiconductors also makes no
|
|
* representation or warranty that such application will be suitable for the
|
|
* specified use without further testing or modification.
|
|
*
|
|
* @par
|
|
* Permission to use, copy, modify, and distribute this software and its
|
|
* documentation is hereby granted, under NXP Semiconductors' and its
|
|
* licensor's relevant copyrights in the software, without fee, provided that it
|
|
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
|
* copyright, permission, and disclaimer notice must appear in all copies of
|
|
* this code.
|
|
*/
|
|
|
|
#ifndef __CLOCK_18XX_43XX_H_
|
|
#define __CLOCK_18XX_43XX_H_
|
|
|
|
#include "cguccu_18xx_43xx.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** @defgroup CLOCK_18XX_43XX CHIP: LPC18xx/43xx Clock Driver
|
|
* @ingroup CHIP_18XX_43XX_Drivers
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup CLOCK_18XX_43XX_OPTIONS CHIP: LPC18xx/43xx Clock Driver driver options
|
|
* @ingroup CLOCK_18XX_43XX CHIP_18XX_43XX_DRIVER_OPTIONS
|
|
* The clock driver has options that configure it's operation at build-time.<br>
|
|
*
|
|
* <b>MAX_CLOCK_FREQ</b><br>
|
|
* This macro defines the maximum frequency supported by the Chip [204MHz for LPC43xx
|
|
* 180MHz for LPC18xx]. API Chip_SetupXtalClocking() and Chip_SetupIrcClocking() will
|
|
* use this macro to set the CPU Core frequency to the maximum supported.<br>
|
|
* To set a Core frequency other than the maximum frequency Chip_SetupCoreClock() API
|
|
* must be used. <b>Using this macro to set the Core freqency is not recommended.</b>
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/* Internal oscillator frequency */
|
|
#define CGU_IRC_FREQ (12000000)
|
|
|
|
#ifndef MAX_CLOCK_FREQ
|
|
#if defined(CHIP_LPC43XX)
|
|
#define MAX_CLOCK_FREQ (204000000)
|
|
#else
|
|
#define MAX_CLOCK_FREQ (180000000)
|
|
#endif
|
|
#endif
|
|
|
|
#define PLL_MIN_CCO_FREQ 156000000 /**< Min CCO frequency of main PLL */
|
|
#define PLL_MAX_CCO_FREQ 320000000 /**< Max CCO frequency of main PLL */
|
|
|
|
/**
|
|
* @brief PLL Parameter strucutre
|
|
*/
|
|
typedef struct {
|
|
int ctrl; /**< Control register value */
|
|
CHIP_CGU_CLKIN_T srcin; /**< Input clock Source see #CHIP_CGU_CLKIN_T */
|
|
int nsel; /**< Pre-Div value */
|
|
int psel; /**< Post-Div Value */
|
|
int msel; /**< M-Div value */
|
|
uint32_t fin; /**< Input frequency */
|
|
uint32_t fout; /**< Output frequency */
|
|
uint32_t fcco; /**< CCO frequency */
|
|
} PLL_PARAM_T;
|
|
|
|
/**
|
|
* @brief Enables the crystal oscillator
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_EnableCrystal(void);
|
|
|
|
/**
|
|
* @brief Disables the crystal oscillator
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_DisableCrystal(void);
|
|
|
|
/**
|
|
* @brief Configures the main PLL
|
|
* @param Input : Which clock input to use as the PLL input
|
|
* @param MinHz : Minimum allowable PLL output frequency
|
|
* @param DesiredHz : Desired PLL output frequency
|
|
* @param MaxHz : Maximum allowable PLL output frequency
|
|
* @return Frequency of the PLL in Hz
|
|
* Returns the configured PLL frequency or zero if the PLL can not be configured between MinHz
|
|
* and MaxHz. This will not wait for PLL lock. Call Chip_Clock_MainPLLLocked() to determine if
|
|
* the PLL is locked.
|
|
*/
|
|
uint32_t Chip_Clock_SetupMainPLLHz(CHIP_CGU_CLKIN_T Input, uint32_t MinHz, uint32_t DesiredHz, uint32_t MaxHz);
|
|
|
|
/**
|
|
* @brief Directly set the PLL multipler
|
|
* @param Input : Which clock input to use as the PLL input
|
|
* @param mult : How many times to multiply the input clock
|
|
* @return Frequency of the PLL in Hz
|
|
*/
|
|
uint32_t Chip_Clock_SetupMainPLLMult(CHIP_CGU_CLKIN_T Input, uint32_t mult);
|
|
|
|
/**
|
|
* @brief Returns the frequency of the main PLL
|
|
* @return Frequency of the PLL in Hz
|
|
* Returns zero if the main PLL is not running.
|
|
*/
|
|
uint32_t Chip_Clock_GetMainPLLHz(void);
|
|
|
|
/**
|
|
* @brief Disables the main PLL
|
|
* @return none
|
|
* Make sure the main PLL is not needed to clock the part before disabling it.
|
|
* Saves power if the main PLL is not needed.
|
|
*/
|
|
__STATIC_INLINE void Chip_Clock_DisableMainPLL(void)
|
|
{
|
|
/* power down main PLL */
|
|
LPC_CGU->PLL1_CTRL |= 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Enbles the main PLL
|
|
* @return none
|
|
* Make sure the main PLL is enabled.
|
|
*/
|
|
__STATIC_INLINE void Chip_Clock_EnableMainPLL(void)
|
|
{
|
|
/* power up main PLL */
|
|
LPC_CGU->PLL1_CTRL &= ~1;
|
|
}
|
|
/**
|
|
* @brief Sets-up the main PLL
|
|
* @param ppll : Pointer to pll param structure #PLL_PARAM_T
|
|
* @return none
|
|
* Make sure the main PLL is enabled.
|
|
*/
|
|
__STATIC_INLINE void Chip_Clock_SetupMainPLL(const PLL_PARAM_T *ppll)
|
|
{
|
|
/* power up main PLL */
|
|
LPC_CGU->PLL1_CTRL = ppll->ctrl | ((uint32_t) ppll->srcin << 24) | (ppll->msel << 16) | (ppll->nsel << 12) | (ppll->psel << 8) | ( 1 << 11);
|
|
}
|
|
|
|
/**
|
|
* @brief Sets up a CGU clock divider and it's input clock
|
|
* @param Divider : CHIP_CGU_IDIV_T value indicating which divider to configure
|
|
* @param Input : CHIP_CGU_CLKIN_T value indicating which clock source to use or CLOCKINPUT_PD to power down divider
|
|
* @param Divisor : value to divide Input clock by
|
|
* @return Nothing
|
|
* Maximum divider on A = 4, B/C/D = 16, E = 256.
|
|
* See the user manual for allowable combinations for input clock.
|
|
*/
|
|
void Chip_Clock_SetDivider(CHIP_CGU_IDIV_T Divider, CHIP_CGU_CLKIN_T Input, uint32_t Divisor);
|
|
|
|
/**
|
|
* @brief Gets a CGU clock divider source
|
|
* @param Divider : CHIP_CGU_IDIV_T value indicating which divider to get the source of
|
|
* @return CHIP_CGU_CLKIN_T indicating which clock source is set or CLOCKINPUT_PD
|
|
*/
|
|
CHIP_CGU_CLKIN_T Chip_Clock_GetDividerSource(CHIP_CGU_IDIV_T Divider);
|
|
|
|
/**
|
|
* @brief Gets a CGU clock divider divisor
|
|
* @param Divider : CHIP_CGU_IDIV_T value indicating which divider to get the source of
|
|
* @return the divider value for the divider
|
|
*/
|
|
uint32_t Chip_Clock_GetDividerDivisor(CHIP_CGU_IDIV_T Divider);
|
|
|
|
/**
|
|
* @brief Returns the frequency of the specified input clock source
|
|
* @param input : Which clock input to return the frequency of
|
|
* @return Frequency of input source in Hz
|
|
* This function returns an ideal frequency and not the actual frequency. Returns
|
|
* zero if the clock source is disabled.
|
|
*/
|
|
uint32_t Chip_Clock_GetClockInputHz(CHIP_CGU_CLKIN_T input);
|
|
|
|
/**
|
|
* @brief Returns the frequency of the specified base clock source
|
|
* @param clock : which base clock to return the frequency of.
|
|
* @return Frequency of base source in Hz
|
|
* This function returns an ideal frequency and not the actual frequency. Returns
|
|
* zero if the clock source is disabled.
|
|
*/
|
|
uint32_t Chip_Clock_GetBaseClocktHz(CHIP_CGU_BASE_CLK_T clock);
|
|
|
|
/**
|
|
* @brief Sets a CGU Base Clock clock source
|
|
* @param BaseClock : CHIP_CGU_BASE_CLK_T value indicating which base clock to set
|
|
* @param Input : CHIP_CGU_CLKIN_T value indicating which clock source to use or CLOCKINPUT_PD to power down base clock
|
|
* @param autoblocken : Enables autoblocking during frequency change if true
|
|
* @param powerdn : The clock base is setup, but powered down if true
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_SetBaseClock(CHIP_CGU_BASE_CLK_T BaseClock, CHIP_CGU_CLKIN_T Input, bool autoblocken, bool powerdn);
|
|
|
|
/**
|
|
* @brief Get CGU Base Clock clock source information
|
|
* @param BaseClock : CHIP_CGU_BASE_CLK_T value indicating which base clock to get
|
|
* @param Input : Pointer to CHIP_CGU_CLKIN_T value of the base clock
|
|
* @param autoblocken : Pointer to autoblocking value of the base clock
|
|
* @param powerdn : Pointer to power down flag
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_GetBaseClockOpts(CHIP_CGU_BASE_CLK_T BaseClock, CHIP_CGU_CLKIN_T *Input, bool *autoblocken,
|
|
bool *powerdn);
|
|
|
|
/**
|
|
* @brief Gets a CGU Base Clock clock source
|
|
* @param BaseClock : CHIP_CGU_BASE_CLK_T value indicating which base clock to get inpuot clock for
|
|
* @return CHIP_CGU_CLKIN_T indicating which clock source is set or CLOCKINPUT_PD
|
|
*/
|
|
CHIP_CGU_CLKIN_T Chip_Clock_GetBaseClock(CHIP_CGU_BASE_CLK_T BaseClock);
|
|
|
|
/**
|
|
* @brief Enables a base clock source
|
|
* @param BaseClock : CHIP_CGU_BASE_CLK_T value indicating which base clock to enable
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_EnableBaseClock(CHIP_CGU_BASE_CLK_T BaseClock);
|
|
|
|
/**
|
|
* @brief Disables a base clock source
|
|
* @param BaseClock : CHIP_CGU_BASE_CLK_T value indicating which base clock to disable
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_DisableBaseClock(CHIP_CGU_BASE_CLK_T BaseClock);
|
|
|
|
/**
|
|
* @brief Returns base clock enable state
|
|
* @param BaseClock : CHIP_CGU_BASE_CLK_T value indicating which base clock to check
|
|
* @return true if the base clock is enabled, false if disabled
|
|
*/
|
|
bool Chip_Clock_IsBaseClockEnabled(CHIP_CGU_BASE_CLK_T BaseClock);
|
|
|
|
/**
|
|
* @brief Enables a peripheral clock and sets clock states
|
|
* @param clk : CHIP_CCU_CLK_T value indicating which clock to enable
|
|
* @param autoen : true to enable autoblocking on a clock rate change, false to disable
|
|
* @param wakeupen : true to enable wakeup mechanism, false to disable
|
|
* @param div : Divider for the clock, must be 1 for most clocks, 2 supported on others
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_EnableOpts(CHIP_CCU_CLK_T clk, bool autoen, bool wakeupen, int div);
|
|
|
|
/**
|
|
* @brief Enables a peripheral clock
|
|
* @param clk : CHIP_CCU_CLK_T value indicating which clock to enable
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_Enable(CHIP_CCU_CLK_T clk);
|
|
|
|
/**
|
|
* @brief Enables RTCclock
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_RTCEnable(void);
|
|
|
|
/**
|
|
* @brief Disables a peripheral clock
|
|
* @param clk : CHIP_CCU_CLK_T value indicating which clock to disable
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_Disable(CHIP_CCU_CLK_T clk);
|
|
|
|
/**
|
|
* @brief Returns a peripheral clock rate
|
|
* @param clk : CHIP_CCU_CLK_T value indicating which clock to get rate for
|
|
* @return 0 if the clock is disabled, or the rate of the clock
|
|
*/
|
|
uint32_t Chip_Clock_GetRate(CHIP_CCU_CLK_T clk);
|
|
|
|
/**
|
|
* @brief Returns EMC clock rate
|
|
* @return 0 if the clock is disabled, or the rate of the clock
|
|
*/
|
|
uint32_t Chip_Clock_GetEMCRate(void);
|
|
|
|
/**
|
|
* @brief Start the power down sequence by disabling the branch output
|
|
* clocks with wake up mechanism (Only the clocks which
|
|
* wake up mechanism bit enabled will be disabled)
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_StartPowerDown(void);
|
|
|
|
/**
|
|
* @brief Clear the power down mode bit & proceed normal operation of branch output
|
|
* clocks (Only the clocks which wake up mechanism bit enabled will be
|
|
* enabled after the wake up event)
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_ClearPowerDown(void);
|
|
|
|
/**
|
|
* Structure for setting up the USB or audio PLL
|
|
*/
|
|
typedef struct {
|
|
uint32_t ctrl; /* Default control word for PLL */
|
|
uint32_t mdiv; /* Default M-divider value for PLL */
|
|
uint32_t ndiv; /* Default NP-divider value for PLL */
|
|
uint32_t fract; /* Default fractional value for audio PLL only */
|
|
uint32_t freq; /* Output frequency of the pll */
|
|
} CGU_USBAUDIO_PLL_SETUP_T;
|
|
|
|
/**
|
|
* @brief Sets up the audio or USB PLL
|
|
* @param Input : Input clock
|
|
* @param pllnum : PLL identifier
|
|
* @param pPLLSetup : Pointer to PLL setup structure
|
|
* @return Nothing
|
|
* Sets up the PLL with the passed structure values.
|
|
*/
|
|
void Chip_Clock_SetupPLL(CHIP_CGU_CLKIN_T Input, CHIP_CGU_USB_AUDIO_PLL_T pllnum,
|
|
const CGU_USBAUDIO_PLL_SETUP_T *pPLLSetup);
|
|
|
|
/**
|
|
* @brief Enables the audio or USB PLL
|
|
* @param pllnum : PLL identifier
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_EnablePLL(CHIP_CGU_USB_AUDIO_PLL_T pllnum);
|
|
|
|
/**
|
|
* @brief Disables the audio or USB PLL
|
|
* @param pllnum : PLL identifier
|
|
* @return Nothing
|
|
*/
|
|
void Chip_Clock_DisablePLL(CHIP_CGU_USB_AUDIO_PLL_T pllnum);
|
|
|
|
#define CGU_PLL_LOCKED (1 << 0) /* PLL locked status */
|
|
#define CGU_PLL_FR (1 << 1) /* PLL free running indicator status */
|
|
|
|
/**
|
|
* @brief Returns the PLL status
|
|
* @param pllnum : PLL identifier
|
|
* @return An OR'ed value of CGU_PLL_LOCKED or CGU_PLL_FR
|
|
*/
|
|
uint32_t Chip_Clock_GetPLLStatus(CHIP_CGU_USB_AUDIO_PLL_T pllnum);
|
|
|
|
/**
|
|
* @brief Calculate main PLL Pre, Post and M div values
|
|
* @param freq : Expected output frequency
|
|
* @param ppll : Pointer to #PLL_PARAM_T structure
|
|
* @return 0 on success; < 0 on failure
|
|
* @note
|
|
* ppll->srcin[IN] should have the appropriate Input clock source selected<br>
|
|
* ppll->fout[OUT] will have the actual output frequency<br>
|
|
* ppll->fcco[OUT] will have the frequency of CCO
|
|
*/
|
|
int Chip_Clock_CalcMainPLLValue(uint32_t freq, PLL_PARAM_T *ppll);
|
|
|
|
|
|
/**
|
|
* @brief Wait for Main PLL to be locked
|
|
* @return 1 - PLL is LOCKED; 0 - PLL is not locked
|
|
* @note The main PLL should be locked prior to using it as a clock input for a base clock.
|
|
*/
|
|
__STATIC_INLINE int Chip_Clock_MainPLLLocked(void)
|
|
{
|
|
/* Return true if locked */
|
|
return (LPC_CGU->PLL1_STAT & 1) != 0;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __CLOCK_18XX_43XX_H_ */
|
|
|
|
|
|
|
|
|
|
|
|
|