rt-thread-official/bsp/lpc5410x/Libraries/lpc_chip/chip_5410x/clock_5410x.h

474 lines
14 KiB
C

/*
* @brief LPC5410X clock driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* 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_5410X_H_
#define __CLOCK_5410X_H_
#include "pll_5410x.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CLOCK_5410X CHIP: LPC5410X Clock Driver
* @ingroup CHIP_5410X_DRIVERS
* @{
*/
/* Internal oscillator frequency */
#define SYSCON_IRC_FREQ (12000000)
#define SYSCON_WDTOSC_FREQ (500000)
#define SYSCON_RTC_FREQ (32768)
/**
* @brief Returns the internal oscillator (IRC) clock rate
* @return internal oscillator (IRC) clock rate
*/
STATIC INLINE uint32_t Chip_Clock_GetIntOscRate(void)
{
return SYSCON_IRC_FREQ;
}
/**
* @brief Returns the external clock input rate
* @return External clock input rate
*/
STATIC INLINE uint32_t Chip_Clock_GetExtClockInRate(void)
{
return ExtClockIn;
}
/**
* @brief Returns the RTC clock rate
* @return RTC oscillator clock rate in Hz
*/
STATIC INLINE uint32_t Chip_Clock_GetRTCOscRate(void)
{
return SYSCON_RTC_FREQ;
}
/**
* @brief Return estimated watchdog oscillator rate
* @return Estimated watchdog oscillator rate
* @note This rate is accurate to plus or minus 40%.
*/
STATIC INLINE uint32_t Chip_Clock_GetWDTOSCRate(void)
{
return SYSCON_WDTOSC_FREQ;
}
/**
* Clock source selections for only the main A system clock. The main A system
* clock is used as an input into the main B system clock selector. Main clock A
* only needs to be setup if the main clock A input is used in the main clock
* system selector.
*/
typedef enum {
SYSCON_MAIN_A_CLKSRC_IRC = 0, /*!< Internal oscillator */
SYSCON_MAIN_A_CLKSRCA_CLKIN, /*!< Crystal (main) oscillator in */
SYSCON_MAIN_A_CLKSRCA_WDTOSC, /*!< Watchdog oscillator rate */
} CHIP_SYSCON_MAIN_A_CLKSRC_T;
/**
* @brief Set main A system clock source
* @param src : Clock source for main A
* @return Nothing
* @note This function only needs to be setup if main clock A will be
* selected in the Chip_Clock_GetMain_B_ClockRate() function.
*/
STATIC INLINE void Chip_Clock_SetMain_A_ClockSource(CHIP_SYSCON_MAIN_A_CLKSRC_T src)
{
LPC_SYSCON->MAINCLKSELA = (uint32_t) src;
}
/**
* @brief Returns the main A clock source
* @return Returns which clock is used for the main A
*/
STATIC INLINE CHIP_SYSCON_MAIN_A_CLKSRC_T Chip_Clock_GetMain_A_ClockSource(void)
{
return (CHIP_SYSCON_MAIN_A_CLKSRC_T) (LPC_SYSCON->MAINCLKSELA);
}
/**
* @brief Return main A clock rate
* @return main A clock rate in Hz
*/
uint32_t Chip_Clock_GetMain_A_ClockRate(void);
/**
* Clock sources for only main B system clock
*/
typedef enum {
SYSCON_MAIN_B_CLKSRC_MAINCLKSELA = 0, /*!< main clock A */
SYSCON_MAIN_B_CLKSRC_SYSPLLIN, /*!< System PLL input */
SYSCON_MAIN_B_CLKSRC_SYSPLLOUT, /*!< System PLL output */
SYSCON_MAIN_B_CLKSRC_RTC, /*!< RTC oscillator 32KHz output */
} CHIP_SYSCON_MAIN_B_CLKSRC_T;
/**
* @brief Set main B system clock source
* @param src : Clock source for main B
* @return Nothing
*/
STATIC INLINE void Chip_Clock_SetMain_B_ClockSource(CHIP_SYSCON_MAIN_B_CLKSRC_T src)
{
LPC_SYSCON->MAINCLKSELB = (uint32_t) src;
}
/**
* @brief Returns the main B clock source
* @return Returns which clock is used for the main B
*/
STATIC INLINE CHIP_SYSCON_MAIN_B_CLKSRC_T Chip_Clock_GetMain_B_ClockSource(void)
{
return (CHIP_SYSCON_MAIN_B_CLKSRC_T) (LPC_SYSCON->MAINCLKSELB);
}
/**
* @brief Return main B clock rate
* @return main B clock rate
*/
uint32_t Chip_Clock_GetMain_B_ClockRate(void);
/**
* Clock sources for CLKOUT
*/
typedef enum {
SYSCON_CLKOUTSRC_MAINCLK = 0, /*!< Main system clock for CLKOUT */
SYSCON_CLKOUTSRC_CLKIN, /*!< CLKIN for CLKOUT */
SYSCON_CLKOUTSRC_WDTOSC, /*!< Watchdog oscillator for CLKOUT */
SYSCON_CLKOUTSRC_IRC, /*!< Internal oscillator for CLKOUT */
SYSCON_CLKOUTSRCA_OUTPUT, /*!< clkoutA output route to input of clkoutB */
SYSCON_CLKOUTSRC_RTC = 7 /*!< RTC oscillator 32KHz for CLKOUT */
} CHIP_SYSCON_CLKOUTSRC_T;
/**
* @brief Set CLKOUT clock source and divider
* @param src : Clock source for CLKOUT
* @param div : divider for CLKOUT clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The CLKOUT clock
* rate is the clock source divided by the divider. This function will
* also toggle the clock source update register to update the clock
* source.
*/
void Chip_Clock_SetCLKOUTSource(CHIP_SYSCON_CLKOUTSRC_T src, uint32_t div);
/**
* System and peripheral clocks enum
*/
typedef enum CHIP_SYSCON_CLOCK {
/* Peripheral clock enables for SYSAHBCLKCTRL0 */
SYSCON_CLOCK_ROM = 1, /*!< ROM clock */
SYSCON_CLOCK_SRAM1 = 3, /*!< SRAM1 clock */
SYSCON_CLOCK_SRAM2, /*!< SRAM2 clock */
SYSCON_CLOCK_FLASH = 7, /*!< FLASH controller clock */
SYSCON_CLOCK_FMC, /*!< FMC clock */
SYSCON_CLOCK_INPUTMUX = 11, /*!< Input mux clock */
SYSCON_CLOCK_IOCON = 13, /*!< IOCON clock */
SYSCON_CLOCK_GPIO0, /*!< GPIO0 clock */
SYSCON_CLOCK_GPIO1, /*!< GPIO1 clock */
SYSCON_CLOCK_PINT = 18, /*!< PININT clock */
SYSCON_CLOCK_GINT, /*!< grouped pin interrupt block clock */
SYSCON_CLOCK_DMA, /*!< DMA clock */
SYSCON_CLOCK_CRC, /*!< CRC clock */
SYSCON_CLOCK_WWDT, /*!< WDT clock */
SYSCON_CLOCK_RTC, /*!< RTC clock */
SYSCON_CLOCK_MAILBOX = 26, /*!< Mailbox clock */
SYSCON_CLOCK_ADC0, /*!< ADC0 clock */
/* Peripheral clock enables for SYSAHBCLKCTRL1 */
SYSCON_CLOCK_MRT = 32, /*!< multi-rate timer clock */
SYSCON_CLOCK_RIT, /*!< Repetitive interval timer clock */
SYSCON_CLOCK_SCT0, /*!< SCT0 clock */
SYSCON_CLOCK_FIFO = 32 + 9, /*!< System FIFO clock */
SYSCON_CLOCK_UTICK, /*!< UTICK clock */
SYSCON_CLOCK_TIMER2 = 32 + 22, /*!< TIMER2 clock */
SYSCON_CLOCK_TIMER3 = 32 + 26, /*!< TIMER3 clock */
SYSCON_CLOCK_TIMER4, /*!< TIMER4 clock */
/* Peripheral clock enables for ASYNCAPBCLKCTRLCLR */
SYSCON_CLOCK_USART0 = 128 + 1, /*!< USART0 clock */
SYSCON_CLOCK_USART1, /*!< USART1 clock */
SYSCON_CLOCK_USART2, /*!< USART2 clock */
SYSCON_CLOCK_USART3, /*!< USART3 clock */
SYSCON_CLOCK_I2C0, /*!< I2C0 clock */
SYSCON_CLOCK_I2C1, /*!< I2C1 clock */
SYSCON_CLOCK_I2C2, /*!< I2C2 clock */
SYSCON_CLOCK_SPI0 = 128 + 9, /*!< SPI0 clock */
SYSCON_CLOCK_SPI1, /*!< SPI1 clock */
SYSCON_CLOCK_TIMER0 = 128 + 13, /*!< TIMER0 clock */
SYSCON_CLOCK_TIMER1, /*!< TIMER1 clock */
SYSCON_CLOCK_FRG /*!< FRG clock */
} CHIP_SYSCON_CLOCK_T;
/**
* @brief Enable a system or peripheral clock
* @param clk : Clock to enable
* @return Nothing
*/
void Chip_Clock_EnablePeriphClock(CHIP_SYSCON_CLOCK_T clk);
/**
* @brief Disable a system or peripheral clock
* @param clk : Clock to disable
* @return Nothing
*/
void Chip_Clock_DisablePeriphClock(CHIP_SYSCON_CLOCK_T clk);
/**
* @brief Set system tick clock divider (external CLKIN as SYSTICK reference only)
* @param div : divider for system clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The system tick
* rate is the external CLKIN rate divided by this value. The extern CLKIN pin
* signal, divided by the SYSTICKCLKDIV divider, is selected by clearing
* CLKSOURCE bit 2 in the System Tick CSR register. The core clock must be at least
* 2.5 times faster than the reference system tick clock otherwise the count
* values are unpredictable.
*/
STATIC INLINE void Chip_Clock_SetSysTickClockDiv(uint32_t div)
{
LPC_SYSCON->SYSTICKCLKDIV = div;
}
/**
* @brief Returns system tick clock divider
* @return system tick clock divider
*/
STATIC INLINE uint32_t Chip_Clock_GetSysTickClockDiv(void)
{
return LPC_SYSCON->SYSTICKCLKDIV;
}
/**
* @brief Returns the system tick rate as used with the system tick divider
* @return the system tick rate
*/
uint32_t Chip_Clock_GetSysTickClockRate(void);
/**
* @brief Set system clock divider
* @param div : divider for system clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The system clock
* rate is the main system clock divided by this value.
*/
STATIC INLINE void Chip_Clock_SetSysClockDiv(uint32_t div)
{
LPC_SYSCON->AHBCLKDIV = div;
}
/**
* @brief Set system tick clock divider
* @param div : divider for system clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The system tick
* rate is the main system clock divided by this value. Use caution when using
* the CMSIS SysTick_Config() functions as they typically use SystemCoreClock
* for setup.
*/
STATIC INLINE void Chip_Clock_SetADCClockDiv(uint32_t div)
{
LPC_SYSCON->ADCCLKDIV = div;
}
/**
* @brief Returns ADC clock divider
* @return ADC clock divider, 0 = disabled
*/
STATIC INLINE uint32_t Chip_Clock_GetADCClockDiv(void)
{
return LPC_SYSCON->ADCCLKDIV;
}
/**
* Clock sources for ADC clock source select
*/
typedef enum {
SYSCON_ADCCLKSELSRC_MAINCLK = 0, /*!< Main clock */
SYSCON_ADCCLKSELSRC_SYSPLLOUT, /*!< PLL output */
SYSCON_ADCCLKSELSRC_IRC /*!< Internal oscillator */
} CHIP_SYSCON_ADCCLKSELSRC_T;
/**
* @brief Set the ADC clock source
* @param src : ADC clock source
* @return Nothing
*/
STATIC INLINE void Chip_Clock_SetADCClockSource(CHIP_SYSCON_ADCCLKSELSRC_T src)
{
LPC_SYSCON->ADCCLKSEL = (uint32_t) src;
}
/**
* @brief Returns the ADC clock source
* @return Returns which clock is used for the ADC clock source
*/
STATIC INLINE CHIP_SYSCON_ADCCLKSELSRC_T Chip_Clock_GetADCClockSource(void)
{
return (CHIP_SYSCON_ADCCLKSELSRC_T) (LPC_SYSCON->ADCCLKSEL);
}
/**
* @brief Return ADC clock rate
* @return ADC clock rate
*/
uint32_t Chip_Clock_GetADCClockRate(void);
/**
* @brief Enable the RTC 32KHz output
* @return Nothing
* @note This clock can be used for the main clock directly, but
* do not use this clock with the system PLL.
*/
STATIC INLINE void Chip_Clock_EnableRTCOsc(void)
{
LPC_SYSCON->RTCOSCCTRL = 1;
}
/**
* @brief Disable the RTC 32KHz output
* @return Nothing
*/
STATIC INLINE void Chip_Clock_DisableRTCOsc(void)
{
LPC_SYSCON->RTCOSCCTRL = 0;
}
/**
* Clock source selections for the asynchronous APB clock
*/
typedef enum {
SYSCON_ASYNC_IRC = 0, /*!< IRC input */
SYSCON_ASYNC_WDTOSC, /*!< Watchdog oscillator */
SYSCON_ASYNC_MAINCLK = 4, /*!< Main clock */
SYSCON_ASYNC_CLKIN, /*!< external CLK input */
SYSCON_ASYNC_SYSPLLOUT /*!< System PLL output */
} CHIP_ASYNC_SYSCON_SRC_T;
/**
* @brief Set asynchronous APB clock source
* @param src : Clock source for asynchronous APB clock
* @return Nothing
*/
void Chip_Clock_SetAsyncSysconClockSource(CHIP_ASYNC_SYSCON_SRC_T src);
/**
* @brief Get asynchronous APB clock source
* @return Clock source for asynchronous APB clock
*/
CHIP_ASYNC_SYSCON_SRC_T Chip_Clock_GetAsyncSysconClockSource(void);
/**
* @brief Return asynchronous APB clock rate
* @return Asynchronous APB clock rate
* @note Includes adjustments by Async clock divider (ASYNCCLKDIV).
*/
uint32_t Chip_Clock_GetAsyncSyscon_ClockRate(void);
/**
* @brief Set UART divider clock
* @param div : divider for UART clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The UART clock
* rate is the main system clock divided by this value.
*/
STATIC INLINE void Chip_Clock_SetAsyncSysconClockDiv(uint32_t div)
{
LPC_ASYNC_SYSCON->ASYNCCLKDIV = div;
}
/**
* Clock sources for main system clock. This is a mix of both main clock A
* and B selections.
*/
typedef enum {
SYSCON_MAINCLKSRC_IRC = 0, /*!< Internal oscillator */
SYSCON_MAINCLKSRC_CLKIN, /*!< Crystal (main) oscillator in */
SYSCON_MAINCLKSRC_WDTOSC, /*!< Watchdog oscillator rate */
SYSCON_MAINCLKSRC_PLLIN = 5, /*!< System PLL input */
SYSCON_MAINCLKSRC_PLLOUT, /*!< System PLL output */
SYSCON_MAINCLKSRC_RTC /*!< RTC oscillator 32KHz output */
} CHIP_SYSCON_MAINCLKSRC_T;
/**
* @brief Set main system clock source
* @param src : Clock source for main system
* @return Nothing
*/
void Chip_Clock_SetMainClockSource(CHIP_SYSCON_MAINCLKSRC_T src);
/**
* @brief Get main system clock source
* @return Clock source for main system
* @note
*/
CHIP_SYSCON_MAINCLKSRC_T Chip_Clock_GetMainClockSource(void);
/**
* @brief Return main clock rate
* @return main clock rate
*/
uint32_t Chip_Clock_GetMainClockRate(void);
/**
* @brief Return system clock rate
* @return system clock rate
* @note This is the main clock rate divided by AHBCLKDIV.
*/
uint32_t Chip_Clock_GetSystemClockRate(void);
/**
* @brief Get UART base clock rate
* @return UART base clock rate
*/
uint32_t Chip_Clock_GetUARTBaseClockRate(void);
/**
* @brief Get UART base clock rate using FRG
* @return Actual UART base clock rate
* @note It's recommended to set a base rate at least 16x the
* expected maximum UART transfer bit rate.
*/
uint32_t Chip_Clock_SetUARTBaseClockRate(uint32_t rate);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CLOCK_5410X_H_ */