mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
126 lines
3.7 KiB
C
126 lines
3.7 KiB
C
/*
|
|
* Copyright (C) 2020 iosabi
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser General
|
|
* Public License v2.1. See the file LICENSE in the top level directory for more
|
|
* details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup cpu_qn908x
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief QN908x CPU initialization
|
|
*
|
|
* @author iosabi <iosabi@protonmail.com>
|
|
* @}
|
|
*/
|
|
|
|
#include "cpu.h"
|
|
#include "kernel_init.h"
|
|
#include "periph/init.h"
|
|
|
|
#include "stdio_base.h"
|
|
|
|
#include "vendor/drivers/fsl_clock.h"
|
|
|
|
static void cpu_clock_init(void);
|
|
|
|
/**
|
|
* @brief Initialize the CPU
|
|
*/
|
|
void cpu_init(void)
|
|
{
|
|
/* initialize the Cortex-M core */
|
|
cortexm_init();
|
|
#ifndef MODULE_PERIPH_WDT
|
|
/* If the `periph_wdt` is *not* being used (because the user does not care
|
|
* about that feature) we need to disable the Watchdog and continue running
|
|
* without it. Otherwise the CPU will reboot after about 10 seconds.
|
|
*/
|
|
CLOCK_DisableClock(kCLOCK_Wdt);
|
|
#endif /* ndef MODULE_PERIPH_WDT */
|
|
|
|
/* TODO: It would be good to move the VTOR to SRAM to allow execution from
|
|
* RAM with the FLASH memory off to allow for ultra low power operation on
|
|
* sleep mode. This needs to be done after cortexm_init() since it sets the
|
|
* VTOR to _isr_vectors which is the address on FLASH.
|
|
*/
|
|
|
|
/* initialize the clocks */
|
|
cpu_clock_init();
|
|
|
|
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
|
|
early_init();
|
|
/* trigger static peripheral initialization */
|
|
periph_init();
|
|
}
|
|
|
|
/* Set up clock speed configuration. See cpu_conf.h for details about the
|
|
* different clock options. */
|
|
void cpu_clock_init(void)
|
|
{
|
|
/* Set up external clock frequency. */
|
|
#if CONFIG_BOARD_HAS_XTAL
|
|
#if CONFIG_BOARD_HAS_XTAL_32M
|
|
CLOCK_AttachClk(k32M_to_XTAL_CLK); /* Switch XTAL_CLK to 32M */
|
|
#elif CONFIG_BOARD_HAS_XTAL_16M
|
|
CLOCK_AttachClk(k16M_to_XTAL_CLK); /* Switch XTAL_CLK to 16M */
|
|
#else
|
|
#error "One of the CONFIG_BOARD_XTAL_* must be set."
|
|
#endif
|
|
#endif /* CONFIG_BOARD_HAS_XTAL */
|
|
|
|
/* Set up 32K clock source. */
|
|
#if CONFIG_CPU_CLK_32K_XTAL
|
|
CLOCK_AttachClk(kXTAL32K_to_32K_CLK); /* Switch 32K_CLK to XTAL32K */
|
|
#elif CONFIG_CPU_CLK_32K_RCO
|
|
CLOCK_AttachClk(kRCO32K_to_32K_CLK); /* Switch 32K_CLK to RCO32K */
|
|
#else
|
|
#error "One of the CONFIG_CPU_CLK_32K_* must be set."
|
|
#endif
|
|
|
|
/* Set up System clock source. */
|
|
#if CONFIG_CPU_CLK_SYS_XTAL
|
|
CLOCK_AttachClk(kXTAL_to_SYS_CLK); /* Switch SYS_CLK to XTAL */
|
|
#elif CONFIG_CPU_CLK_SYS_OSC32M
|
|
CLOCK_AttachClk(kOSC32M_to_SYS_CLK); /* Switch SYS_CLK to OSM32M */
|
|
#elif CONFIG_CPU_CLK_SYS_32K
|
|
CLOCK_AttachClk(k32K_to_SYS_CLK); /* Switch SYS_CLK to 32K source */
|
|
#else
|
|
#error "One of the CONFIG_CPU_CLK_SYS_* must be set."
|
|
#endif
|
|
|
|
/* Run the WDT from the APB always. */
|
|
CLOCK_AttachClk(kAPB_to_WDT_CLK);
|
|
|
|
/* Set up dividers */
|
|
|
|
/* Set OSC32M_DIV divider */
|
|
#if CONFIG_CPU_CLK_OSC32M_DIV != 0 && CONFIG_CPU_CLK_OSC32M_DIV != 1
|
|
#error "Invalid CONFIG_CPU_CLK_OSC32M_DIV value"
|
|
#endif
|
|
/* Note: The denominator is set to (CONFIG_CPU_CLK_OSC32M_DIV + 1), so /2
|
|
* when the macro is enabled. */
|
|
CLOCK_SetClkDiv(kCLOCK_DivOsc32mClk, CONFIG_CPU_CLK_OSC32M_DIV);
|
|
|
|
/* Set XTAL_DIV divider */
|
|
#if CONFIG_CPU_CLK_XTAL_DIV != 0 && CONFIG_CPU_CLK_XTAL_DIV != 1
|
|
#error "Invalid CONFIG_CPU_CLK_XTAL_DIV value"
|
|
#endif
|
|
CLOCK_SetClkDiv(kCLOCK_DivXtalClk, CONFIG_CPU_CLK_XTAL_DIV);
|
|
|
|
/* Set AHB_DIV divider. */
|
|
#if CONFIG_CPU_CLK_AHB_DIV < 1 || CONFIG_CPU_CLK_AHB_DIV > 8192
|
|
#error "Invalid CONFIG_CPU_CLK_AHB_DIV"
|
|
#endif
|
|
CLOCK_SetClkDiv(kCLOCK_DivAhbClk, CONFIG_CPU_CLK_AHB_DIV - 1u);
|
|
|
|
/* Set APB_DIV divider. */
|
|
#if CONFIG_CPU_CLK_APB_DIV < 1 || CONFIG_CPU_CLK_APB_DIV > 16
|
|
#error "Invalid CONFIG_CPU_CLK_APB_DIV"
|
|
#endif
|
|
CLOCK_SetClkDiv(kCLOCK_DivApbClk, CONFIG_CPU_CLK_APB_DIV - 1u);
|
|
}
|