EFM32: Add LFA and LFB clock support
This commit is contained in:
parent
d13c9a08b9
commit
d273686d42
@ -71,6 +71,18 @@
|
||||
# error HFPERCLK divisor not yet supported
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_LFACLK_ULFRCO
|
||||
# define BOARD_LFA_ULFCO_ENABLE true
|
||||
#else
|
||||
# define BOARD_LFA_ULFCO_ENABLE false
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_LFBCLK_ULFRCO
|
||||
# define BOARD_LFB_ULFCO_ENABLE true
|
||||
#else
|
||||
# define BOARD_LFB_ULFCO_ENABLE false
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@ -140,7 +152,7 @@ static inline void efm32_statuswait(uint32_t bitset)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void efm32_enable_lfrco(void)
|
||||
static void efm32_enable_lfrco(void)
|
||||
{
|
||||
/* Enable the LFRCO */
|
||||
|
||||
@ -148,8 +160,7 @@ static inline void efm32_enable_lfrco(void)
|
||||
efm32_statuswait(CMU_STATUS_LFRCORDY);
|
||||
}
|
||||
|
||||
|
||||
static inline void efm32_enable_lfxo(void)
|
||||
static void efm32_enable_lfxo(void)
|
||||
{
|
||||
/* Enable the LFXO */
|
||||
|
||||
@ -165,7 +176,7 @@ static inline void efm32_enable_hfrco(void)
|
||||
efm32_statuswait(CMU_STATUS_HFRCORDY);
|
||||
}
|
||||
|
||||
static inline void efm32_enable_hfxo(void)
|
||||
static void efm32_enable_hfxo(void)
|
||||
{
|
||||
/* Enable the HFXO */
|
||||
|
||||
@ -181,6 +192,58 @@ static inline void efm32_enable_auxhfrco(void)
|
||||
efm32_statuswait(CMU_STATUS_AUXHFRCORDY);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_enable_leclocking
|
||||
*
|
||||
* Description:
|
||||
* Enable HFCORE clocking to the LE
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void efm32_enable_leclocking(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
regval = getreg32(EFM32_CMU_HFCORECLKEN0);
|
||||
regval |= CMU_HFCORECLKEN0_LE;
|
||||
putreg32(regval, EFM32_CMU_HFCORECLKEN0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_enable_leclocking
|
||||
*
|
||||
* Description:
|
||||
* If the core frequency is higher than CMU_MAX_FREQ_HFLE on
|
||||
* Giant/Leopard/Wonder, enable HFLE and DIV4.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CMU_CTRL_HFLE
|
||||
static void efm32_enable_hfle(uint32_t frequency)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Check if the core frequency is higher than CMU_MAX_FREQ_HFLE */
|
||||
|
||||
if (frequency > CMU_MAX_FREQ_HFLE)
|
||||
{
|
||||
/* Enable HFLE */
|
||||
|
||||
regval = getreg32(EFM32_CMU_CTRL);
|
||||
regval |= CMU_CTRL_HFLE;
|
||||
putreg32(regval, EFM32_CMU_CTRL);
|
||||
|
||||
/* Enable DIV4 factor for peripheral clock */
|
||||
|
||||
regval = getreg32(EFM32_CMU_HFCORECLKDIV);
|
||||
regval |= CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4;
|
||||
putreg32(regval, EFM32_CMU_HFCORECLKDIV);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define efm32_enable_hfle(f)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_maxwaitstates
|
||||
*
|
||||
@ -326,7 +389,7 @@ static void efm32_setwaitstates(uint32_t hfcoreclk)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void efm32_hfclk_config(uint32_t hfclksel, uint32_t hfclkdiv)
|
||||
static inline uint32_t efm32_hfclk_config(uint32_t hfclksel, uint32_t hfclkdiv)
|
||||
{
|
||||
uint32_t frequency;
|
||||
#ifdef CMU_CTRL_HFLE
|
||||
@ -427,6 +490,7 @@ static inline void efm32_hfclk_config(uint32_t hfclksel, uint32_t hfclkdiv)
|
||||
/* Now select the optimal number of FLASH wait states */
|
||||
|
||||
efm32_setwaitstates(frequency);
|
||||
return frequency;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -458,9 +522,11 @@ static inline void efm32_hfclk_config(uint32_t hfclksel, uint32_t hfclkdiv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void efm32_hfcoreclk_config(uint32_t hfcoreclkdiv)
|
||||
static inline uint32_t efm32_hfcoreclk_config(uint32_t hfcoreclkdiv,
|
||||
uint32_t hfclk)
|
||||
{
|
||||
/* REVISIT: Divider not currently used */
|
||||
return hfclk;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -479,9 +545,11 @@ static inline void efm32_hfcoreclk_config(uint32_t hfcoreclkdiv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void efm32_hfperclk_config(uint32_t hfperclkdiv)
|
||||
static inline uint32_t efm32_hfperclk_config(uint32_t hfperclkdiv,
|
||||
uint32_t hfclk)
|
||||
{
|
||||
/* REVISIT: Divider not currently used */
|
||||
return hfclk;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -509,9 +577,77 @@ static inline void efm32_hfperclk_config(uint32_t hfperclkdiv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void efm32_lfaclk_config(uint32_t lfaclksel)
|
||||
static inline uint32_t efm32_lfaclk_config(uint32_t lfaclksel, bool ulfrco,
|
||||
uint32_t hfcoreclk)
|
||||
{
|
||||
/* REVISIT: Not yet implemented */
|
||||
uint32_t lfaclk;
|
||||
uint32_t regval;
|
||||
|
||||
/* ULFRCO is a special case */
|
||||
|
||||
if (ulfrco)
|
||||
{
|
||||
/* ULFRCO is always enabled */
|
||||
|
||||
lfaclksel = _CMU_LFCLKSEL_LFA_DISABLED;
|
||||
lfaclk = BOARD_ULFRCO_FREQUNCY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable the oscillator source */
|
||||
|
||||
switch (lfaclksel)
|
||||
{
|
||||
default:
|
||||
case _CMU_LFCLKSEL_LFA_DISABLED:
|
||||
{
|
||||
lfaclk = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMU_LFCLKSEL_LFA_LFRCO:
|
||||
{
|
||||
efm32_enable_lfrco();
|
||||
}
|
||||
break;
|
||||
|
||||
case _CMU_LFCLKSEL_LFA_LFXO:
|
||||
{
|
||||
efm32_enable_lfxo();
|
||||
lfaclk = BOARD_LFXO_FREQUENCY;
|
||||
}
|
||||
break;
|
||||
|
||||
case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
|
||||
{
|
||||
/* Enable core clocking to the LE */
|
||||
|
||||
efm32_enable_leclocking();
|
||||
|
||||
/* Enable HFLE, if appropriate */
|
||||
|
||||
efm32_enable_hfle(hfcoreclk);
|
||||
|
||||
/* And, finally, enable the HFXO */
|
||||
|
||||
efm32_enable_hfxo();
|
||||
lfaclk = hfcoreclk >> 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable the LFA clock in the LFCLKSEL register */
|
||||
|
||||
regval = getreg32(EFM32_CMU_LFCLKSEL);
|
||||
regval &= ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK);
|
||||
regval |= (lfaclksel << _CMU_LFCLKSEL_LFA_SHIFT);
|
||||
#ifdef CMU_LFCLKSEL_LFAE_ULFRCO
|
||||
regval |= ((uint32_t)ulfrco << _CMU_LFCLKSEL_LFAE_SHIFT);
|
||||
#endif
|
||||
putreg32(regval, EFM32_CMU_LFCLKSEL);
|
||||
|
||||
return lfaclk;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -535,9 +671,77 @@ static inline void efm32_lfaclk_config(uint32_t lfaclksel)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void efm32_lfbclk_config(uint32_t lfbclksel)
|
||||
static inline uint32_t efm32_lfbclk_config(uint32_t lfbclksel, bool ulfrco,
|
||||
uint32_t hfcoreclk)
|
||||
{
|
||||
/* REVISIT: Not yet implemented */
|
||||
uint32_t lfbclk;
|
||||
uint32_t regval;
|
||||
|
||||
/* ULFRCO is a special case */
|
||||
|
||||
if (ulfrco)
|
||||
{
|
||||
/* ULFRCO is always enabled */
|
||||
|
||||
lfbclksel = _CMU_LFCLKSEL_LFB_DISABLED;
|
||||
lfbclk = BOARD_ULFRCO_FREQUNCY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable the oscillator source */
|
||||
|
||||
switch (lfbclksel)
|
||||
{
|
||||
default:
|
||||
case _CMU_LFCLKSEL_LFB_DISABLED:
|
||||
{
|
||||
lfbclk = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMU_LFCLKSEL_LFB_LFRCO:
|
||||
{
|
||||
efm32_enable_lfrco();
|
||||
}
|
||||
break;
|
||||
|
||||
case _CMU_LFCLKSEL_LFB_LFXO:
|
||||
{
|
||||
efm32_enable_lfxo();
|
||||
lfbclk = BOARD_LFXO_FREQUENCY;
|
||||
}
|
||||
break;
|
||||
|
||||
case _CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:
|
||||
{
|
||||
/* Enable core clocking to the LE */
|
||||
|
||||
efm32_enable_leclocking();
|
||||
|
||||
/* Enable HFLE, if appropriate */
|
||||
|
||||
efm32_enable_hfle(hfcoreclk);
|
||||
|
||||
/* And, finally, enable the HFXO */
|
||||
|
||||
efm32_enable_hfxo();
|
||||
lfbclk = hfcoreclk >> 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable the LFB clock in the LFCLKSEL register */
|
||||
|
||||
regval = getreg32(EFM32_CMU_LFCLKSEL);
|
||||
regval &= ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK);
|
||||
regval |= (lfbclksel << _CMU_LFCLKSEL_LFB_SHIFT);
|
||||
#ifdef CMU_LFCLKSEL_LFBE_ULFRCO
|
||||
regval |= ((uint32_t)ulfrco << _CMU_LFCLKSEL_LFBE_SHIFT);
|
||||
#endif
|
||||
putreg32(regval, EFM32_CMU_LFCLKSEL);
|
||||
|
||||
return lfbclk;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -634,17 +838,28 @@ static inline void efm32_gpioclock(void)
|
||||
|
||||
void efm32_clockconfig(void)
|
||||
{
|
||||
uint32_t hfclk;
|
||||
uint32_t hfcoreclk;
|
||||
uint32_t hfperclk;
|
||||
uint32_t lfaclk;
|
||||
uint32_t lfbclk;
|
||||
|
||||
/* Enable clocks and set dividers as determined by the board.h header file */
|
||||
|
||||
efm32_hfclk_config(BOARD_HFCLKSEL, BOARD_HFCLKDIV);
|
||||
efm32_hfcoreclk_config(BOARD_HFCORECLKDIV);
|
||||
efm32_hfperclk_config(BOARD_HFPERCLKDIV);
|
||||
efm32_lfaclk_config(BOARD_LFACLKSEL);
|
||||
efm32_lfbclk_config(BOARD_LFBCLKSEL);
|
||||
hfclk = efm32_hfclk_config(BOARD_HFCLKSEL, BOARD_HFCLKDIV);
|
||||
hfcoreclk = efm32_hfcoreclk_config(BOARD_HFCORECLKDIV, hfclk);
|
||||
hfperclk = efm32_hfperclk_config(BOARD_HFPERCLKDIV, hfclk);
|
||||
lfaclk = efm32_lfaclk_config(BOARD_LFACLKSEL, BOARD_LFA_ULFCO_ENABLE, hfcoreclk);
|
||||
lfbclk = efm32_lfbclk_config(BOARD_LFBCLKSEL, BOARD_LFB_ULFCO_ENABLE, hfcoreclk);
|
||||
|
||||
efm32_pcntclk_config();
|
||||
efm32_wdogclk_config();
|
||||
efm32_auxclk_config();
|
||||
|
||||
UNUSED(hfperclk);
|
||||
UNUSED(lfaclk);
|
||||
UNUSED(lfbclk);
|
||||
|
||||
/* Enable clocking of the GPIO ports */
|
||||
|
||||
efm32_gpioclock();
|
||||
|
@ -56,6 +56,7 @@
|
||||
* - 4-32 MHz High Frequency Crystal Oscillator (HFXO)
|
||||
* - 32.768 kHz Low Frequency RC Oscillator (LFRCO)
|
||||
* - 32.768 kHz Low Frequency Crystal Oscillator (LFXO)
|
||||
* - 1KHz Ultra Low Frequency RC Oscillator (ULFRCO)
|
||||
*
|
||||
* The device boots with 14 MHz HFRCO as the HFCLK source.
|
||||
*/
|
||||
@ -67,6 +68,7 @@
|
||||
#define BOARD_HFXO_FREQUENCY 32000000 /* 32MHz crystal on board */
|
||||
#define BOARD_LFRCO_FREQUENCY 32768 /* Low frequency oscillator */
|
||||
#define BOARD_LFXO_FREQUENCY 32768 /* 32MHz crystal on board */
|
||||
#define BOARD_ULFRCO_FREQUNCY 1000 /* Ultra low frequency oscillator */
|
||||
|
||||
/* HFCLK - High Frequency Clock
|
||||
*
|
||||
@ -110,9 +112,13 @@
|
||||
* LFRCO is disabled from reset. The selection is configured using the LFA
|
||||
* field in CMU_LFCLKSEL. The HFCORECLK/2 setting allows the Low Energy A
|
||||
* Peripherals to be used as high-frequency peripherals.
|
||||
*
|
||||
* Use _CMU_LFCLKSEL_LFA_DISABLED to disable.
|
||||
* ULFRCO is a special case.
|
||||
*/
|
||||
|
||||
#define BOARD_LFACLKSEL _CMU_LFCLKSEL_LFA_LFXO
|
||||
#undef BOARD_LFACLK_ULFRCO
|
||||
#define BOARD_LFACLK_FREQUENCY BOARD_LFXO_FREQUENCY
|
||||
|
||||
/* LFBCLK - Low Frequency B Clock
|
||||
@ -123,9 +129,13 @@
|
||||
* LFRCO is disabled from reset. The selection is configured using the LFB
|
||||
* field in CMU_LFCLKSEL. The HFCORECLK/2 setting allows the Low Energy B
|
||||
* Peripherals to be used as high-frequency peripherals.
|
||||
*
|
||||
* Use _CMU_LFCLKSEL_LFA_DISABLED to disable
|
||||
* ULFRCO is a special case.
|
||||
*/
|
||||
|
||||
#define BOARD_LFBCLKSEL _CMU_LFCLKSEL_LFB_LFXO
|
||||
#undef BOARD_LFBCLK_ULFRCO
|
||||
#define BOARD_LFBCLK_FREQUENCY BOARD_LFXO_FREQUENCY
|
||||
|
||||
/* PCNTnCLK - Pulse Counter n Clock
|
||||
|
@ -56,6 +56,7 @@
|
||||
* - 4-32 MHz High Frequency Crystal Oscillator (HFXO)
|
||||
* - 32.768 kHz Low Frequency RC Oscillator (LFRCO)
|
||||
* - 32.768 kHz Low Frequency Crystal Oscillator (LFXO)
|
||||
* - 1KHz Ultra Low Frequency RC Oscillator (ULFRCO)
|
||||
*
|
||||
* The device boots with 14 MHz HFRCO as the HFCLK source.
|
||||
*/
|
||||
@ -67,6 +68,7 @@
|
||||
#define BOARD_HFXO_FREQUENCY 32000000 /* 32MHz crystal on board */
|
||||
#define BOARD_LFRCO_FREQUENCY 32768 /* Low frequency oscillator */
|
||||
#define BOARD_LFXO_FREQUENCY 32768 /* 32MHz crystal on board */
|
||||
#define BOARD_ULFRCO_FREQUNCY 1000 /* Ultra low frequency oscillator */
|
||||
|
||||
/* HFCLK - High Frequency Clock
|
||||
*
|
||||
@ -110,9 +112,13 @@
|
||||
* LFRCO is disabled from reset. The selection is configured using the LFA
|
||||
* field in CMU_LFCLKSEL. The HFCORECLK/2 setting allows the Low Energy A
|
||||
* Peripherals to be used as high-frequency peripherals.
|
||||
*
|
||||
* Use _CMU_LFCLKSEL_LFA_DISABLED to disable
|
||||
* ULFRCO is a special case.
|
||||
*/
|
||||
|
||||
#define BOARD_LFACLKSEL _CMU_LFCLKSEL_LFA_LFXO
|
||||
#undef BOARD_LFACLK_ULFRCO
|
||||
#define BOARD_LFACLK_FREQUENCY BOARD_LFXO_FREQUENCY
|
||||
|
||||
/* LFBCLK - Low Frequency B Clock
|
||||
@ -123,9 +129,13 @@
|
||||
* LFRCO is disabled from reset. The selection is configured using the LFB
|
||||
* field in CMU_LFCLKSEL. The HFCORECLK/2 setting allows the Low Energy B
|
||||
* Peripherals to be used as high-frequency peripherals.
|
||||
*
|
||||
* Use _CMU_LFCLKSEL_LFB_DISABLED to disable
|
||||
* ULFRCO is a special case.
|
||||
*/
|
||||
|
||||
#define BOARD_LFBCLKSEL _CMU_LFCLKSEL_LFB_LFXO
|
||||
#undef BOARD_LFBCLK_ULFRCO
|
||||
#define BOARD_LFBCLK_FREQUENCY BOARD_LFXO_FREQUENCY
|
||||
|
||||
/* PCNTnCLK - Pulse Counter n Clock
|
||||
|
Loading…
Reference in New Issue
Block a user