esp32-s2_dfu/hw/mcu/nxp/lpc_chip_43xx/inc/clock_18xx_43xx.h

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_ */