mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
333 lines
9.5 KiB
C
333 lines
9.5 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 Implementation specific CPU configuration options
|
||
|
*
|
||
|
* @author iosabi <iosabi@protonmail.com>
|
||
|
*/
|
||
|
|
||
|
#ifndef CPU_CONF_H
|
||
|
#define CPU_CONF_H
|
||
|
|
||
|
#include "cpu_conf_common.h"
|
||
|
|
||
|
#include "vendor/QN908XC.h"
|
||
|
#include "vendor/QN908XC_features.h"
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @name ARM Cortex-M specific CPU configuration
|
||
|
* @{
|
||
|
*/
|
||
|
#define CPU_DEFAULT_IRQ_PRIO (1U)
|
||
|
/**
|
||
|
* NUMBER_OF_INT_VECTORS in the QN908XC.h is defined as including the standard
|
||
|
* ARM interrupt vectors and headers, however CPU_IRQ_NUMOF does not include
|
||
|
* the first 15 interrupt values and the stack pointer.
|
||
|
*/
|
||
|
#define CPU_IRQ_NUMOF (NUMBER_OF_INT_VECTORS - 16)
|
||
|
/**
|
||
|
* The flash is aliased at several addresses in the memory range. In particular,
|
||
|
* address 0 can be mapped to RAM or flash, so it is possible to run from
|
||
|
* address 0 from flash, or even turn off the flash altogether and run from RAM
|
||
|
* to save power. This setting uses the ROM_START_ADDR value set in the
|
||
|
* Makefile.
|
||
|
*/
|
||
|
#define CPU_FLASH_BASE (QN908X_ROM_START_ADDR)
|
||
|
/**
|
||
|
* @brief Bit-Band configuration
|
||
|
*/
|
||
|
#define CPU_HAS_BITBAND 1
|
||
|
/** @} */
|
||
|
|
||
|
/**
|
||
|
* @name Clocks configuration
|
||
|
* @{
|
||
|
* @brief External and internal clocks configuration.
|
||
|
*
|
||
|
* The QN908x has an internal 32 MHz RCO for the high frequency clock source and
|
||
|
* a 32 KHz RCO for the low frequency clock source, as well as external
|
||
|
* connections for a crystal oscillator (XTAL) of either 16 MHz or 32 MHz for
|
||
|
* the high frequency clock source and another connection for a 32.768 KHz XTAL
|
||
|
* for the low frequency clock normally used for accurate Bluetooth timing.
|
||
|
* Note that the "32 KHz" clock source is not exactly the same frequency whether
|
||
|
* you use the internal or external one.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Whether the board has a 32.768 KHz crystal in XTAL32_IN / XTAL32_OUT.
|
||
|
**/
|
||
|
#if !defined(CONFIG_BOARD_HAS_XTAL32K) || DOXYGEN
|
||
|
#define CONFIG_BOARD_HAS_XTAL32K 0
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @name 32K low frequency clock selector
|
||
|
* @{
|
||
|
*/
|
||
|
#ifdef DOXYGEN
|
||
|
/**
|
||
|
* @brief Enabled when the 32K low frequency uses the external crystal.
|
||
|
**/
|
||
|
#define CONFIG_CPU_CLK_32K_XTAL
|
||
|
/**
|
||
|
* @brief Enabled when the 32K low frequency uses the internal oscillator.
|
||
|
**/
|
||
|
#define CONFIG_CPU_CLK_32K_RCO
|
||
|
#endif /* def DOXYGEN */
|
||
|
/** @} */
|
||
|
|
||
|
/* Default 32K clock selector config. */
|
||
|
#if !defined(CONFIG_CPU_CLK_32K_XTAL) && !defined(CONFIG_CPU_CLK_32K_RCO)
|
||
|
#if CONFIG_BOARD_HAS_XTAL32K
|
||
|
#define CONFIG_CPU_CLK_32K_XTAL 1
|
||
|
#else
|
||
|
#define CONFIG_CPU_CLK_32K_RCO 1
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @brief Whether the board has a 16 or 32 MHz crystal in XTAL_IN / XTAL_OUT.
|
||
|
* @{
|
||
|
**/
|
||
|
#ifndef CONFIG_BOARD_HAS_XTAL
|
||
|
#define CONFIG_BOARD_HAS_XTAL 0
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @name External high frequency "XTAL" crystal frequency
|
||
|
*/
|
||
|
#ifdef DOXYGEN
|
||
|
/**
|
||
|
* @brief Enabled when the external XTAL is a 16 MHz one.
|
||
|
**/
|
||
|
#define CONFIG_CPU_CLK_XTAL_16M
|
||
|
/**
|
||
|
* @brief Enabled when the external XTAL is a 32 MHz one.
|
||
|
**/
|
||
|
#define CONFIG_CPU_CLK_XTAL_32M
|
||
|
#endif /* def DOXYGEN */
|
||
|
/** @} */
|
||
|
|
||
|
/* Default XTAL setting. */
|
||
|
#if CONFIG_BOARD_HAS_XTAL && \
|
||
|
!defined(CONFIG_BOARD_HAS_XTAL_16M) && !defined(CONFIG_BOARD_HAS_XTAL_32M)
|
||
|
#define CONFIG_BOARD_HAS_XTAL_32M 1
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @brief Internal OSC32M clock input /2 divider enabled
|
||
|
**/
|
||
|
#ifndef CONFIG_CPU_CLK_OSC32M_DIV
|
||
|
#define CONFIG_CPU_CLK_OSC32M_DIV 0
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @brief External XTAL 32 MHz clock input /2 divider enabled
|
||
|
**/
|
||
|
#ifndef CONFIG_CPU_CLK_XTAL_DIV
|
||
|
#define CONFIG_CPU_CLK_XTAL_DIV 0
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @name System clock configuration selector
|
||
|
* @{
|
||
|
*/
|
||
|
#ifdef DOXYGEN
|
||
|
/**
|
||
|
* @brief System clock is external crystal source (including divider).
|
||
|
**/
|
||
|
#define CONFIG_CPU_CLK_SYS_XTAL
|
||
|
/**
|
||
|
* @brief System clock is internal 32 MHz oscillator source (including divider).
|
||
|
**/
|
||
|
#define CONFIG_CPU_CLK_SYS_OSC32M
|
||
|
/**
|
||
|
* @brief System clock is the low frequency clock (32 or 32.768 KHz)
|
||
|
**/
|
||
|
#define CONFIG_CPU_CLK_SYS_32K
|
||
|
#endif /* def DOXYGEN */
|
||
|
/** @} */
|
||
|
|
||
|
/* Default system clock configuration selector */
|
||
|
#if !defined(CONFIG_CPU_CLK_SYS_XTAL) && !defined(CONFIG_CPU_CLK_SYS_OSC32M) && \
|
||
|
!defined(CONFIG_CPU_CLK_SYS_32K)
|
||
|
#if CONFIG_BOARD_HAS_XTAL
|
||
|
#define CONFIG_CPU_CLK_SYS_XTAL 1
|
||
|
#else
|
||
|
#define CONFIG_CPU_CLK_SYS_OSC32M 1
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @brief AHB clock divider
|
||
|
*
|
||
|
* The AHB clock is derived from the System clock using this divider value,
|
||
|
* between 1 and 8192, and serves as a clock source for ARM core, FSP, SCT,
|
||
|
* Quad-SPI, Flexcomm (UART, SPI, I2C), GPIO, BLE_AHB and DMA.
|
||
|
* Note: When BLE is enabled, the AHB clock must be at least the BLE clock
|
||
|
* (either 8 or 16 MHz) limiting the range of allowed values for this
|
||
|
* divider so that the AHB clock is 8, 16 or 32 MHz.
|
||
|
**/
|
||
|
#ifndef CONFIG_CPU_CLK_AHB_DIV
|
||
|
#define CONFIG_CPU_CLK_AHB_DIV 1u
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @brief APB clock divider
|
||
|
*
|
||
|
* The APB clock is derived from the AHB clock using this divide value,
|
||
|
* between 1 and 16, and serves as the clock source for several
|
||
|
* peripherals, such as the RTC, ADC, DAC, Capacitive Sense (CS) and
|
||
|
* optionally the WDT.
|
||
|
**/
|
||
|
#ifndef CONFIG_CPU_CLK_APB_DIV
|
||
|
#define CONFIG_CPU_CLK_APB_DIV 1u
|
||
|
#endif
|
||
|
|
||
|
/** @} */
|
||
|
|
||
|
/**
|
||
|
* @name Code Read Protection
|
||
|
* @{
|
||
|
* @brief Image "Code Read Protection" field definitions.
|
||
|
*
|
||
|
* The Code Read Protection (CRP) is a 32-bit field stored in one of the
|
||
|
* reserved fields in the Cortex-M interrupt vector and therefore part of the
|
||
|
* image. It allows to enable or disable access to the flash from the In-System
|
||
|
* Programming (ISP) interface to read, erase or write flash pages, as well as
|
||
|
* external SWD access for debugging or programming the flash. Not all the CRP
|
||
|
* values are valid and an invalid value may render the flash inaccessible and
|
||
|
* effectively brick the device.
|
||
|
*
|
||
|
* To select the access level define the @ref QN908X_CRP macro from the global
|
||
|
* compile options, otherwise the default value in this module will be used
|
||
|
* (allowing everything). The value of the uint32_t CRP field in the Image
|
||
|
* vector table should be the "or" of the following QN908X_CRP_* macros. Every
|
||
|
* field must be either enabled or disabled, otherwise it would result in an
|
||
|
* invalid CRP value.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Number of pages to protect (0 to 255).
|
||
|
*
|
||
|
* This defines the number of pages to protect starting from 0. A value of 0
|
||
|
* in this macro means that no page is protected. The maximum number allowed to
|
||
|
* be passed to this macro is 255, however there are 256 pages in the flash. The
|
||
|
* last page is protected if any other page is protected.
|
||
|
*
|
||
|
* Protected pages can't be erased or written to by the ISP.
|
||
|
*/
|
||
|
#define QN908X_CRP_PROTECT_PAGES(X) (255 - (X))
|
||
|
|
||
|
/**
|
||
|
* @brief Mass erase from ISP allowed.
|
||
|
*/
|
||
|
#define QN908X_CRP_MASS_ERASE_ALLOW (0x800)
|
||
|
/**
|
||
|
* @brief Mass erase from ISP not allowed.
|
||
|
*/
|
||
|
#define QN908X_CRP_MASS_ERASE_DISALLOW (0x400)
|
||
|
|
||
|
/**
|
||
|
* @brief Page erase/write from ISP (for unprotected pages) allowed.
|
||
|
*/
|
||
|
#define QN908X_CRP_PAGE_ERASE_WRITE_ALLOW (0x2000)
|
||
|
/**
|
||
|
* @brief Page erase/write from ISP (for unprotected pages) not allowed.
|
||
|
*/
|
||
|
#define QN908X_CRP_PAGE_ERASE_WRITE_DISALLOW (0x1000)
|
||
|
|
||
|
/**
|
||
|
* @brief Flash read (for unprotected pages) from ISP allowed or not.
|
||
|
*/
|
||
|
#define QN908X_CRP_FLASH_READ_ALLOW (0x8000)
|
||
|
/**
|
||
|
* @brief Flash read (for unprotected pages) from ISP not allowed.
|
||
|
*/
|
||
|
#define QN908X_CRP_FLASH_READ_DISALLOW (0x4000)
|
||
|
|
||
|
/**
|
||
|
* @brief ISP entry is allowed (via CHIP_MODE pin).
|
||
|
*/
|
||
|
#define QN908X_CRP_ISP_ENTRY_ALLOW (0x20000)
|
||
|
/**
|
||
|
* @brief ISP entry via CHIP_MODE pin is not allowed.
|
||
|
*/
|
||
|
#define QN908X_CRP_ISP_ENTRY_DISALLOW (0x10000)
|
||
|
|
||
|
/**
|
||
|
* @brief External access is allowed (including SWD interface).
|
||
|
*/
|
||
|
#define QN908X_CRP_EXTERNAL_ACCESS_ALLOW (0x80000)
|
||
|
/**
|
||
|
* @brief External access is not allowed (including SWD interface).
|
||
|
*/
|
||
|
#define QN908X_CRP_EXTERNAL_ACCESS_DISALLOW (0x40000)
|
||
|
|
||
|
/** @} */
|
||
|
|
||
|
/**
|
||
|
* @brief Default "Code Read Protection" allows everything.
|
||
|
*/
|
||
|
#ifndef QN908X_CRP
|
||
|
#define QN908X_CRP \
|
||
|
(QN908X_CRP_PROTECT_PAGES(0) \
|
||
|
| QN908X_CRP_MASS_ERASE_ALLOW \
|
||
|
| QN908X_CRP_PAGE_ERASE_WRITE_ALLOW \
|
||
|
| QN908X_CRP_FLASH_READ_ALLOW \
|
||
|
| QN908X_CRP_ISP_ENTRY_ALLOW \
|
||
|
| QN908X_CRP_EXTERNAL_ACCESS_ALLOW)
|
||
|
#endif /* QN908X_CRP */
|
||
|
|
||
|
/**
|
||
|
* @brief The "Code Read Protection" is stored at the offset 0x20.
|
||
|
*
|
||
|
* To modify the CRP field define the macro @ref QN908X_CRP.
|
||
|
*/
|
||
|
#define CORTEXM_VECTOR_RESERVED_0X20 QN908X_CRP
|
||
|
|
||
|
/* Safety checks that the QN908X_CRP value is valid. */
|
||
|
#if !(QN908X_CRP & QN908X_CRP_MASS_ERASE_ALLOW) == \
|
||
|
!(QN908X_CRP & QN908X_CRP_MASS_ERASE_DISALLOW)
|
||
|
#error "Must select exactly one of QN908X_CRP_MASS_ERASE_* in the QN908X_CRP"
|
||
|
#endif
|
||
|
#if !(QN908X_CRP & QN908X_CRP_PAGE_ERASE_WRITE_ALLOW) == \
|
||
|
!(QN908X_CRP & QN908X_CRP_PAGE_ERASE_WRITE_DISALLOW)
|
||
|
#error \
|
||
|
"Must select exactly one of QN908X_CRP_PAGE_ERASE_WRITE_* in the QN908X_CRP"
|
||
|
#endif
|
||
|
#if !(QN908X_CRP & QN908X_CRP_FLASH_READ_ALLOW) == \
|
||
|
!(QN908X_CRP & QN908X_CRP_FLASH_READ_DISALLOW)
|
||
|
#error "Must select exactly one of QN908X_CRP_FLASH_READ_* in the QN908X_CRP"
|
||
|
#endif
|
||
|
#if !(QN908X_CRP & QN908X_CRP_ISP_ENTRY_ALLOW) == \
|
||
|
!(QN908X_CRP & QN908X_CRP_ISP_ENTRY_DISALLOW)
|
||
|
#error "Must select exactly one of QN908X_CRP_ISP_ENTRY_* in the QN908X_CRP"
|
||
|
#endif
|
||
|
#if !(QN908X_CRP & QN908X_CRP_EXTERNAL_ACCESS_ALLOW) == \
|
||
|
!(QN908X_CRP & QN908X_CRP_EXTERNAL_ACCESS_DISALLOW)
|
||
|
#error \
|
||
|
"Must select exactly one of QN908X_CRP_EXTERNAL_ACCESS_* in the QN908X_CRP"
|
||
|
#endif
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* CPU_CONF_H */
|
||
|
/** @} */
|