2018-03-27 16:10:12 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018, Christian Taedcke
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file
|
2018-09-16 18:01:04 +08:00
|
|
|
* @brief Common SoC initialization for the EXX32
|
2018-03-27 16:10:12 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <kernel.h>
|
|
|
|
#include <init.h>
|
|
|
|
#include <soc.h>
|
|
|
|
#include <em_cmu.h>
|
|
|
|
#include <em_chip.h>
|
|
|
|
#include <arch/cpu.h>
|
|
|
|
#include <cortex_m/exc.h>
|
|
|
|
|
|
|
|
#ifdef CONFIG_CMU_HFCLK_HFXO
|
|
|
|
/**
|
|
|
|
* @brief Initialization parameters for the external high frequency oscillator
|
|
|
|
*/
|
|
|
|
static const CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_DEFAULT;
|
|
|
|
#elif (defined CONFIG_CMU_HFCLK_LFXO)
|
|
|
|
/**
|
|
|
|
* @brief Initialization parameters for the external low frequency oscillator
|
|
|
|
*/
|
|
|
|
static const CMU_LFXOInit_TypeDef lfxoInit = CMU_LFXOINIT_DEFAULT;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize the system clock
|
|
|
|
*
|
|
|
|
* @return N/A
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static ALWAYS_INLINE void clkInit(void)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_CMU_HFCLK_HFXO
|
2018-08-16 17:17:44 +08:00
|
|
|
if (CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_HFXO) {
|
|
|
|
CMU_HFXOInit(&hfxoInit);
|
|
|
|
CMU_OscillatorEnable(cmuOsc_HFXO, true, true);
|
|
|
|
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
|
|
|
|
}
|
2018-03-27 16:10:12 +08:00
|
|
|
SystemHFXOClockSet(CONFIG_CMU_HFXO_FREQ);
|
|
|
|
CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
|
2018-08-16 17:17:44 +08:00
|
|
|
#elif (defined CONFIG_CMU_HFCLK_LFXO)
|
|
|
|
if (CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_LFXO) {
|
|
|
|
CMU_LFXOInit(&lfxoInit);
|
|
|
|
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
|
|
|
|
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_LFXO);
|
|
|
|
}
|
2018-03-27 16:10:12 +08:00
|
|
|
SystemLFXOClockSet(CONFIG_CMU_LFXO_FREQ);
|
2018-08-16 17:17:44 +08:00
|
|
|
CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
|
2018-03-27 16:10:12 +08:00
|
|
|
#elif (defined CONFIG_CMU_HFCLK_HFRCO)
|
|
|
|
/*
|
|
|
|
* This is the default clock, the controller starts with, so nothing to
|
|
|
|
* do here.
|
|
|
|
*/
|
|
|
|
#else
|
|
|
|
#error "Unsupported clock source for HFCLK selected"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Enable the High Frequency Peripheral Clock */
|
|
|
|
CMU_ClockEnable(cmuClock_HFPER, true);
|
|
|
|
|
|
|
|
#ifdef CONFIG_GPIO_GECKO
|
|
|
|
CMU_ClockEnable(cmuClock_GPIO, true);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Perform basic hardware initialization
|
|
|
|
*
|
|
|
|
* Initialize the interrupt controller device drivers.
|
|
|
|
* Also initialize the timer device driver, if required.
|
|
|
|
*
|
|
|
|
* @return 0
|
|
|
|
*/
|
2018-09-16 18:01:04 +08:00
|
|
|
static int silabs_exx32_init(struct device *arg)
|
2018-03-27 16:10:12 +08:00
|
|
|
{
|
|
|
|
ARG_UNUSED(arg);
|
|
|
|
|
2018-08-15 08:57:08 +08:00
|
|
|
unsigned int oldLevel; /* old interrupt lock level */
|
2018-03-27 16:10:12 +08:00
|
|
|
|
|
|
|
/* disable interrupts */
|
|
|
|
oldLevel = irq_lock();
|
|
|
|
|
|
|
|
/* handle chip errata */
|
|
|
|
CHIP_Init();
|
|
|
|
|
|
|
|
_ClearFaults();
|
|
|
|
|
|
|
|
/* Initialize system clock according to CONFIG_CMU settings */
|
|
|
|
clkInit();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* install default handler that simply resets the CPU
|
|
|
|
* if configured in the kernel, NOP otherwise
|
|
|
|
*/
|
|
|
|
NMI_INIT();
|
|
|
|
|
|
|
|
/* restore interrupt state */
|
|
|
|
irq_unlock(oldLevel);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-16 18:01:04 +08:00
|
|
|
SYS_INIT(silabs_exx32_init, PRE_KERNEL_1, 0);
|