mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #13855 from iosabi/qn908x_initial
cpu/qn908x: Initial minimal support for NXP QN908x CPUs.
This commit is contained in:
commit
646e665a86
10
boards/common/qn908x/Kconfig
Normal file
10
boards/common/qn908x/Kconfig
Normal file
@ -0,0 +1,10 @@
|
||||
# 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.
|
||||
|
||||
config BOARD_COMMON_QN908X
|
||||
bool
|
||||
depends on CPU_FAM_QN908X
|
||||
# Add common board support here.
|
3
boards/common/qn908x/Makefile
Normal file
3
boards/common/qn908x/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = boards_common_qn908x
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
3
boards/common/qn908x/Makefile.features
Normal file
3
boards/common/qn908x/Makefile.features
Normal file
@ -0,0 +1,3 @@
|
||||
CPU ?= qn908x
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
26
boards/common/qn908x/Makefile.include
Normal file
26
boards/common/qn908x/Makefile.include
Normal file
@ -0,0 +1,26 @@
|
||||
# Using dap or jlink depends on which firmware the OpenSDA debugger is running
|
||||
#DEBUG_ADAPTER ?= dap
|
||||
DEBUG_ADAPTER ?= jlink
|
||||
|
||||
# Use the shared OpenOCD configuration
|
||||
OPENOCD_CONFIG ?= $(RIOTBOARD)/common/qn908x/dist/openocd.cfg
|
||||
|
||||
# Disable the watchdog when flashing. OpenOCD runs a CRC program in RAM to
|
||||
# verify the image, which needs to have the WDT disabled but it is normally
|
||||
# enabled after a 'reset halt' command.
|
||||
OPENOCD_PRE_FLASH_CMDS += "-c qn908x disable_wdog"
|
||||
|
||||
# Set default port depending on operating system
|
||||
PORT_LINUX ?= /dev/ttyACM0
|
||||
PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.usbmodem*)))
|
||||
|
||||
# OpenOCD is able to handle .elf files and is the preferred way.
|
||||
FLASHFILE ?= $(ELFFILE)
|
||||
|
||||
# Setup serial terminal
|
||||
include $(RIOTMAKE)/tools/serial.inc.mk
|
||||
|
||||
# This board uses OpenOCD. Note that support for QN908x in OpenOCD at the time
|
||||
# of writing has not been merged in the tree and is only available at
|
||||
# http://openocd.zylin.com/#/c/5584/ .
|
||||
include $(RIOTMAKE)/tools/openocd.inc.mk
|
12
boards/common/qn908x/dist/openocd.cfg
vendored
Normal file
12
boards/common/qn908x/dist/openocd.cfg
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# Generic configuration for a qn908x-based board.
|
||||
|
||||
# QN908X only supports SWD
|
||||
transport select swd
|
||||
|
||||
# NXP QN908x.
|
||||
source [find target/qn908x.cfg]
|
||||
|
||||
$TARGETNAME configure -event gdb-attach {
|
||||
halt
|
||||
}
|
||||
$TARGETNAME configure -rtos auto
|
21
boards/qn9080dk/Kconfig
Normal file
21
boards/qn9080dk/Kconfig
Normal file
@ -0,0 +1,21 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
config BOARD
|
||||
default "qn9080dk" if BOARD_QN9080DK
|
||||
|
||||
config BOARD_QN9080DK
|
||||
bool
|
||||
default y
|
||||
select BOARD_COMMON_QN908X
|
||||
select CPU_MODEL_QN9080XHN
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
select BOARD_HAS_XTAL32K
|
||||
select BOARD_HAS_XTAL_32M
|
||||
|
||||
source "$(RIOTBOARD)/common/qn908x/Kconfig"
|
6
boards/qn9080dk/Makefile
Normal file
6
boards/qn9080dk/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
MODULE = board
|
||||
|
||||
# Use the common qn908x board.
|
||||
DIRS += $(RIOTBOARD)/common/qn908x
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
3
boards/qn9080dk/Makefile.dep
Normal file
3
boards/qn9080dk/Makefile.dep
Normal file
@ -0,0 +1,3 @@
|
||||
ifneq (,$(filter saul_default,$(USEMODULE)))
|
||||
USEMODULE += saul_gpio
|
||||
endif
|
8
boards/qn9080dk/Makefile.features
Normal file
8
boards/qn9080dk/Makefile.features
Normal file
@ -0,0 +1,8 @@
|
||||
CPU = qn908x
|
||||
CPU_MODEL = qn9080xhn
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
||||
|
||||
# Include the common qn908x board features.
|
||||
include $(RIOTBOARD)/common/qn908x/Makefile.features
|
8
boards/qn9080dk/Makefile.include
Normal file
8
boards/qn9080dk/Makefile.include
Normal file
@ -0,0 +1,8 @@
|
||||
CFLAGS += \
|
||||
-DCONFIG_BOARD_HAS_XTAL \
|
||||
-DCONFIG_BOARD_HAS_XTAL32K \
|
||||
-DCONFIG_BOARD_HAS_XTAL_32M \
|
||||
#
|
||||
|
||||
# Include default QN908x board config
|
||||
include $(RIOTBOARD)/common/qn908x/Makefile.include
|
37
boards/qn9080dk/board.c
Normal file
37
boards/qn9080dk/board.c
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 boards_qn9080dk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Board specific implementations for the QN9080DK base board
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "periph/gpio.h"
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
/* Initialize LEDs and Buttons. */
|
||||
gpio_init(LED_RED_PIN, GPIO_OUT);
|
||||
gpio_init(LED_GREEN_PIN, GPIO_OUT);
|
||||
gpio_init(LED_BLUE_PIN, GPIO_OUT);
|
||||
gpio_init(BTN1_PIN, BTN1_MODE);
|
||||
gpio_init(BTN2_PIN, BTN2_MODE);
|
||||
|
||||
/* initialize the CPU */
|
||||
cpu_init();
|
||||
}
|
62
boards/qn9080dk/doc.txt
Normal file
62
boards/qn9080dk/doc.txt
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
@defgroup boards_qn9080dk QN9080DK base board
|
||||
@ingroup boards
|
||||
@brief Support for the QN9080DK base board.
|
||||
|
||||
### General information
|
||||
|
||||
The QN9080DK is the developer board reference from NXP for the QN908x CPUs.
|
||||
The developer kit comes with two boards: a larger PCB with a QFN "module"
|
||||
including a QN9080DHN soldered onto it, altogether referred as the "base
|
||||
board"; and separately a much smaller USB dongle with another QN9080 cpu.
|
||||
This board module supports the "base board" only, including the definitions
|
||||
of the gpio, buttons and LEDs specific to this board.
|
||||
|
||||
This board packs a few peripherals and many GPIOs:
|
||||
|
||||
* MMA8652FC, a 12-bit accelerometer
|
||||
*
|
||||
|
||||
The board also features a dedicated programmer hardware implemented using NXP's
|
||||
LPC4322, with its dedicated USB port for connecting to a computer on one end
|
||||
and the SWD port and one UART RX/TX pair connected to the QN9080 on the other
|
||||
end. The LPC4322 also has a fast (50 ksps) ADC ADC122S021 connected to a
|
||||
current sense amplifier to monitor the QN9080 current profile directly on
|
||||
the board.
|
||||
|
||||
For more information visit NXP's product description page for the
|
||||
[QN9080-DK](https://www.nxp.com/QN9080DK) where you can find the User's
|
||||
Guide.
|
||||
|
||||
### User Interface
|
||||
|
||||
Buttons:
|
||||
|
||||
| Label | RIOT OS macro | MCU PIN | Function |
|
||||
|:----- |:------------- |:-------- |:--------- |
|
||||
| SW1 | BTN1_PIN | PA24 | User defined |
|
||||
| SW2 | BTN2_PIN | PA19 | User defined |
|
||||
| SW3 | | nRESET | QN9080 reset |
|
||||
|
||||
|
||||
One RGB led, controlled by three GPIOs
|
||||
|
||||
| Label | RIOT OS macro | MCU PIN |
|
||||
|:----- |:------------- |:-------- |
|
||||
| red | LED_RED_PIN | PA31 |
|
||||
| green | LED_GREEN_PIN | PA25 |
|
||||
| blue | LED_BLUE_PIN | PA13 |
|
||||
|
||||
### Pinout
|
||||
|
||||
Button1:
|
||||
|
||||
### Flash the board
|
||||
|
||||
The board can be flashed using the internal LPC4322 JTAG/SWD debugger or an
|
||||
external debugger connected to P1, selected using JP2.
|
||||
|
||||
OpenOCD support for the QN908x is experimental and available as pending
|
||||
[patch](http://openocd.zylin.com/#/c/5584/).
|
||||
|
||||
*/
|
69
boards/qn9080dk/include/board.h
Normal file
69
boards/qn9080dk/include/board.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 boards_qn9080dk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Board specific definitions for the QN9080DK base board
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H
|
||||
#define BOARD_H
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Clock configuration
|
||||
* @{
|
||||
*/
|
||||
#ifndef CLOCK_CORECLOCK
|
||||
/* Using 32MHz internal oscillator as default clock source */
|
||||
#define CLOCK_CORECLOCK (32000000ul)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LED configuration
|
||||
* @{
|
||||
*/
|
||||
#define LED_RED_PIN GPIO_PIN(PORT_A, 31)
|
||||
#define LED_GREEN_PIN GPIO_PIN(PORT_A, 25)
|
||||
#define LED_BLUE_PIN GPIO_PIN(PORT_A, 13)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name User buttons
|
||||
* @{
|
||||
*/
|
||||
#define BTN1_PIN GPIO_PIN(PORT_A, 24)
|
||||
#define BTN1_MODE GPIO_IN_PU
|
||||
#define BTN2_PIN GPIO_PIN(PORT_A, 19)
|
||||
#define BTN2_MODE GPIO_IN_PU
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Initialize board specific hardware
|
||||
*/
|
||||
void board_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BOARD_H */
|
||||
/** @} */
|
71
boards/qn9080dk/include/gpio_params.h
Normal file
71
boards/qn9080dk/include/gpio_params.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 boards_qn9080dk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Board specific configuration of direct mapped GPIOs
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*/
|
||||
|
||||
#ifndef GPIO_PARAMS_H
|
||||
#define GPIO_PARAMS_H
|
||||
|
||||
#include "board.h"
|
||||
#include "saul/periph.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPIO pin configuration
|
||||
*/
|
||||
static const saul_gpio_params_t saul_gpio_params[] =
|
||||
{
|
||||
{
|
||||
.name = "LED red",
|
||||
.pin = LED_RED_PIN,
|
||||
.mode = GPIO_OUT,
|
||||
.flags = SAUL_GPIO_INIT_CLEAR,
|
||||
},
|
||||
{
|
||||
.name = "LED green",
|
||||
.pin = LED_GREEN_PIN,
|
||||
.mode = GPIO_OUT,
|
||||
.flags = SAUL_GPIO_INIT_CLEAR,
|
||||
},
|
||||
{
|
||||
.name = "LED blue",
|
||||
.pin = LED_BLUE_PIN,
|
||||
.mode = GPIO_OUT,
|
||||
.flags = SAUL_GPIO_INIT_CLEAR,
|
||||
},
|
||||
{
|
||||
.name = "Button(SW1)",
|
||||
.pin = BTN1_PIN,
|
||||
.mode = BTN1_MODE,
|
||||
.flags = SAUL_GPIO_INVERTED,
|
||||
},
|
||||
{
|
||||
.name = "Button(SW2)",
|
||||
.pin = BTN2_PIN,
|
||||
.mode = BTN2_MODE,
|
||||
.flags = SAUL_GPIO_INVERTED,
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GPIO_PARAMS_H */
|
||||
/** @} */
|
49
boards/qn9080dk/include/periph_conf.h
Normal file
49
boards/qn9080dk/include/periph_conf.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 boards_qn9080dk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Configuration of CPU peripherals for QN9080DK base board board
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CONF_H
|
||||
#define PERIPH_CONF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* put here the board peripherals definitions:
|
||||
- Available clocks
|
||||
- Timers
|
||||
- UARTs
|
||||
- PWMs
|
||||
- SPIs
|
||||
- I2C
|
||||
- ADC
|
||||
- RTC
|
||||
- RTT
|
||||
etc
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PERIPH_CONF_H */
|
||||
/** @} */
|
51
cpu/qn908x/Kconfig
Normal file
51
cpu/qn908x/Kconfig
Normal file
@ -0,0 +1,51 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
config CPU_FAM_QN908X
|
||||
bool
|
||||
select CPU_CORE_CORTEX_M4F
|
||||
select HAS_CORTEXM_MPU
|
||||
select HAS_CPU_QN908X
|
||||
select HAS_PERIPH_CPUID
|
||||
select HAS_PERIPH_GPIO
|
||||
select HAS_PERIPH_GPIO_IRQ
|
||||
select HAS_PERIPH_WDT
|
||||
select HAS_PERIPH_WDT_CB
|
||||
|
||||
## CPU Models
|
||||
# For cpus QN9080CHN (revision C) and QN9080DHN (revision D)
|
||||
config CPU_MODEL_QN9080XHN
|
||||
bool
|
||||
select CPU_FAM_QN908X
|
||||
|
||||
# For the smaller package for the same die, with 28 GPIOs instead of 35.
|
||||
# cpus QN9083CUK (revision C) and QN9083DUK (revision D)
|
||||
config CPU_MODEL_QN9083XUK
|
||||
bool
|
||||
select CPU_FAM_QN908X
|
||||
|
||||
## CPU common symbols
|
||||
config CPU_FAM
|
||||
default "qn908x" if CPU_FAM_QN908X
|
||||
|
||||
config CPU_MODEL
|
||||
default "qn9080xhn" if CPU_MODEL_QN9080XHN
|
||||
default "qn9083xhk" if CPU_MODEL_QN9083XUK
|
||||
|
||||
config CPU
|
||||
default "qn908x" if CPU_FAM_QN908X
|
||||
|
||||
## Definition of specific features
|
||||
config HAS_CPU_QN908X
|
||||
bool
|
||||
help
|
||||
Indicates that the current cpu is 'qn908x'.
|
||||
|
||||
# Other cpu configuration
|
||||
rsource "Kconfig.clk"
|
||||
|
||||
source "$(RIOTCPU)/cortexm_common/Kconfig"
|
120
cpu/qn908x/Kconfig.clk
Normal file
120
cpu/qn908x/Kconfig.clk
Normal file
@ -0,0 +1,120 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
menu "QN908x clock configuration"
|
||||
depends on CPU_FAM_QN908X
|
||||
|
||||
config BOARD_HAS_XTAL32K
|
||||
bool
|
||||
help
|
||||
Indicates that the board has an external low frequency 32.786 KHz
|
||||
crystal oscillator connected to the XTAL32_IN / XTAL32_OUT pins.
|
||||
This should only be set from board definition.
|
||||
|
||||
choice
|
||||
prompt "32K low frequency clock selector"
|
||||
default CPU_CLK_32K_XTAL if BOARD_HAS_XTAL32K
|
||||
default CPU_CLK_32K_RCO
|
||||
help
|
||||
The "32K" clock bus runs at either 32 KHz from the internal RCO or
|
||||
32.768 KHz from an external crystal oscillator. This clock can be used
|
||||
to drive the "System clock" for a very low power operation, but it can
|
||||
independently also be used for the watchdog timer (WDT) and other low
|
||||
frequency system timers like a real time clock.
|
||||
|
||||
config CPU_CLK_32K_XTAL
|
||||
bool "External 32.768 KHz crystal"
|
||||
depends on BOARD_HAS_XTAL32K
|
||||
|
||||
config CPU_CLK_32K_RCO
|
||||
bool "Internal 32 KHz oscillator"
|
||||
|
||||
endchoice
|
||||
|
||||
config BOARD_HAS_XTAL
|
||||
bool
|
||||
help
|
||||
Indicates that the board has an external high frequency crystal
|
||||
oscillator connected to the XTAL_IN / XTAL_OUT pins.
|
||||
This should only be set from board definition.
|
||||
|
||||
config BOARD_HAS_XTAL_16M
|
||||
bool
|
||||
imply BOARD_HAS_XTAL
|
||||
depends on !BOARD_HAS_XTAL_32M
|
||||
help
|
||||
Indicates that the external high frequency crystal oscillator is a
|
||||
16 MHz crystal. This should only be set from board definition.
|
||||
|
||||
config BOARD_HAS_XTAL_32M
|
||||
bool
|
||||
imply BOARD_HAS_XTAL
|
||||
help
|
||||
Indicates that the external high frequency crystal oscillator is a
|
||||
32 MHz crystal. This should only be set from board definition.
|
||||
|
||||
config CPU_CLK_OSC32M_DIV
|
||||
bool "Internal OSC32M clock input /2 divider"
|
||||
help
|
||||
Selecting this option will set the high-speed internal oscillator
|
||||
divider to /2, making it a 16 MHz clock source. See "System clock
|
||||
configuration selector" for selecting this source.
|
||||
|
||||
config CPU_CLK_XTAL_DIV
|
||||
bool "External XTAL 32 MHz clock input /2 divider"
|
||||
depends on BOARD_HAS_XTAL_32M
|
||||
help
|
||||
Selecting this option will set the high-speed external crystal
|
||||
oscillator divider to /2. This option is only available when the
|
||||
external oscillator is a 32 MHz one. See "System clock
|
||||
configuration selector" for selecting this source.
|
||||
|
||||
choice
|
||||
prompt "System clock configuration selector"
|
||||
default CPU_CLK_SYS_XTAL if BOARD_HAS_XTAL
|
||||
default CPU_CLK_SYS_OSC32M
|
||||
help
|
||||
The System clock is used to derive the AHB clock, which drives the ARM
|
||||
core and most peripherals.
|
||||
|
||||
config CPU_CLK_SYS_XTAL
|
||||
bool "External 16/32 MHz crystal source (with optional divider)"
|
||||
depends on BOARD_HAS_XTAL
|
||||
|
||||
config CPU_CLK_SYS_OSC32M
|
||||
bool "Internal 32 MHz oscillator source (with optional divider)"
|
||||
|
||||
config CPU_CLK_SYS_32K
|
||||
bool "Low frequency clock source (32 or 32.768 KHz)"
|
||||
|
||||
endchoice
|
||||
|
||||
config CPU_CLK_AHB_DIV
|
||||
int "AHB clock divider"
|
||||
default 1
|
||||
range 1 8192
|
||||
help
|
||||
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.
|
||||
|
||||
config CPU_CLK_APB_DIV
|
||||
int "APB clock divider"
|
||||
default 1
|
||||
range 1 16
|
||||
help
|
||||
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.
|
||||
|
||||
# TODO: Add USB PLL and BLE clock selectors.
|
||||
|
||||
endmenu
|
10
cpu/qn908x/Makefile
Normal file
10
cpu/qn908x/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# define the module that is build
|
||||
MODULE = cpu
|
||||
|
||||
# add a list of subdirectories that should also be built
|
||||
DIRS = periph $(RIOTCPU)/cortexm_common vendor
|
||||
|
||||
# (file triggers compiler bug. see #5775)
|
||||
SRC_NOLTO += vectors.c
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
18
cpu/qn908x/Makefile.dep
Normal file
18
cpu/qn908x/Makefile.dep
Normal file
@ -0,0 +1,18 @@
|
||||
# In some cases, peripheral modules use vendor provided driver modules such as
|
||||
# the vendor_fsl_clock. This file defines the dependencies between these periph
|
||||
# modules and the vendor modules.
|
||||
USEMODULE += vendor
|
||||
|
||||
# The clock functionality is used by most modules, including cpu.c even when
|
||||
# no peripheral module is being used.
|
||||
USEMODULE += vendor_fsl_clock
|
||||
|
||||
# All peripherals use gpio_mux.h
|
||||
USEMODULE += periph_gpio_mux
|
||||
|
||||
# This cpu modules doesn't support UART peripherals yet, so we need to include
|
||||
# stdio_null.
|
||||
# TODO: Remove stdio_null once periph_uart is implemented in this module.
|
||||
USEMODULE += stdio_null
|
||||
|
||||
include $(RIOTCPU)/cortexm_common/Makefile.dep
|
9
cpu/qn908x/Makefile.features
Normal file
9
cpu/qn908x/Makefile.features
Normal file
@ -0,0 +1,9 @@
|
||||
CPU_CORE = cortex-m4f
|
||||
CPU_FAM = qn908x
|
||||
|
||||
FEATURES_PROVIDED += cortexm_mpu
|
||||
FEATURES_PROVIDED += periph_cpuid
|
||||
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
||||
FEATURES_PROVIDED += periph_wdt periph_wdt_cb
|
||||
|
||||
include $(RIOTCPU)/cortexm_common/Makefile.features
|
39
cpu/qn908x/Makefile.include
Normal file
39
cpu/qn908x/Makefile.include
Normal file
@ -0,0 +1,39 @@
|
||||
# Add search path for linker scripts
|
||||
LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ldscripts
|
||||
LINKER_SCRIPT = qn908x.ld
|
||||
|
||||
# Internal FLASH memory is located at address 0x0100000, aliased to address
|
||||
# 0x2100000 and can also be aliased to address 0, which is done by the
|
||||
# pre_startup() function in cpu/qn908x/isr_qn908x.c. The address 0 can be also
|
||||
# be remapped to RAM instead, and the FLASH can be turned completely off to save
|
||||
# power, thus linking all the code based on address 0 could make it easier in
|
||||
# the future to provide a low-power mode where portions of the code execute
|
||||
# from RAM only during this low-power mode. However, linking all the code at
|
||||
# address 0 makes it more difficult to attach gdb after a 'reset halt' but
|
||||
# before the FLASH is mapped to 0 by pre_startup() since it can't place a
|
||||
# breakpoint at any function in the FLASH alias at 0 until it is mapped.
|
||||
# This default value of 0x01000000 makes it possible to place breakpoints across
|
||||
# reboots, but it can be override from the board if needed. When setting
|
||||
# ROM_START_ADDR to 0 the IMAGE_OFFSET must be set to 0x01000000 to allow
|
||||
# flashing at the right location.
|
||||
ROM_START_ADDR ?= 0x01000000
|
||||
# SRAM is actually at 0x04000000 but it is also aliased to 0x20000000.
|
||||
RAM_BASE_ADDR = 0x20000000
|
||||
RAM_START_ADDR = $(RAM_BASE_ADDR)
|
||||
|
||||
# The only QN908x chips available have 512K flash, although it seems possible to
|
||||
# have 256K versions.
|
||||
ROM_LEN ?= 512K
|
||||
RAM_LEN ?= 128K
|
||||
|
||||
CFLAGS += \
|
||||
-DQN908X_ROM_START_ADDR=$(ROM_START_ADDR)
|
||||
#
|
||||
|
||||
# Vendor submodules are all bundled in the vendor module, and they include
|
||||
# some files from the include/vendor directory directly so we need to add that
|
||||
# include path here.
|
||||
PSEUDOMODULES += vendor_%
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/include/vendor
|
||||
|
||||
include $(RIOTMAKE)/arch/cortexm.inc.mk
|
125
cpu/qn908x/cpu.c
Normal file
125
cpu/qn908x/cpu.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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 "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 */
|
||||
stdio_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);
|
||||
}
|
68
cpu/qn908x/doc.txt
Normal file
68
cpu/qn908x/doc.txt
Normal file
@ -0,0 +1,68 @@
|
||||
/* NXP QN908x specific information for the `periph` drivers */
|
||||
/**
|
||||
|
||||
@defgroup cpu_qn908x NXP QN908x
|
||||
@ingroup cpu
|
||||
@brief NXP QN908x BLE-enabled Cortex-M4F MCU specific implementation
|
||||
|
||||
The NXP QN908x family of chips such as the QN9080 feature a Cortex-M4F,
|
||||
Bluetooth Low Energy, USB 2.0 and in some SKUs like the QN9080SIP NFC as well.
|
||||
The CPU is designed to be ultra-low-power and high-performance, allowing
|
||||
applications with small battery capacity. It includes an optional DC-DC and LDO,
|
||||
low power sleep timers, I2C, SPI, ADC, SPIFI and several other peripherals.
|
||||
|
||||
|
||||
@defgroup cpu_qn908x_cpuid NXP QN908x CPUID
|
||||
@ingroup cpu_qn908x
|
||||
@brief NXP QN908x CPUID driver
|
||||
|
||||
No configuration is necessary. The CPUID value is based on the factory assigned
|
||||
default Bluetooth address in the read-only flash section which may not be the
|
||||
Bluetooth address used by the Bluetooth module if a different one was programmed
|
||||
there.
|
||||
|
||||
|
||||
@defgroup cpu_qn908x_gpio NXP QN908x GPIO
|
||||
@ingroup cpu_qn908x
|
||||
@brief NXP QN908x GPIO driver
|
||||
|
||||
The GPIO driver uses the @ref GPIO_PIN(port, pin) macro to declare pins.
|
||||
|
||||
No configuration is necessary.
|
||||
|
||||
|
||||
@defgroup cpu_qn908x_wdt NXP QN908x Watchdog timer (WDT)
|
||||
@ingroup cpu_qn908x
|
||||
@brief NXP QN908x Watchdog timer (WDT)
|
||||
|
||||
The Watchdog timer in the NXP QN908x starts disabled on reset: the clock bit
|
||||
`CLK_WDT_EN` is enabled in the `CLK_EN` register on reset so the timer is
|
||||
running but the interrupt and reset functions are disabled. However, after the
|
||||
read-only bootloader ROM in the QN908x transfer the control flow to the user
|
||||
application (the RIOT kernel) the Watchdog is enabled with a timeout of 10
|
||||
seconds.
|
||||
|
||||
If your board does not include the `periph_wdt` module, the Watchdog will be
|
||||
disabled at `cpu_init()` time and there's no configuration necessary. However,
|
||||
if your board or application does include it, the Watchdog will be left
|
||||
configured with the 10 second timeout set by the Bootloader and you need to
|
||||
call `wdt_setup_reboot()` or `wdt_setup_reboot_with_callback()` within the first
|
||||
10 seconds.
|
||||
|
||||
The WDT block supports different clock sources which would be configured by the
|
||||
board since they depend on whether the optional crystals are populated in your
|
||||
board. Nevertheless, the millisecond values passed to `wdt_setup_reboot*` are
|
||||
internally converted to clock ticks using the clock configured at the time the
|
||||
function was called. `wdt_setup_reboot*()` can be called multiple times to
|
||||
change the WDT parameters or after changing the WDT clock source, but in any
|
||||
case `wdt_start()` must be called after it to start the WDT operation.
|
||||
|
||||
Once the WDT triggers, it is not possible to avoid the device reboot and calling
|
||||
wdt_kick() from the WDT callback (if any) or after the callback was called will
|
||||
not have any effect. Note that, however, if the WDT callback returns before the
|
||||
configured CONFIG_WDT_WARNING_PERIOD the CPU will continue executing the code
|
||||
before the WDT interrupt occurred. If this is not desired, an infinite loop at
|
||||
the end of the WDT callback, after the safety operations have been performed is
|
||||
advisable.
|
||||
|
||||
*/
|
332
cpu/qn908x/include/cpu_conf.h
Normal file
332
cpu/qn908x/include/cpu_conf.h
Normal file
@ -0,0 +1,332 @@
|
||||
/*
|
||||
* 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 */
|
||||
/** @} */
|
71
cpu/qn908x/include/gpio_mux.h
Normal file
71
cpu/qn908x/include/gpio_mux.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 Common Pin MUX functions.
|
||||
*
|
||||
* The pins in this CPU are multiplexed to several different function. This
|
||||
* module allows to configure the pin multiplexer (MUX) from peripheral drivers.
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*/
|
||||
|
||||
#ifndef GPIO_MUX_H
|
||||
#define GPIO_MUX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Obtain the GPIO_BASE address from a GPIO_PIN(x, y) value.
|
||||
*/
|
||||
#define GPIO_T_ADDR_BASE(pin) (GPIOA_BASE + ((pin) & 0xf000u))
|
||||
|
||||
/**
|
||||
* @brief Obtain the GPIO_BASE GPIO_Type* pointer from a GPIO_PIN(x, y) value.
|
||||
*/
|
||||
#define GPIO_T_ADDR(pin) ((GPIO_Type *)(GPIO_T_ADDR_BASE(pin)))
|
||||
|
||||
/**
|
||||
* @brief Obtain the "x" port number (0 based) from a GPIO_PIN(x, y) value.
|
||||
*
|
||||
* This macro needs to be kept in sync with the definition of GPIO_PIN.
|
||||
*/
|
||||
#define GPIO_T_PORT(pin) ((gpio_t)(pin) >> 12u)
|
||||
|
||||
/**
|
||||
* @brief Obtain the pin number "y" from a GPIO_PIN(x, y) value.
|
||||
*/
|
||||
#define GPIO_T_PIN(pin) ((pin) & 0x00ffu)
|
||||
|
||||
#if defined(GPIOB_BASE) && (GPIO_T_ADDR_BASE(GPIO_PIN(1, 1)) != GPIOB_BASE)
|
||||
#error "GPIO_T_ADDR(GPIO_PIN(1, x)) must be the GPIOB address"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Configure the pin mux to the given function.
|
||||
*
|
||||
* The meaning of the function value will depend on the gpio pin.
|
||||
*/
|
||||
void gpio_init_mux(gpio_t pin, uint32_t func);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GPIO_MUX_H */
|
||||
/** @} */
|
148
cpu/qn908x/include/periph_cpu.h
Normal file
148
cpu/qn908x/include/periph_cpu.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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 CPU specific definitions for internal peripheral handling
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CPU_H
|
||||
#define PERIPH_CPU_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name CPU specific gpio_t type definition
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_T
|
||||
typedef uint16_t gpio_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Definition of a fitting UNDEF value
|
||||
*/
|
||||
#define GPIO_UNDEF (0xffff)
|
||||
|
||||
/**
|
||||
* @brief Define a CPU specific GPIO pin generator macro.
|
||||
*
|
||||
* This generates the GPIO port base address with a mask of the GPIO_PIN value
|
||||
* to avoid a memory access. The value 12 here is selected as an optimization
|
||||
* to be able to derive the GPIO port address with a simple mask of the GPIO_PIN
|
||||
* value.
|
||||
*/
|
||||
#define GPIO_PIN(x, y) (((x) << 12u) | (y))
|
||||
|
||||
/* QN908x has a unique default Bluetooth address in the Flash Information Page
|
||||
* descriptor. This value is set in the factory and cannot be modified by
|
||||
* users. However, the actual Bluetooth address used by the stack may be
|
||||
* different, this is just the default. */
|
||||
/**
|
||||
* @brief Starting offset of CPU_ID
|
||||
*/
|
||||
#define CPUID_ADDR (FSL_FEATURE_FLASH_ADDR_OF_VENDOR_BD_ADDR)
|
||||
|
||||
/**
|
||||
* @brief Length of the CPU_ID in octets
|
||||
*/
|
||||
#define CPUID_LEN (6U)
|
||||
|
||||
/**
|
||||
* @brief Watchdog clock can be stopped independently of other clocks.
|
||||
*/
|
||||
#define WDT_HAS_STOP (1)
|
||||
|
||||
/**
|
||||
* @name WDT upper and lower bound times in ms
|
||||
* @{
|
||||
*/
|
||||
/** The WDT clock can run up to 16MHz (via CLK_APB) and the WDT counter is
|
||||
* 32-bit so the maximum value in ms we can wait is ((1 << 32) - 1) / 16000.
|
||||
* TODO: A much larger limit (~1.5 days) can be set if the WDT runs from the
|
||||
* 32 KHz clock. However, this is likely decided by the board and depends on the
|
||||
* clocks installed on the board. Figure out a way to configure this limit based
|
||||
* on the clock used.
|
||||
*/
|
||||
#define NWDT_TIME_LOWER_LIMIT (0)
|
||||
#define NWDT_TIME_UPPER_LIMIT (268435U)
|
||||
#define WWDT_TIME_LOWER_LIMIT (0)
|
||||
#define WWDT_TIME_UPPER_LIMIT (268435U)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Generate GPIO mode bitfields
|
||||
*
|
||||
* The GPIO_MODE has the following structure:
|
||||
* - bit 0: open-drain: 1 for enabled (open-drain mode) and 0 for disabled.
|
||||
* - bit 1: output-enabled: 1 output mode, 0 input mode.
|
||||
* - bit 4-5: pull_mode: 0 for hi-z (no pull-up or down), 1 for pull-down and 2
|
||||
* for pull-up. These correspond to the IOCON_MODE macros.
|
||||
*/
|
||||
#define GPIO_MODE(open_drain, out_enabled, pull_mode) \
|
||||
((open_drain) | ((out_enabled) << 1) | ((pull_mode) << 4))
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @name GPIO pin modes
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_MODE_T
|
||||
typedef enum {
|
||||
GPIO_IN = GPIO_MODE(0, 0, 0), /**< IN */
|
||||
GPIO_IN_PD = GPIO_MODE(0, 0, 1), /**< IN with pull-down */
|
||||
GPIO_IN_PU = GPIO_MODE(0, 0, 2), /**< IN with pull-up */
|
||||
GPIO_OUT = GPIO_MODE(0, 1, 0), /**< OUT (push-pull) */
|
||||
GPIO_OD = GPIO_MODE(1, 1, 0), /**< OD */
|
||||
GPIO_OD_PU = GPIO_MODE(1, 1, 2), /**< OD with pull-up */
|
||||
} gpio_mode_t;
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @name GPIO flank configuration values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_FLANK_T
|
||||
typedef enum {
|
||||
GPIO_LOW = 0, /**< emit interrupt when the value is low */
|
||||
GPIO_HIGH = 1, /**< emit interrupt when the value is high */
|
||||
GPIO_RISING = 2, /**< emit interrupt on rising flank */
|
||||
GPIO_FALLING = 3, /**< emit interrupt on falling flank */
|
||||
} gpio_flank_t;
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief Available ports on the QN908x.
|
||||
*/
|
||||
enum {
|
||||
PORT_A = 0, /**< port A */
|
||||
PORT_B = 1, /**< port B */
|
||||
GPIO_PORTS_NUMOF /**< overall number of available ports */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PERIPH_CPU_H */
|
||||
/** @} */
|
118
cpu/qn908x/include/vectors_qn908x.h
Normal file
118
cpu/qn908x/include/vectors_qn908x.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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 Interrupt service routine declarations NXP QN908x MCUs
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef VECTORS_QN908X_H
|
||||
#define VECTORS_QN908X_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "vectors_cortexm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Dummy handler
|
||||
*/
|
||||
void dummy_handler(void);
|
||||
|
||||
/* Device specific interrupt vectors */
|
||||
void isr_ext_gpio_wakeup(void); /**< Ext GPIO wakeup */
|
||||
void isr_osc(void); /**< BLE wakeup */
|
||||
void isr_acmp0(void); /**< Analog comparator0 */
|
||||
void isr_acmp1(void); /**< Analog comparator1 */
|
||||
void isr_rtc_sec(void); /**< RTC second */
|
||||
void isr_rtc_fr(void); /**< RTC free running */
|
||||
void isr_cs_wakeup(void); /**< Capacitive sense wakeup */
|
||||
void isr_cs(void); /**< Capacitive sense */
|
||||
void isr_gpioa(void); /**< GPIO group A */
|
||||
void isr_gpiob(void); /**< GPIO group B */
|
||||
void isr_dma0(void); /**< DMA controller */
|
||||
void isr_pin_int0(void); /**< pin or pattern match engine slice 0 */
|
||||
void isr_pin_int1(void); /**< pin or pattern match engine slice 1 */
|
||||
void isr_pin_int2(void); /**< pin or pattern match engine slice 2 */
|
||||
void isr_pin_int3(void); /**< pin or pattern match engine slice 3 */
|
||||
void isr_osc_int_low(void); /**< Inverse of OSC */
|
||||
void isr_usb0(void); /**< USB device */
|
||||
void isr_flexcomm0(void); /**< Flexcomm Interface 0 (USART) */
|
||||
void isr_flexcomm1(void); /**< Flexcomm Interface 1 (USART, I2C) */
|
||||
void isr_flexcomm2(void); /**< Flexcomm Interface 2 (SPI, I2C) */
|
||||
void isr_flexcomm3(void); /**< Flexcomm Interface 3 (SPI) */
|
||||
void isr_ble(void); /**< BLE interrupts */
|
||||
void isr_fsp(void); /**< FSP */
|
||||
void isr_qdec0(void); /**< QDEC0 */
|
||||
void isr_qdec1(void); /**< QDEC1 */
|
||||
void isr_ctimer0(void); /**< Standard counter/timer CTIMER0 */
|
||||
void isr_ctimer1(void); /**< Standard counter/timer CTIMER1 */
|
||||
void isr_ctimer2(void); /**< Standard counter/timer CTIMER2 */
|
||||
void isr_ctimer3(void); /**< Standard counter/timer CTIMER3 */
|
||||
void isr_wdt(void); /**< Watch dog timer */
|
||||
void isr_adc(void); /**< ADC */
|
||||
void isr_dac(void); /**< DAC */
|
||||
void isr_xtal_ready(void); /**< High frequency crystal ready */
|
||||
void isr_flash(void); /**< Flash */
|
||||
void isr_spifi0(void); /**< SPI flash interface */
|
||||
void isr_sct0(void); /**< SCTimer/PWM */
|
||||
void isr_rng(void); /**< Random number generator */
|
||||
void isr_calib(void); /**< Calibration */
|
||||
void isr_ble_tx(void); /**< ble tx flag */
|
||||
void isr_ble_rx(void); /**< ble rx flag */
|
||||
void isr_ble_freq_hop(void); /**< ble frequency hop */
|
||||
void isr_bod(void); /**< Brown out detect */
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @brief In-System Programming configuration field
|
||||
*
|
||||
* After the interrupt vectors, at address 0x110 there's a ISP
|
||||
* (In-System Programming) configuration field. Define isp_configuration to
|
||||
* any | combination of the following `QN908X_ISP_*` values to change the ISP
|
||||
* allowed options.
|
||||
*/
|
||||
__attribute__((section(".vectors.100")))
|
||||
extern const uint32_t isp_configuration;
|
||||
|
||||
/**
|
||||
* @brief SMART write enabled to ISP
|
||||
*/
|
||||
#define QN908X_ISP_SMART_EN 0x80
|
||||
|
||||
/**
|
||||
* @brief SMART USB disabled to ISP
|
||||
*/
|
||||
#define QN908X_ISP_USB_DIS 0x20
|
||||
|
||||
/**
|
||||
* @brief SMART UART disabled to ISP
|
||||
*/
|
||||
#define QN908X_ISP_UART_DIS 0x08
|
||||
|
||||
/**
|
||||
* @brief SMART SPI disabled to ISP
|
||||
*/
|
||||
#define QN908X_ISP_SPI_DIS 0x02
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* VECTORS_QN908X_H */
|
9491
cpu/qn908x/include/vendor/QN908XC.h
vendored
Normal file
9491
cpu/qn908x/include/vendor/QN908XC.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
613
cpu/qn908x/include/vendor/QN908XC_features.h
vendored
Normal file
613
cpu/qn908x/include/vendor/QN908XC_features.h
vendored
Normal file
@ -0,0 +1,613 @@
|
||||
/*
|
||||
** ###################################################################
|
||||
** Version: rev. 1.0, 2017-03-27
|
||||
** Build: b170421
|
||||
**
|
||||
** Abstract:
|
||||
** Chip specific module features.
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2017 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2017-03-27)
|
||||
** Initial version.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
#ifndef _QN908XC_FEATURES_H_
|
||||
#define _QN908XC_FEATURES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* SOC module features */
|
||||
|
||||
/* @brief ACMP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ACMP_COUNT (2)
|
||||
/* @brief ADC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ADC_COUNT (1)
|
||||
/* @brief ADC12 availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ADC12_COUNT (0)
|
||||
/* @brief ADC16 availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ADC16_COUNT (0)
|
||||
/* @brief ADC_5HC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ADC_5HC_COUNT (0)
|
||||
/* @brief AES availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AES_COUNT (0)
|
||||
/* @brief HW AES availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AES_HW (1)
|
||||
/* @brief AFE availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AFE_COUNT (0)
|
||||
/* @brief AGC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AGC_COUNT (1)
|
||||
/* @brief AIPS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AIPS_COUNT (0)
|
||||
/* @brief AIPSTZ availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AIPSTZ_COUNT (0)
|
||||
/* @brief ANATOP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ANATOP_COUNT (0)
|
||||
/* @brief AOI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AOI_COUNT (0)
|
||||
/* @brief APBH availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_APBH_COUNT (0)
|
||||
/* @brief ASMC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ASMC_COUNT (0)
|
||||
/* @brief ASRC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ASRC_COUNT (0)
|
||||
/* @brief ASYNC_SYSCON availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT (0)
|
||||
/* @brief ATX availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ATX_COUNT (0)
|
||||
/* @brief AXBS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_AXBS_COUNT (0)
|
||||
/* @brief BCH availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_BCH_COUNT (0)
|
||||
/* @brief BLEDP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_BLEDP_COUNT (1)
|
||||
/* @brief BOD availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_BOD_COUNT (1)
|
||||
/* @brief CAAM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CAAM_COUNT (0)
|
||||
/* @brief CADC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CADC_COUNT (0)
|
||||
/* @brief CALIB availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CALIB_COUNT (1)
|
||||
/* @brief CAN availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CAN_COUNT (0)
|
||||
/* @brief CAU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CAU_COUNT (0)
|
||||
/* @brief CAU3 availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CAU3_COUNT (0)
|
||||
/* @brief CCM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CCM_COUNT (0)
|
||||
/* @brief CCM_ANALOG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CCM_ANALOG_COUNT (0)
|
||||
/* @brief CHRG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CHRG_COUNT (0)
|
||||
/* @brief CMP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CMP_COUNT (0)
|
||||
/* @brief CMT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CMT_COUNT (0)
|
||||
/* @brief CNC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CNC_COUNT (0)
|
||||
/* @brief COP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_COP_COUNT (0)
|
||||
/* @brief CRC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CRC_COUNT (1)
|
||||
/* @brief CS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CS_COUNT (1)
|
||||
/* @brief CSI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CSI_COUNT (0)
|
||||
/* @brief CT32B availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CT32B_COUNT (0)
|
||||
/* @brief CTI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CTI_COUNT (0)
|
||||
/* @brief CTIMER availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_CTIMER_COUNT (4)
|
||||
/* @brief DAC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DAC_COUNT (1)
|
||||
/* @brief DAC32 availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DAC32_COUNT (0)
|
||||
/* @brief DCDC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DCDC_COUNT (0)
|
||||
/* @brief DCP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DCP_COUNT (0)
|
||||
/* @brief DDR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DDR_COUNT (0)
|
||||
/* @brief DDRC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DDRC_COUNT (0)
|
||||
/* @brief DDRC_MP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DDRC_MP_COUNT (0)
|
||||
/* @brief DDR_PHY availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DDR_PHY_COUNT (0)
|
||||
/* @brief DMA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DMA_COUNT (1)
|
||||
/* @brief DMAMUX availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DMAMUX_COUNT (1)
|
||||
/* @brief DMIC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DMIC_COUNT (0)
|
||||
/* @brief DRY availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DRY_COUNT (0)
|
||||
/* @brief DSPI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_DSPI_COUNT (0)
|
||||
/* @brief ECSPI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ECSPI_COUNT (0)
|
||||
/* @brief EDMA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EDMA_COUNT (0)
|
||||
/* @brief EEPROM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EEPROM_COUNT (0)
|
||||
/* @brief EIM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EIM_COUNT (0)
|
||||
/* @brief EMC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EMC_COUNT (0)
|
||||
/* @brief EMVSIM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EMVSIM_COUNT (0)
|
||||
/* @brief ENC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ENC_COUNT (0)
|
||||
/* @brief ENET availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ENET_COUNT (0)
|
||||
/* @brief EPDC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EPDC_COUNT (0)
|
||||
/* @brief EPIT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EPIT_COUNT (0)
|
||||
/* @brief ESAI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ESAI_COUNT (0)
|
||||
/* @brief EWM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_EWM_COUNT (0)
|
||||
/* @brief FB availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FB_COUNT (0)
|
||||
/* @brief FGPIO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FGPIO_COUNT (0)
|
||||
/* @brief FLASH availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLASH_COUNT (1)
|
||||
/* @brief FLEXCAN availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLEXCAN_COUNT (0)
|
||||
/* @brief FLEXCOMM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLEXCOMM_COUNT (4)
|
||||
/* @brief FLEXIO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLEXIO_COUNT (0)
|
||||
/* @brief FLEXRAM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLEXRAM_COUNT (0)
|
||||
/* @brief FLEXSPI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FLEXSPI_COUNT (0)
|
||||
/* @brief FMC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FMC_COUNT (0)
|
||||
/* @brief FSKDT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FSKDT_COUNT (0)
|
||||
/* @brief FSP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FSP_COUNT (1)
|
||||
/* @brief FTFA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FTFA_COUNT (0)
|
||||
/* @brief FTFE availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FTFE_COUNT (0)
|
||||
/* @brief FTFL availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FTFL_COUNT (0)
|
||||
/* @brief FTM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FTM_COUNT (0)
|
||||
/* @brief FTMRA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FTMRA_COUNT (0)
|
||||
/* @brief FTMRE availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FTMRE_COUNT (0)
|
||||
/* @brief FTMRH availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_FTMRH_COUNT (0)
|
||||
/* @brief GINT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_GINT_COUNT (0)
|
||||
/* @brief GPC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_GPC_COUNT (0)
|
||||
/* @brief GPC_PGC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_GPC_PGC_COUNT (0)
|
||||
/* @brief GPIO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_GPIO_COUNT (2)
|
||||
/* @brief GPMI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_GPMI_COUNT (0)
|
||||
/* @brief GPT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_GPT_COUNT (0)
|
||||
/* @brief HSADC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_HSADC_COUNT (0)
|
||||
/* @brief I2C availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_I2C_COUNT (2)
|
||||
/* @brief I2S availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_I2S_COUNT (0)
|
||||
/* @brief ICS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ICS_COUNT (0)
|
||||
/* @brief IEE availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IEE_COUNT (0)
|
||||
/* @brief IEER availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IEER_COUNT (0)
|
||||
/* @brief IGPIO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IGPIO_COUNT (0)
|
||||
/* @brief II2C availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_II2C_COUNT (0)
|
||||
/* @brief INPUTMUX availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_INPUTMUX_COUNT (0)
|
||||
/* @brief INTMUX availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_INTMUX_COUNT (0)
|
||||
/* @brief IOCON availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IOCON_COUNT (0)
|
||||
/* @brief IOMUXC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IOMUXC_COUNT (0)
|
||||
/* @brief IOMUXC_GPR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IOMUXC_GPR_COUNT (0)
|
||||
/* @brief IOMUXC_LPSR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IOMUXC_LPSR_COUNT (0)
|
||||
/* @brief IOMUXC_LPSR_GPR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IOMUXC_LPSR_GPR_COUNT (0)
|
||||
/* @brief IOMUXC_SNVS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IOMUXC_SNVS_COUNT (0)
|
||||
/* @brief IPWM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IPWM_COUNT (0)
|
||||
/* @brief IRQ availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IRQ_COUNT (0)
|
||||
/* @brief IUART availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_IUART_COUNT (0)
|
||||
/* @brief KBI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_KBI_COUNT (0)
|
||||
/* @brief KPP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_KPP_COUNT (0)
|
||||
/* @brief L2CACHEC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_L2CACHEC_COUNT (0)
|
||||
/* @brief LCD availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LCD_COUNT (0)
|
||||
/* @brief LCDC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LCDC_COUNT (0)
|
||||
/* @brief LCDIF availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LCDIF_COUNT (0)
|
||||
/* @brief LDO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LDO_COUNT (0)
|
||||
/* @brief LLWU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LLWU_COUNT (0)
|
||||
/* @brief LMEM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LMEM_COUNT (0)
|
||||
/* @brief LPADC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPADC_COUNT (0)
|
||||
/* @brief LPCMP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPCMP_COUNT (0)
|
||||
/* @brief LPDAC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPDAC_COUNT (0)
|
||||
/* @brief LPI2C availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPI2C_COUNT (0)
|
||||
/* @brief LPIT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPIT_COUNT (0)
|
||||
/* @brief LPSCI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPSCI_COUNT (0)
|
||||
/* @brief LPSPI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPSPI_COUNT (0)
|
||||
/* @brief LPTMR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPTMR_COUNT (0)
|
||||
/* @brief LPTPM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPTPM_COUNT (0)
|
||||
/* @brief LPUART availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LPUART_COUNT (0)
|
||||
/* @brief LTC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_LTC_COUNT (0)
|
||||
/* @brief MAILBOX availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MAILBOX_COUNT (0)
|
||||
/* @brief MC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MC_COUNT (0)
|
||||
/* @brief MCG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MCG_COUNT (0)
|
||||
/* @brief MCGLITE availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MCGLITE_COUNT (0)
|
||||
/* @brief MCM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MCM_COUNT (0)
|
||||
/* @brief MIPI_CSI2 availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MIPI_CSI2_COUNT (0)
|
||||
/* @brief MIPI_DSI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MIPI_DSI_COUNT (0)
|
||||
/* @brief MIPI_DSI_HOST availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MIPI_DSI_HOST_COUNT (0)
|
||||
/* @brief MMAU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MMAU_COUNT (0)
|
||||
/* @brief MMCAU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MMCAU_COUNT (0)
|
||||
/* @brief MMDC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MMDC_COUNT (0)
|
||||
/* @brief MMDVSQ availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MMDVSQ_COUNT (0)
|
||||
/* @brief MPU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MPU_COUNT (0)
|
||||
/* @brief MRT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MRT_COUNT (0)
|
||||
/* @brief MSCAN availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MSCAN_COUNT (0)
|
||||
/* @brief MSCM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MSCM_COUNT (0)
|
||||
/* @brief MTB availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MTB_COUNT (0)
|
||||
/* @brief MTBDWT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MTBDWT_COUNT (0)
|
||||
/* @brief MU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_MU_COUNT (0)
|
||||
/* @brief NFC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_NFC_COUNT (0)
|
||||
/* @brief OCOTP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_OCOTP_COUNT (0)
|
||||
/* @brief OPAMP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_OPAMP_COUNT (0)
|
||||
/* @brief OSC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_OSC_COUNT (0)
|
||||
/* @brief OSC32 availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_OSC32_COUNT (0)
|
||||
/* @brief OTFAD availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_OTFAD_COUNT (0)
|
||||
/* @brief PCC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PCC_COUNT (0)
|
||||
/* @brief PCIE_PHY_CMN availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PCIE_PHY_CMN_COUNT (0)
|
||||
/* @brief PCIE_PHY_TRSV availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PCIE_PHY_TRSV_COUNT (0)
|
||||
/* @brief PDB availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PDB_COUNT (0)
|
||||
/* @brief PGA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PGA_COUNT (0)
|
||||
/* @brief PINT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PINT_COUNT (1)
|
||||
/* @brief PIT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PIT_COUNT (0)
|
||||
/* @brief PMC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PMC_COUNT (0)
|
||||
/* @brief PMU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PMU_COUNT (0)
|
||||
/* @brief PORT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PORT_COUNT (0)
|
||||
/* @brief PROP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PROP_COUNT (1)
|
||||
/* @brief PWM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PWM_COUNT (0)
|
||||
/* @brief PWT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PWT_COUNT (0)
|
||||
/* @brief PXP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_PXP_COUNT (0)
|
||||
/* @brief QDEC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_QDEC_COUNT (2)
|
||||
/* @brief QuadSPI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_QuadSPI_COUNT (0)
|
||||
/* @brief RCM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RCM_COUNT (0)
|
||||
/* @brief RDC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RDC_COUNT (0)
|
||||
/* @brief RDC_SEMAPHORE availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RDC_SEMAPHORE_COUNT (0)
|
||||
/* @brief RFSYS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RFSYS_COUNT (0)
|
||||
/* @brief RFVBAT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RFVBAT_COUNT (0)
|
||||
/* @brief RIT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RIT_COUNT (0)
|
||||
/* @brief RNG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RNG_COUNT (1)
|
||||
/* @brief RNGB availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RNGB_COUNT (0)
|
||||
/* @brief ROM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ROM_COUNT (0)
|
||||
/* @brief ROMC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ROMC_COUNT (0)
|
||||
/* @brief RSIM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RSIM_COUNT (0)
|
||||
/* @brief RTC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_RTC_COUNT (1)
|
||||
/* @brief SCG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SCG_COUNT (0)
|
||||
/* @brief SCI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SCI_COUNT (0)
|
||||
/* @brief SCT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SCT_COUNT (1)
|
||||
/* @brief SDHC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDHC_COUNT (0)
|
||||
/* @brief SDIF availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDIF_COUNT (0)
|
||||
/* @brief SDIO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDIO_COUNT (0)
|
||||
/* @brief SDMA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDMA_COUNT (0)
|
||||
/* @brief SDMAARM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDMAARM_COUNT (0)
|
||||
/* @brief SDMABP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDMABP_COUNT (0)
|
||||
/* @brief SDMACORE availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDMACORE_COUNT (0)
|
||||
/* @brief SDMCORE availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDMCORE_COUNT (0)
|
||||
/* @brief SDRAM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SDRAM_COUNT (0)
|
||||
/* @brief SEMA4 availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SEMA4_COUNT (0)
|
||||
/* @brief SEMA42 availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SEMA42_COUNT (0)
|
||||
/* @brief SHA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SHA_COUNT (0)
|
||||
/* @brief SIM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SIM_COUNT (0)
|
||||
/* @brief SIMDGO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SIMDGO_COUNT (0)
|
||||
/* @brief SJC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SJC_COUNT (0)
|
||||
/* @brief SLCD availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SLCD_COUNT (0)
|
||||
/* @brief SMARTCARD availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SMARTCARD_COUNT (0)
|
||||
/* @brief SMC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SMC_COUNT (0)
|
||||
/* @brief SNVS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SNVS_COUNT (0)
|
||||
/* @brief SPBA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SPBA_COUNT (0)
|
||||
/* @brief SPDIF availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SPDIF_COUNT (0)
|
||||
/* @brief SPI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SPI_COUNT (2)
|
||||
/* @brief SPIFI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SPIFI_COUNT (1)
|
||||
/* @brief SPM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SPM_COUNT (0)
|
||||
/* @brief SRC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SRC_COUNT (0)
|
||||
/* @brief SYSCON availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_SYSCON_COUNT (1)
|
||||
/* @brief TEMPMON availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TEMPMON_COUNT (0)
|
||||
/* @brief TMR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TMR_COUNT (0)
|
||||
/* @brief TPM availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TPM_COUNT (0)
|
||||
/* @brief TRGMUX availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TRGMUX_COUNT (0)
|
||||
/* @brief TRIAMP availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TRIAMP_COUNT (0)
|
||||
/* @brief TRNG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TRNG_COUNT (0)
|
||||
/* @brief TSC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TSC_COUNT (0)
|
||||
/* @brief TSI availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TSI_COUNT (0)
|
||||
/* @brief TSTMR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_TSTMR_COUNT (0)
|
||||
/* @brief UART availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_UART_COUNT (0)
|
||||
/* @brief USART availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USART_COUNT (2)
|
||||
/* @brief USB availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USB_COUNT (1)
|
||||
/* @brief USBHS availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBHS_COUNT (0)
|
||||
/* @brief USBDCD availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBDCD_COUNT (0)
|
||||
/* @brief USBFSH availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBFSH_COUNT (0)
|
||||
/* @brief USBHSD availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBHSD_COUNT (0)
|
||||
/* @brief USBHSDCD availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBHSDCD_COUNT (0)
|
||||
/* @brief USBHSH availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBHSH_COUNT (0)
|
||||
/* @brief USBNC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBNC_COUNT (0)
|
||||
/* @brief USBPHY availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USBPHY_COUNT (0)
|
||||
/* @brief USB_HSIC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USB_HSIC_COUNT (0)
|
||||
/* @brief USB_OTG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USB_OTG_COUNT (0)
|
||||
/* @brief USDHC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_USDHC_COUNT (0)
|
||||
/* @brief UTICK availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_UTICK_COUNT (0)
|
||||
/* @brief VIU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_VIU_COUNT (0)
|
||||
/* @brief VREF availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_VREF_COUNT (0)
|
||||
/* @brief VFIFO availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_VFIFO_COUNT (0)
|
||||
/* @brief WDOG availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_WDOG_COUNT (1)
|
||||
/* @brief WKPU availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_WKPU_COUNT (0)
|
||||
/* @brief WWDT availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_WWDT_COUNT (0)
|
||||
/* @brief XBAR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XBAR_COUNT (0)
|
||||
/* @brief XBARA availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XBARA_COUNT (0)
|
||||
/* @brief XBARB availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XBARB_COUNT (0)
|
||||
/* @brief XCVR availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XCVR_COUNT (0)
|
||||
/* @brief XRDC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XRDC_COUNT (0)
|
||||
/* @brief XTALOSC availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XTALOSC_COUNT (0)
|
||||
/* @brief XTALOSC24M availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_XTALOSC24M_COUNT (0)
|
||||
/* @brief ZLL availability on the SoC. */
|
||||
#define FSL_FEATURE_SOC_ZLL_COUNT (0)
|
||||
|
||||
/* CRC module features */
|
||||
|
||||
/* @brief CRC for boot info */
|
||||
#define FSL_FEATURE_CRC_BASE_ADDR (0x210B0700)
|
||||
/* @brief Boot version */
|
||||
#define FSL_FEATURE_CRC_READ_BASE_ADDR (0x31000000)
|
||||
/* @brief Boot feature */
|
||||
#define FSL_FEATURE_CRC_LOCK_BIT_STORE_ADDR (0x2107F800)
|
||||
|
||||
/* CTIMER module features */
|
||||
|
||||
/* @brief Has CTIMER IR_CR3INT (register bit IR[CR3INT]). */
|
||||
#define FSL_FEATURE_CTIMER_HAS_IR_CR3INT (0)
|
||||
/* @brief Has CTIMER CCR_CAP3 (register bits CCR[CAP3RE][CAP3FE][CAP3I]). */
|
||||
#define FSL_FEATURE_CTIMER_HAS_CCR_CAP3 (0)
|
||||
|
||||
/* DMA module features */
|
||||
|
||||
/* @brief Number of channels */
|
||||
#define FSL_FEATURE_DMA_NUMBER_OF_CHANNELS (20)
|
||||
|
||||
/* FLASH module features */
|
||||
|
||||
/* @brief Flash size in bytes */
|
||||
#define FSL_FEATURE_FLASH_SIZE_BYTES (524288U)
|
||||
/* @brief Flash page size in bytes */
|
||||
#define FSL_FEATURE_FLASH_PAGE_SIZE_BYTES (2048U)
|
||||
/* @brief Flash block write unit in bytes */
|
||||
#define FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE (0x4U)
|
||||
/* @brief P-Flash block count */
|
||||
#define FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT (2)
|
||||
/* @brief P-Flash block size */
|
||||
#define FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE (0x40000U)
|
||||
/* @brief Flash base address */
|
||||
#define FSL_FEATURE_FLASH_BASE_ADDR (0x21000000U)
|
||||
/* @brief Flash read base address */
|
||||
#define FSL_FEATURE_FLASH_READ_BASE_ADDR (0x31000000U)
|
||||
/* @brief Flash lock bit address */
|
||||
#define FSL_FEATURE_FLASH_LOCK_BIT_STORE_ADDR (0x2107F800U)
|
||||
/* @brief Flash information page address */
|
||||
#define FSL_FEATURE_FLASH_INFO_BASE_ADDR (0x210B0000U)
|
||||
/* @brief CRC for boot info (4 Bytes) */
|
||||
#define FSL_FEATURE_FLASH_ADDR_OF_BOOT_CRC (0x210B0700U)
|
||||
/* @brief Boot version (4 Bytes) */
|
||||
#define FSL_FEATURE_FLASH_ADDR_OF_BOOT_VERSION (0x210B0704U)
|
||||
/* @brief Boot feature (4 Bytes) */
|
||||
#define FSL_FEATURE_FLASH_ADDR_OF_BOOT_FEATURE (0x210B0708U)
|
||||
/* @brief Temperature sensor calibration value (4 Bytes) */
|
||||
#define FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL (0x210B07F0U)
|
||||
/* @brief Bandgap voltage for ADC reference calibration (4 Bytes) */
|
||||
#define FSL_FEATURE_FLASH_ADDR_OF_BANDGAP_VOL (0x210B07F4U)
|
||||
/* @brief Main Bandgap voltage calibration (4 Bytes) */
|
||||
#define FSL_FEATURE_FLASH_ADDR_OF_MAINBANDGAP_VOL (0x210B070CU)
|
||||
/* @brief Vendor bluetooth address(MAC) (6 Bytes) */
|
||||
#define FSL_FEATURE_FLASH_ADDR_OF_VENDOR_BD_ADDR (0x210B07FAU)
|
||||
|
||||
/* PINT module features */
|
||||
|
||||
/* @brief Number of connected outputs */
|
||||
#define FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS (4)
|
||||
|
||||
/* RTC module features */
|
||||
|
||||
/* @brief RTC has Free Running Counter */
|
||||
#define FSL_FEATURE_RTC_HAS_FRC (1)
|
||||
|
||||
/* SCT module features */
|
||||
|
||||
/* @brief Number of events */
|
||||
#define FSL_FEATURE_SCT_NUMBER_OF_EVENTS (10)
|
||||
/* @brief Number of states */
|
||||
#define FSL_FEATURE_SCT_NUMBER_OF_STATES (10)
|
||||
/* @brief Number of match capture */
|
||||
#define FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE (10)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _QN908XC_FEATURES_H_ */
|
||||
|
356
cpu/qn908x/include/vendor/drivers/fsl_clock.h
vendored
Normal file
356
cpu/qn908x/include/vendor/drivers/fsl_clock.h
vendored
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright (c) 2016 - 2017 , NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_CLOCK_H_
|
||||
#define _FSL_CLOCK_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*! @addtogroup clock */
|
||||
/*! @{ */
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
*****************************************************************************/
|
||||
|
||||
/* To calculate flexcomm clock for baud rate correction */
|
||||
#define FLEXCOMM_CLK(srcClock_Hz, baudrate_Bps) ((((srcClock_Hz) / 8) / baudrate_Bps) * baudrate_Bps * 8)
|
||||
|
||||
/*! @brief Configure whether driver controls clock
|
||||
*
|
||||
* When set to 0, peripheral drivers will enable clock in initialize function
|
||||
* and disable clock in de-initialize function. When set to 1, peripheral
|
||||
* driver will not control the clock, application could contol the clock out of
|
||||
* the driver.
|
||||
*
|
||||
* @note All drivers share this feature switcher. If it is set to 1, application
|
||||
* should handle clock enable and disable for all drivers.
|
||||
*/
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
|
||||
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
|
||||
#endif
|
||||
|
||||
/*! @brief Clock ip name array for LPUART. */
|
||||
#define LPUART_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Flexcomm0, kCLOCK_Flexcomm1 \
|
||||
}
|
||||
/*! @brief Clock ip name array for BI2C. */
|
||||
#define BI2C_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Flexcomm1, kCLOCK_Flexcomm2 \
|
||||
}
|
||||
/*! @brief Clock ip name array for FLEXCOMM. */
|
||||
#define FLEXCOMM_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Flexcomm0, kCLOCK_Flexcomm1, kCLOCK_Flexcomm2, kCLOCK_Flexcomm3 \
|
||||
}
|
||||
/*! @brief Clock ip name array for CRC. */
|
||||
#define CRC_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Crc \
|
||||
}
|
||||
/*! @brief Clock ip name array for CTIMER. */
|
||||
#define CTIMER_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Ctimer0, kCLOCK_Ctimer1, kCLOCK_Ctimer2, kCLOCK_Ctimer3 \
|
||||
}
|
||||
/*! @brief Clock ip name array for SCTimer. */
|
||||
#define SCT_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Sct0 \
|
||||
}
|
||||
/*! @brief Clock ip name array for GPIO. */
|
||||
#define GPIO_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Gpio \
|
||||
}
|
||||
/*! @brief Clock ip name array for Calibration. */
|
||||
#define CAL_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Cal \
|
||||
}
|
||||
/*! @brief Clock ip name array for USBD. */
|
||||
#define USBD_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Usbd0 \
|
||||
}
|
||||
/*! @brief Clock ip name array for WDT. */
|
||||
#define WDT_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Wdt \
|
||||
}
|
||||
/*! @brief Clock ip name array for BIV(including RTC and SYSCON clock). Enabled as default */
|
||||
#define BIV_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Biv \
|
||||
}
|
||||
/*! @brief Clock ip name array for ADC. */
|
||||
#define ADC_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Adc \
|
||||
}
|
||||
/*! @brief Clock ip name array for DAC. */
|
||||
#define DAC_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Dac \
|
||||
}
|
||||
/*! @brief Clock ip name array for CS. */
|
||||
#define CS_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Cs \
|
||||
}
|
||||
/*! @brief Clock ip name array for FSP. */
|
||||
#define FSP_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Fsp \
|
||||
}
|
||||
/*! @brief Clock ip name array for DMA. */
|
||||
#define DMA_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Dma \
|
||||
}
|
||||
/*! @brief Clock ip name array for QDEC. */
|
||||
#define QDEC_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Qdec0, kCLOCK_Qdec1 \
|
||||
}
|
||||
/*! @brief Clock ip name array for DP. */
|
||||
#define DP_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Dp \
|
||||
}
|
||||
/*! @brief Clock ip name array for SPIFI. */
|
||||
#define SPIFI_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Spifi \
|
||||
}
|
||||
/*! @brief Clock ip name array for BLE. */
|
||||
#define BLE_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Ble \
|
||||
}
|
||||
/*! @brief Clock ip name array for PROP. */
|
||||
#define PROP_CLOCKS \
|
||||
{ \
|
||||
kCLOCK_Prop \
|
||||
}
|
||||
|
||||
/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
|
||||
/*------------------------------------------------------------------------------
|
||||
clock_ip_name_t definition:
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
|
||||
typedef enum _clock_ip_name
|
||||
{
|
||||
kCLOCK_IpInvalid = 33U,
|
||||
kCLOCK_Flexcomm0 = 0U,
|
||||
kCLOCK_Flexcomm1 = 1U,
|
||||
kCLOCK_Flexcomm2 = 2U,
|
||||
kCLOCK_Flexcomm3 = 3U,
|
||||
kCLOCK_Ctimer0 = 4U,
|
||||
kCLOCK_Ctimer1 = 5U,
|
||||
kCLOCK_Ctimer2 = 6U,
|
||||
kCLOCK_Ctimer3 = 7U,
|
||||
kCLOCK_Sct0 = 8U,
|
||||
kCLOCK_Wdt = 9U,
|
||||
kCLOCK_Usbd0 = 10U,
|
||||
kCLOCK_Gpio = 11U,
|
||||
kCLOCK_Biv = 12U,
|
||||
kCLOCK_Adc = 13U,
|
||||
kCLOCK_Dac = 14U,
|
||||
kCLOCK_Cs = 15U,
|
||||
kCLOCK_Crc = 16U,
|
||||
kCLOCK_Fsp = 16U,
|
||||
kCLOCK_Dma = 17U,
|
||||
kCLOCK_Pint = 17U,
|
||||
kCLOCK_InputMux = 17U,
|
||||
kCLOCK_Qdec0 = 19U,
|
||||
kCLOCK_Qdec1 = 20U,
|
||||
kCLOCK_Dp = 21U,
|
||||
kCLOCK_Spifi = 22U,
|
||||
kCLOCK_Cal = 25U,
|
||||
kCLOCK_Ble = 27U,
|
||||
kCLOCK_Prop = 29U,
|
||||
} clock_ip_name_t;
|
||||
|
||||
/*! @brief Clock name used to get clock frequency. */
|
||||
typedef enum _clock_name
|
||||
{
|
||||
kCLOCK_CoreSysClk, /*!< Core/system clock (aka MAIN_CLK) */
|
||||
kCLOCK_BusClk, /*!< Bus clock (AHB clock) */
|
||||
kCLOCK_ApbClk, /*!< Apb clock */
|
||||
kCLOCK_WdtClk, /*!< Wdt clock*/
|
||||
kCLOCK_FroHf, /*!< FRO */
|
||||
kCLOCK_Xin, /*!< 16/32 MHz XIN */
|
||||
kCLOCK_32KClk /*!< 32K clock */
|
||||
} clock_name_t;
|
||||
|
||||
/*! @brief Clock Mux Switches
|
||||
*
|
||||
* [4 bits for choice] [8 bits mux ID]
|
||||
*/
|
||||
|
||||
#define MUX_A(m, choice) (((m) << 0) | ((choice + 1) << 8))
|
||||
|
||||
#define CM_32KCLKSEL 0
|
||||
#define CM_SYSCLKSEL 1
|
||||
#define CM_WDTCLKSEL 2
|
||||
#define CM_BLECLKSEL 3
|
||||
#define CM_XTALCLKSEL 4
|
||||
|
||||
typedef enum _clock_attach_id
|
||||
{
|
||||
kXTAL32K_to_32K_CLK = MUX_A(CM_32KCLKSEL, 0), /*!< XTAL 32K clock */
|
||||
kRCO32K_to_32K_CLK = MUX_A(CM_32KCLKSEL, 1), /*!< RCO 32KHz clock */
|
||||
|
||||
kOSC32M_to_SYS_CLK = MUX_A(CM_SYSCLKSEL, 0), /*!< OSC 32MHz clock */
|
||||
kXTAL_to_SYS_CLK = MUX_A(CM_SYSCLKSEL, 1), /*!< XTAL 16MHz/32MHz clock */
|
||||
k32K_to_SYS_CLK = MUX_A(CM_SYSCLKSEL, 2), /*!< 32KHz clock */
|
||||
|
||||
k32K_to_WDT_CLK = MUX_A(CM_WDTCLKSEL, 0), /*!< 32KHz clock */
|
||||
kAPB_to_WDT_CLK = MUX_A(CM_WDTCLKSEL, 1), /*!< APB clock */
|
||||
|
||||
k8M_to_BLE_CLK = MUX_A(CM_BLECLKSEL, 0), /*!< 8M CLOCK */
|
||||
k16M_to_BLE_CLK = MUX_A(CM_BLECLKSEL, 1), /*!< 16M CLOCK */
|
||||
|
||||
k16M_to_XTAL_CLK = MUX_A(CM_XTALCLKSEL, 0), /*!< 16M XTAL */
|
||||
k32M_to_XTAL_CLK = MUX_A(CM_XTALCLKSEL, 1), /*!< 32M XTAL */
|
||||
kNONE_to_NONE = 0x80000000U,
|
||||
} clock_attach_id_t;
|
||||
|
||||
/* Clock dividers */
|
||||
typedef enum _clock_div_name
|
||||
{
|
||||
kCLOCK_DivXtalClk,
|
||||
kCLOCK_DivOsc32mClk,
|
||||
kCLOCK_DivAhbClk,
|
||||
kCLOCK_DivApbClk,
|
||||
kCLOCK_DivFrg0,
|
||||
kCLOCK_DivFrg1,
|
||||
kCLOCK_DivClkOut
|
||||
} clock_div_name_t;
|
||||
|
||||
/*! @brief USB clock source definition. */
|
||||
typedef enum _clock_usb_src
|
||||
{
|
||||
kCLOCK_UsbSrcFro =
|
||||
(uint32_t)kCLOCK_FroHf, /*!< Fake USB src clock, temporary fix until USB clock control is done properly */
|
||||
} clock_usb_src_t;
|
||||
|
||||
/* Clock clock out source */
|
||||
typedef enum _clock_clkout_src
|
||||
{
|
||||
kCLOCK_Clkout_32K = SYSCON_CLK_CTRL_CLK_32K_OE_MASK, /*!< 32KHz clock out */
|
||||
kCLOCK_Clkout_XTAL = SYSCON_CLK_CTRL_CLK_XTAL_OE_MASK /*!< XTAL clock out */
|
||||
} clock_clkout_src_t;
|
||||
|
||||
/* Clock clock out pin */
|
||||
typedef enum _clock_clkout_pin
|
||||
{
|
||||
kCLOCK_Clkout_PA04_32K = SYSCON_PIO_WAKEUP_EN1_PA04_32K_OE_MASK,
|
||||
kCLOCK_Clkout_PA05_XTAL = SYSCON_PIO_WAKEUP_EN1_PA05_XTAL_OE_MASK,
|
||||
kCLOCK_Clkout_PA10_32K = SYSCON_PIO_WAKEUP_EN1_PA10_32K_OE_MASK,
|
||||
kCLOCK_Clkout_PA11_XTAL = SYSCON_PIO_WAKEUP_EN1_PA11_XTAL_OE_MASK,
|
||||
kCLOCK_Clkout_PA18_32K = SYSCON_PIO_WAKEUP_EN1_PA18_32K_OE_MASK,
|
||||
kCLOCK_Clkout_PA19_XTAL = SYSCON_PIO_WAKEUP_EN1_PA19_XTAL_OE_MASK,
|
||||
kCLOCK_Clkout_PA24_32K = SYSCON_PIO_WAKEUP_EN1_PA24_32K_OE_MASK,
|
||||
kCLOCK_Clkout_PA25_XTAL = SYSCON_PIO_WAKEUP_EN1_PA25_XTAL_OE_MASK
|
||||
} clock_clkout_pin_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @brief Enable the specified peripheral clock
|
||||
*/
|
||||
void CLOCK_EnableClock(clock_ip_name_t clk);
|
||||
|
||||
/*!
|
||||
* @brief Disable the specified peripheral clock
|
||||
*/
|
||||
void CLOCK_DisableClock(clock_ip_name_t clk);
|
||||
|
||||
/*!
|
||||
* @brief Configure the clock selection muxes.
|
||||
*
|
||||
* @param connection: Clock to be configured.
|
||||
*/
|
||||
void CLOCK_AttachClk(clock_attach_id_t connection);
|
||||
|
||||
/*!
|
||||
* @brief Setup peripheral clock dividers.
|
||||
*
|
||||
* @param div_name: Clock divider name
|
||||
* @param divided_by_value: Value to be divided
|
||||
*/
|
||||
void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value);
|
||||
|
||||
/*!
|
||||
* @brief Get frequency of selected clock
|
||||
*
|
||||
* @return Frequency of selected clock
|
||||
*/
|
||||
uint32_t CLOCK_GetFreq(clock_name_t clk);
|
||||
|
||||
/*!
|
||||
* @brief Disable USB FS clock.
|
||||
*
|
||||
* Disable USB FS clock.
|
||||
*/
|
||||
static inline void CLOCK_DisableUsbfs0Clock(void)
|
||||
{
|
||||
CLOCK_DisableClock(kCLOCK_Usbd0);
|
||||
}
|
||||
|
||||
bool CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src, uint32_t freq);
|
||||
/*!
|
||||
* @brief Enable/Disable clock out source.
|
||||
*
|
||||
* @param mask Mask value for the clock source, See "clock_clkout_src_t".
|
||||
* @param enable Enable/Disable the clock out source.
|
||||
*/
|
||||
void CLOCK_EnableClkoutSource(uint32_t mask, bool enable);
|
||||
/*!
|
||||
* @brief Enable/Disable clock out pin.
|
||||
*
|
||||
* @param mask Mask value for the clock source, See "clock_clkout_pin_t".
|
||||
* @param enable Enable/Disable the clock out pin.
|
||||
*/
|
||||
void CLOCK_EnableClkoutPin(uint32_t mask, bool enable);
|
||||
|
||||
/*! @brief Return Input frequency for the Fractional baud rate generator
|
||||
* @return Input Frequency for FRG
|
||||
*/
|
||||
uint32_t CLOCK_GetFRGInputClock(void);
|
||||
|
||||
/*!
|
||||
* @brief Set output of the Fractional baud rate generator
|
||||
*
|
||||
* @param div_name: Clock divider name: kCLOCK_DivFrg0 and kCLOCK_DivFrg1
|
||||
* @param freq: Desired output frequency
|
||||
* @return Error Code 0 - fail 1 - success
|
||||
*/
|
||||
uint32_t CLOCK_SetFRGClock(clock_div_name_t div_name, uint32_t freq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_CLOCK_H_ */
|
259
cpu/qn908x/include/vendor/drivers/fsl_iocon.h
vendored
Normal file
259
cpu/qn908x/include/vendor/drivers/fsl_iocon.h
vendored
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_IOCON_H_
|
||||
#define _FSL_IOCON_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup qn_iocon
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#define IOCON SYSCON
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief IOCON driver version 2.0.0. */
|
||||
#define LPC_IOCON_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* @brief Array of IOCON pin definitions passed to IOCON_SetPinMuxing() must be in this format
|
||||
*/
|
||||
typedef struct _iocon_group
|
||||
{
|
||||
uint32_t port : 8; /* Pin port */
|
||||
uint32_t pin : 8; /* Pin number */
|
||||
uint32_t modefunc : 16; /* Function and mode */
|
||||
} iocon_group_t;
|
||||
|
||||
/**
|
||||
* @brief IOCON function, mode and drive selection definitions
|
||||
* @note See the User Manual for specific drive levels, modes and functions supported by the various pins.
|
||||
*/
|
||||
#define IOCON_FUNC0 0x0U /*!< Selects pin function 0 */
|
||||
#define IOCON_FUNC1 0x1U /*!< Selects pin function 1 */
|
||||
#define IOCON_FUNC2 0x2U /*!< Selects pin function 2 */
|
||||
#define IOCON_FUNC3 0x3U /*!< Selects pin function 3 */
|
||||
#define IOCON_FUNC4 0x4U /*!< Selects pin function 4 */
|
||||
#define IOCON_FUNC5 0x5U /*!< Selects pin function 5 */
|
||||
#define IOCON_FUNC6 0x6U /*!< Selects pin function 6 */
|
||||
#define IOCON_FUNC7 0x7U /*!< Selects pin function 7 */
|
||||
|
||||
#define IOCON_MODE_HIGHZ (0x0U << 4U) /*!< Selects High-Z function */
|
||||
#define IOCON_MODE_PULLDOWN (0x1U << 4U) /*!< Selects pull-down function */
|
||||
#define IOCON_MODE_PULLUP (0x2U << 4U) /*!< Selects pull-up function */
|
||||
|
||||
#define IOCON_DRIVE_LOW (0x0U << 6U) /*!< Enable low drive strength */
|
||||
#define IOCON_DRIVE_HIGH (0x1U << 6U) /*!< Enable high drive strength */
|
||||
#define IOCON_DRIVE_EXTRA (0x1U << 7U) /*!< Enable extra drive, only valid for PA06/PA11/PA19/PA26/PA27 */
|
||||
|
||||
/**
|
||||
* @brief Pull mode
|
||||
*/
|
||||
typedef enum _iocon_pull_mode
|
||||
{
|
||||
kIOCON_HighZ = 0U, /*!< High Z */
|
||||
kIOCON_PullDown, /*!< Pull down */
|
||||
kIOCON_PullUp /*!< Pull up */
|
||||
} iocon_pull_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Drive strength
|
||||
*/
|
||||
typedef enum _iocon_drive_strength
|
||||
{
|
||||
kIOCON_LowDriveStrength = 0U, /*!< Low-drive */
|
||||
kIOCON_HighDriveStrength, /*!< High-drive */
|
||||
kIOCON_LowDriveWithExtraStrength, /*!< Low-drive with extra */
|
||||
kIOCON_HighDriveWithExtraStrength, /*!< High-drive with extra */
|
||||
} iocon_drive_strength_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Sets I/O control pin mux
|
||||
* @param base The base of SYSCON peripheral on the chip
|
||||
* @param port GPIO port to mux (value from 0 ~ 1)
|
||||
* @param pin GPIO pin to mux (value from 0 ~ 31)
|
||||
* @param modeFunc OR'ed values of type IOCON_*
|
||||
* @return Nothing
|
||||
*/
|
||||
__STATIC_INLINE void IOCON_PinMuxSet(SYSCON_Type *base, uint8_t port, uint8_t pin, uint32_t modeFunc)
|
||||
{
|
||||
assert(((port == 0U) && (pin <= 31U)) || ((port == 1U) && (pin <= 2U)));
|
||||
|
||||
uint8_t pinMuxIndex = (pin >> 3U);
|
||||
uint8_t pinMuxLocation = ((pin & 0x7U) << 2U);
|
||||
uint8_t pinPullIndex = (pin >> 4U);
|
||||
uint8_t pinPullLocation = ((pin & 0xFU) << 1U);
|
||||
|
||||
if (port == 0U)
|
||||
{
|
||||
base->PIO_FUNC_CFG[pinMuxIndex] &= ~(0x07U << pinMuxLocation);
|
||||
base->PIO_FUNC_CFG[pinMuxIndex] |= (modeFunc & 0x07U) << pinMuxLocation;
|
||||
|
||||
pinPullIndex = (pin >> 4U);
|
||||
}
|
||||
else if (port == 1U)
|
||||
{
|
||||
pinPullIndex = 2U;
|
||||
|
||||
if ((pin == 0U) || (pin == 1U))
|
||||
{
|
||||
base->PIO_CFG_MISC &= ~(1U << pin);
|
||||
base->PIO_CFG_MISC |= (modeFunc & 0x01U) << pin;
|
||||
}
|
||||
else if (pin == 2U)
|
||||
{
|
||||
base->PIO_CFG_MISC &= ~(1U << 16U);
|
||||
base->PIO_CFG_MISC |= (modeFunc & 0x01U) << 16U;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base->PIO_PULL_CFG[pinPullIndex] &= ~(0x03U << pinPullLocation);
|
||||
base->PIO_PULL_CFG[pinPullIndex] |= ((modeFunc >> 4U) & 0x03U) << pinPullLocation;
|
||||
|
||||
base->PIO_DRV_CFG[port] &= ~(1U << pin);
|
||||
base->PIO_DRV_CFG[port] |= (((modeFunc >> 6U) & 0x01U)) << pin;
|
||||
|
||||
if ((port == 0U) && ((pin == 6U) || (pin == 11U) || (pin == 19U) || (pin == 26U) || (pin == 27U)))
|
||||
{
|
||||
base->PIO_DRV_CFG[2U] &= ~(1U << pin);
|
||||
base->PIO_DRV_CFG[2U] |= (((modeFunc >> 7U) & 0x01U)) << pin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set all I/O control pin muxing
|
||||
* @param base The base of SYSCON peripheral on the chip
|
||||
* @param pinArray Pointer to array of pin mux selections
|
||||
* @param arrayLength Number of entries in pinArray
|
||||
* @return Nothing
|
||||
*/
|
||||
__STATIC_INLINE void IOCON_SetPinMuxing(SYSCON_Type *base, const iocon_group_t *pinArray, uint32_t arrayLength)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0U; i < arrayLength; i++)
|
||||
{
|
||||
IOCON_PinMuxSet(base, pinArray[i].port, pinArray[i].pin, pinArray[i].modefunc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets I/O control pin function
|
||||
* @param base The base of SYSCON peripheral on the chip
|
||||
* @param port GPIO port (value from 0 ~ 1)
|
||||
* @param pin GPIO pin (value from 0 ~ 31)
|
||||
* @param func Pin fucntion (value from 0 ~ 7)
|
||||
* @return Nothing
|
||||
*/
|
||||
__STATIC_INLINE void IOCON_FuncSet(SYSCON_Type *base, uint8_t port, uint8_t pin, uint8_t func)
|
||||
{
|
||||
assert(((port == 0U) && (pin <= 31U)) || ((port == 1U) && (pin <= 2U)));
|
||||
uint8_t index = (pin >> 3);
|
||||
uint8_t pinLocation = ((pin & 0x7U) << 2U);
|
||||
|
||||
if (port == 0U)
|
||||
{
|
||||
base->PIO_FUNC_CFG[index] &= ~(0x07U << pinLocation);
|
||||
base->PIO_FUNC_CFG[index] |= (func & 0x07U) << pinLocation;
|
||||
}
|
||||
else if (port == 1U)
|
||||
{
|
||||
if ((pin == 0U) || (pin == 1U))
|
||||
{
|
||||
base->PIO_CFG_MISC &= ~(1U << pin);
|
||||
base->PIO_CFG_MISC |= (func & 0x01U) << pin;
|
||||
}
|
||||
else if (pin == 2U)
|
||||
{
|
||||
base->PIO_CFG_MISC &= ~(1U << 16U);
|
||||
base->PIO_CFG_MISC |= (func & 0x01U) << 16U;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets I/O control drive capability
|
||||
* @param base The base of SYSCON peripheral on the chip
|
||||
* @param port GPIO port (value from 0 ~ 1)
|
||||
* @param pin GPIO pin (value from 0 ~ 31)
|
||||
* @param strength Drive strength (Extra option is only valid for PA06/PA11/PA19/PA26/PA27)
|
||||
* - kIOCON_LowDriveStrength = 0U - Low-drive strength is configured.
|
||||
* - kIOCON_HighDriveStrength = 1U - High-drive strength is configured
|
||||
* - kIOCON_LowDriveWithExtraStrength = 2U - Low-drive with extra strength is configured
|
||||
* - kIOCON_HighDriveWithExtraStrength = 3U - High-drive with extra strength is configured
|
||||
* @return Nothing
|
||||
*/
|
||||
__STATIC_INLINE void IOCON_DriveSet(SYSCON_Type *base, uint8_t port, uint8_t pin, uint8_t strength)
|
||||
{
|
||||
assert(((port == 0U) && (pin <= 31U)) || ((port == 1U) && (pin <= 2U)));
|
||||
base->PIO_DRV_CFG[port] &= ~(1U << pin);
|
||||
base->PIO_DRV_CFG[port] |= (strength & 0x01U) << pin;
|
||||
if ((port == 0U) && ((pin == 6U) || (pin == 11U) || (pin == 19U) || (pin == 26U) || (pin == 27U)))
|
||||
{
|
||||
base->PIO_DRV_CFG[2U] &= ~(1U << pin);
|
||||
base->PIO_DRV_CFG[2U] |= (((strength >> 1U) & 0x01U)) << pin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets I/O control pull configuration
|
||||
* @param base The base of SYSCON peripheral on the chip
|
||||
* @param port GPIO port (value from 0 ~ 1)
|
||||
* @param pin GPIO pin (value from 0 ~ 31)
|
||||
* @param pullMode Pull mode
|
||||
* - kIOCON_HighZ = 0U - High Z is configured.
|
||||
* - kIOCON_PullDown = 1U - Pull-down is configured
|
||||
* - kIOCON_PullUp = 2U - Pull-up is configured
|
||||
* @return Nothing
|
||||
*/
|
||||
__STATIC_INLINE void IOCON_PullSet(SYSCON_Type *base, uint8_t port, uint8_t pin, uint8_t pullMode)
|
||||
{
|
||||
assert(((port == 0U) && (pin <= 31U)) || ((port == 1U) && (pin <= 2U)));
|
||||
uint8_t index = (port == 1U) ? 2U : (pin >> 4U);
|
||||
uint8_t pinLocation = ((pin & 0xFU) << 1U);
|
||||
|
||||
base->PIO_PULL_CFG[index] &= ~(0x03U << pinLocation);
|
||||
base->PIO_PULL_CFG[index] |= (uint32_t)pullMode << pinLocation;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FSL_IOCON_H_ */
|
52
cpu/qn908x/include/vendor/fsl_common.h
vendored
Normal file
52
cpu/qn908x/include/vendor/fsl_common.h
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 Wrapper header for SDK drivers.
|
||||
*
|
||||
* Vendor SDK drivers include "fsl_common.h" with many definitions and extra
|
||||
* dependencies on more headers that are not used in the RIOT-OS port. This
|
||||
* header is a wrapper intended to keep the SDK headers unchanged and provide
|
||||
* the essential definitions needed by other SDK modules.
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*/
|
||||
|
||||
#ifndef FSL_COMMON_H
|
||||
#define FSL_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "irq.h"
|
||||
#include "vectors_cortexm.h"
|
||||
|
||||
#include "QN908XC.h"
|
||||
#include "QN908XC_features.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* RIOT-OS equivalent functions. */
|
||||
#define DisableGlobalIRQ irq_disable
|
||||
#define EnableGlobalIRQ irq_restore
|
||||
|
||||
#define __Vectors cortex_vector_base
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FSL_COMMON_H */
|
||||
/** @} */
|
97
cpu/qn908x/include/vendor/system_QN908XC.h
vendored
Normal file
97
cpu/qn908x/include/vendor/system_QN908XC.h
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
** ###################################################################
|
||||
** Processors: QN9080C
|
||||
** QN9083C
|
||||
**
|
||||
** Compilers: Keil ARM C/C++ Compiler
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
** MCUXpresso Compiler
|
||||
**
|
||||
** Reference manual: QN908X User manual Rev.1.0 21 Mar 2017
|
||||
** Version: rev. 1.0, 2017-03-27
|
||||
** Build: b170328
|
||||
**
|
||||
** Abstract:
|
||||
** Provides a system configuration function and a global variable that
|
||||
** contains the system frequency. It configures the device and initializes
|
||||
** the oscillator (PLL) that is part of the microcontroller device.
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2017 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2017-03-27)
|
||||
** Initial version.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file QN908XC
|
||||
* @version 1.0
|
||||
* @date 2017-03-27
|
||||
* @brief Device specific configuration file for QN908XC (header file)
|
||||
*
|
||||
* Provides a system configuration function and a global variable that contains
|
||||
* the system frequency. It configures the device and initializes the oscillator
|
||||
* (PLL) that is part of the microcontroller device.
|
||||
*/
|
||||
|
||||
#ifndef _SYSTEM_QN908XC_H_
|
||||
#define _SYSTEM_QN908XC_H_ /**< Symbol preventing repeated inclusion */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CLK_XTAL_16MHZ 16000000u /* 16 MHz XTAL clock */
|
||||
#define CLK_XTAL_32MHZ 32000000u /* 32 MHz XTAL clock */
|
||||
#define CLK_OSC_32MHZ 32000000u /* OSC 32 MHz */
|
||||
#define CLK_XTAL_32KHZ 32768u /* XTAL 32 kHz */
|
||||
#define CLK_RCO_32KHZ 32000u /* RCO 32 kHz */
|
||||
|
||||
#define DEFAULT_SYSTEM_CLOCK 16000000u /* Default System clock value */
|
||||
|
||||
/**
|
||||
* @brief System clock frequency (core clock)
|
||||
*
|
||||
* The system clock frequency supplied to the SysTick timer and the processor
|
||||
* core clock. This variable can be used by the user application to setup the
|
||||
* SysTick timer or configure other parameters. It may also be used by debugger to
|
||||
* query the frequency of the debug timer or configure the trace clock speed
|
||||
* SystemCoreClock is initialized with a correct predefined value.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
*
|
||||
* Typically this function configures the oscillator (PLL) that is part of the
|
||||
* microcontroller device. For systems with variable clock speed it also updates
|
||||
* the variable SystemCoreClock. SystemInit is called from startup_device file.
|
||||
*/
|
||||
void SystemInit (void);
|
||||
|
||||
/**
|
||||
* @brief Updates the SystemCoreClock variable.
|
||||
*
|
||||
* It must be called whenever the core clock is changed during program
|
||||
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
|
||||
* the current core clock.
|
||||
*/
|
||||
void SystemCoreClockUpdate (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYSTEM_QN908XC_H_ */
|
129
cpu/qn908x/isr_qn908x.c
Normal file
129
cpu/qn908x/isr_qn908x.c
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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 Default interrupt service routine definitions for NXP QN908x
|
||||
*
|
||||
* These weak default definitions act as a fallback definition if no driver
|
||||
* defines a ISR for the specific interrupt.
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "vectors_cortexm.h"
|
||||
#include "vectors_qn908x.h"
|
||||
|
||||
/* These are defined in vectors_cortexm.c. */
|
||||
extern void reset_handler_default(void);
|
||||
extern uint32_t _estack; /* Exception stack pointer. */
|
||||
|
||||
/**
|
||||
* @brief Jump to the reset_handle_default handler with the exception stack.
|
||||
*/
|
||||
__attribute__((noreturn)) static inline void cpu_restart(void)
|
||||
{
|
||||
/* Reset the stack pointer to the beginning again and jump to the reset
|
||||
* handler at the expected address.
|
||||
*/
|
||||
__asm volatile ("msr msp, %[estack]\n"
|
||||
"mov pc, %[entry]\n"
|
||||
:
|
||||
: [ estack ] "r" (&_estack),
|
||||
[ entry ] "r" (reset_handler_default)
|
||||
: "memory");
|
||||
|
||||
/* This function doesn't return anyway. */
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remap the flash to address 0 on start.
|
||||
*
|
||||
* The bootloader will jump to the flash at address 0x21000000 which is aliased
|
||||
* to the flash on this CPU. However, our program is linked to run as if the
|
||||
* flash is mapped at address 0 which is the common case. The range starting at
|
||||
* address 0 can be mapped to flash, RAM or ROM via the SYS_MODE_CTRL register,
|
||||
* but on reset the default value (0x0) means that it is mapped to ROM.
|
||||
* We need to remap the flash and change the program counter to be running from
|
||||
* the right address range (0).
|
||||
*/
|
||||
void pre_startup(void)
|
||||
{
|
||||
register unsigned int pc;
|
||||
|
||||
/* Disable interrupts */
|
||||
__disable_irq();
|
||||
|
||||
/* Check whether we are running from the 0x21000000 range. If that's the
|
||||
* case we need to remap the flash to the address 0 in SYS_MODE_CTRL and
|
||||
* jump back to the reset_handler_default so everything starts as running
|
||||
* from the address 0x0 instead.
|
||||
*/
|
||||
__asm volatile ("mov %0, pc" : "=r" (pc));
|
||||
|
||||
if ((pc & 0x21000000) == 0x21000000) {
|
||||
SYSCON->SYS_MODE_CTRL |= 1;
|
||||
cpu_restart();
|
||||
}
|
||||
}
|
||||
|
||||
/* QN908x interrupt service routines */
|
||||
WEAK_DEFAULT void isr_ext_gpio_wakeup(void);
|
||||
WEAK_DEFAULT void isr_osc(void);
|
||||
WEAK_DEFAULT void isr_acmp0(void);
|
||||
WEAK_DEFAULT void isr_acmp1(void);
|
||||
WEAK_DEFAULT void isr_rtc_sec(void);
|
||||
WEAK_DEFAULT void isr_rtc_fr(void);
|
||||
WEAK_DEFAULT void isr_cs_wakeup(void);
|
||||
WEAK_DEFAULT void isr_cs(void);
|
||||
WEAK_DEFAULT void isr_gpioa(void);
|
||||
WEAK_DEFAULT void isr_gpiob(void);
|
||||
WEAK_DEFAULT void isr_dma0(void);
|
||||
WEAK_DEFAULT void isr_pin_int0(void);
|
||||
WEAK_DEFAULT void isr_pin_int1(void);
|
||||
WEAK_DEFAULT void isr_pin_int2(void);
|
||||
WEAK_DEFAULT void isr_pin_int3(void);
|
||||
WEAK_DEFAULT void isr_osc_int_low(void);
|
||||
WEAK_DEFAULT void isr_usb0(void);
|
||||
WEAK_DEFAULT void isr_flexcomm0(void);
|
||||
WEAK_DEFAULT void isr_flexcomm1(void);
|
||||
WEAK_DEFAULT void isr_flexcomm2(void);
|
||||
WEAK_DEFAULT void isr_flexcomm3(void);
|
||||
WEAK_DEFAULT void isr_ble(void);
|
||||
WEAK_DEFAULT void isr_fsp(void);
|
||||
WEAK_DEFAULT void isr_qdec0(void);
|
||||
WEAK_DEFAULT void isr_qdec1(void);
|
||||
WEAK_DEFAULT void isr_ctimer0(void);
|
||||
WEAK_DEFAULT void isr_ctimer1(void);
|
||||
WEAK_DEFAULT void isr_ctimer2(void);
|
||||
WEAK_DEFAULT void isr_ctimer3(void);
|
||||
WEAK_DEFAULT void isr_wdt(void);
|
||||
WEAK_DEFAULT void isr_adc(void);
|
||||
WEAK_DEFAULT void isr_dac(void);
|
||||
WEAK_DEFAULT void isr_xtal_ready(void);
|
||||
WEAK_DEFAULT void isr_flash(void);
|
||||
WEAK_DEFAULT void isr_spifi0(void);
|
||||
WEAK_DEFAULT void isr_sct0(void);
|
||||
WEAK_DEFAULT void isr_rng(void);
|
||||
WEAK_DEFAULT void isr_calib(void);
|
||||
WEAK_DEFAULT void isr_ble_tx(void);
|
||||
WEAK_DEFAULT void isr_ble_rx(void);
|
||||
WEAK_DEFAULT void isr_ble_freq_hop(void);
|
||||
WEAK_DEFAULT void isr_bod(void);
|
||||
|
||||
void dummy_handler(void)
|
||||
{
|
||||
dummy_handler_default();
|
||||
}
|
69
cpu/qn908x/ldscripts/qn908x.ld
Normal file
69
cpu/qn908x/ldscripts/qn908x.ld
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup cpu_qn908x
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Sections definitions for the NXP QN908x MCUs
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*
|
||||
* This linker script organizes the flash headers to generate a "Legacy" image
|
||||
* as described in the "Boot Process" section of the QN908x user manual. A
|
||||
* legacy image contains an "Image vector table" which is the standard ARM
|
||||
* vector table with some special values in the reserved fields. In particular,
|
||||
* this needs a to have a valid checksum at address 0x1c to be considered a
|
||||
* valid image by the bootloader, which is not set by the build process.
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
_vectors_length = 0x114;
|
||||
|
||||
/* The Flash lock and protect descriptor occupies the last flash page of 0x800
|
||||
* bytes. See "Flash lock and protection" protection section. */
|
||||
_flash_lock_length = 0x800;
|
||||
|
||||
INCLUDE cortexm_rom_offset.ld
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* Note: What we call "rom" here is the flash region for consistency with
|
||||
* the rest of the RIOT build system naming. There is a 256 kB ROM memory in
|
||||
* the QN908x holding the bootloader and Bluetooth stack that can't be
|
||||
* modified by the user.
|
||||
*/
|
||||
vectors : ORIGIN = _rom_start_addr + _rom_offset, LENGTH = _vectors_length
|
||||
rom (rx) : ORIGIN = _rom_start_addr + _rom_offset + _vectors_length, LENGTH = _fw_rom_length - _vectors_length - _flash_lock_length
|
||||
ram (!rx) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* "Image vector table" 0x000-0x114, defined in the "Boot process" section,
|
||||
* must have exactly this size, otherwise we configured something wrong.
|
||||
*/
|
||||
.vectors :
|
||||
{
|
||||
PROVIDE(_isr_vectors = .);
|
||||
KEEP(*(SORT(.vector*)))
|
||||
} > vectors
|
||||
ASSERT (SIZEOF(.vectors) == _vectors_length,
|
||||
"Image vector table size mismatch.")
|
||||
ASSERT (ADDR(.vectors) == _rom_start_addr + _rom_offset,
|
||||
"Image vector table must start at the beginning of the flash")
|
||||
ASSERT (LOADADDR(.vectors) == _rom_start_addr + _rom_offset,
|
||||
"Image vector table must start at the beginning of the flash")
|
||||
|
||||
}
|
||||
|
||||
INCLUDE cortexm_base.ld
|
1
cpu/qn908x/periph/Makefile
Normal file
1
cpu/qn908x/periph/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTMAKE)/periph.mk
|
276
cpu/qn908x/periph/gpio.c
Normal file
276
cpu/qn908x/periph/gpio.c
Normal file
@ -0,0 +1,276 @@
|
||||
/*
|
||||
* 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
|
||||
* @ingroup drivers_periph_gpio
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level GPIO driver implementation
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "bitarithm.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "vectors_qn908x.h"
|
||||
#include "gpio_mux.h"
|
||||
|
||||
#include "vendor/drivers/fsl_clock.h"
|
||||
#include "vendor/drivers/fsl_iocon.h"
|
||||
|
||||
/* The pull-up / pull-down / high-z mode in the gpio_mode_t enum matches the
|
||||
* values in the IOCON_PinMuxSet() function.
|
||||
*/
|
||||
#if (GPIO_MODE(0, 0, 0) & 0x30) != IOCON_MODE_HIGHZ
|
||||
#error "GPIO_MODE(x, y, 0) must be High-Z mode"
|
||||
#endif
|
||||
#if (GPIO_MODE(0, 0, 1) & 0x30) != IOCON_MODE_PULLDOWN
|
||||
#error "GPIO_MODE(x, y, 0) must be pull-down mode"
|
||||
#endif
|
||||
#if (GPIO_MODE(0, 0, 2) & 0x30) != IOCON_MODE_PULLUP
|
||||
#error "GPIO_MODE(x, y, 0) must be pull-up mode"
|
||||
#endif
|
||||
|
||||
/* Bit mask indicating if a GPIO is set to open_drain. */
|
||||
static uint32_t gpio_open_drain[GPIO_PORTS_NUMOF] = {};
|
||||
|
||||
int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
{
|
||||
GPIO_Type *const base = GPIO_T_ADDR(pin);
|
||||
const uint32_t mask = 1u << GPIO_T_PIN(pin);
|
||||
|
||||
/* We need to enable the GPIO clock before we set any register in the GPIO
|
||||
* blocks. */
|
||||
CLOCK_EnableClock(kCLOCK_Gpio);
|
||||
|
||||
/* Disable the interrupts just in case this was already configured as an
|
||||
* interrupt pin. Note: this only disables the pin(s) that you write a 1
|
||||
* to. */
|
||||
base->INTENCLR = mask;
|
||||
|
||||
/* pin_mode is the "or" of the three parts: function, mode and drive
|
||||
* strength. The mode is just the bits 4 and 5 of the gpio_mode_t and
|
||||
* corresponds to the IOCON_MODE_* values */
|
||||
uint32_t pin_mode =
|
||||
IOCON_FUNC0 | /* FUNC0 is digital GPIO on all pins. */
|
||||
(mode & 0x30) | IOCON_DRIVE_HIGH;
|
||||
gpio_init_mux(pin, pin_mode);
|
||||
|
||||
if (mode & 2) {
|
||||
/* output mode */
|
||||
/* Configure the open-drain variable for allowing setting the values
|
||||
* later. */
|
||||
if (mode & 1) {
|
||||
/* open-drain enabled. */
|
||||
gpio_open_drain[GPIO_T_PORT(pin)] |= mask;
|
||||
/* Starts with the pin set to "high" (open) in open-drain mode.
|
||||
* The DATAOUT value doesn't do anything if the output is not
|
||||
* enabled but we keep track of the current value in DATAOUT
|
||||
* anyway to allow gpio_toggle. */
|
||||
base->OUTENCLR = mask;
|
||||
base->DATAOUT |= mask;
|
||||
}
|
||||
else {
|
||||
gpio_open_drain[GPIO_T_PORT(pin)] &= ~mask;
|
||||
/* Starts with the pin set to low on push-pull mode. */
|
||||
base->DATAOUT &= ~mask;
|
||||
base->OUTENSET = mask;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* input mode */
|
||||
gpio_open_drain[GPIO_T_PORT(pin)] &= ~mask;
|
||||
base->OUTENCLR = mask;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MODULE_PERIPH_GPIO_IRQ
|
||||
|
||||
typedef struct {
|
||||
gpio_cb_t cb;
|
||||
void *arg;
|
||||
} gpio_isr_cb_state_t;
|
||||
|
||||
/**
|
||||
* @brief The number of GPIO pins per port.
|
||||
*/
|
||||
#define PINS_PER_PORT (32)
|
||||
|
||||
/**
|
||||
* @brief The total number of GPIO pins in the chip.
|
||||
*/
|
||||
#define TOTAL_GPIO_PINS (35)
|
||||
|
||||
static gpio_isr_cb_state_t gpio_isr_state[TOTAL_GPIO_PINS] = {};
|
||||
|
||||
int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
|
||||
gpio_cb_t cb, void *arg)
|
||||
{
|
||||
uint8_t gpio_num = GPIO_T_PORT(pin) * PINS_PER_PORT + GPIO_T_PIN(pin);
|
||||
|
||||
if (gpio_num >= TOTAL_GPIO_PINS) {
|
||||
return -1;
|
||||
}
|
||||
gpio_isr_state[gpio_num].cb = cb;
|
||||
gpio_isr_state[gpio_num].arg = arg;
|
||||
|
||||
if (gpio_init(pin, mode) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
GPIO_Type *const base = GPIO_T_ADDR(pin);
|
||||
const uint32_t mask = 1u << GPIO_T_PIN(pin);
|
||||
|
||||
switch (flank) {
|
||||
case GPIO_LOW:
|
||||
base->INTTYPECLR = mask; /* CLR = level */
|
||||
base->INTPOLCLR = mask; /* CLR = low */
|
||||
break;
|
||||
case GPIO_HIGH:
|
||||
base->INTTYPECLR = mask; /* CLR = level */
|
||||
base->INTPOLSET = mask; /* SET = high */
|
||||
break;
|
||||
case GPIO_FALLING:
|
||||
base->INTTYPESET = mask; /* SET = edge */
|
||||
base->INTPOLCLR = mask; /* CLR = falling */
|
||||
break;
|
||||
case GPIO_RISING:
|
||||
base->INTTYPESET = mask; /* SET = edge */
|
||||
base->INTPOLSET = mask; /* SET = rising */
|
||||
break;
|
||||
}
|
||||
gpio_irq_enable(pin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_t pin)
|
||||
{
|
||||
GPIO_T_ADDR(pin)->INTENSET = 1u << GPIO_T_PIN(pin);
|
||||
}
|
||||
|
||||
void gpio_irq_disable(gpio_t pin)
|
||||
{
|
||||
GPIO_T_ADDR(pin)->INTENCLR = 1u << GPIO_T_PIN(pin);
|
||||
}
|
||||
|
||||
#endif /* defined(MODULE_PERIPH_GPIO_IRQ) */
|
||||
|
||||
int gpio_read(gpio_t pin)
|
||||
{
|
||||
return ((GPIO_T_ADDR(pin)->DATA) >> GPIO_T_PIN(pin)) & 1u;
|
||||
}
|
||||
|
||||
void gpio_set(gpio_t pin)
|
||||
{
|
||||
GPIO_Type *const base = GPIO_T_ADDR(pin);
|
||||
const uint32_t mask = 1u << GPIO_T_PIN(pin);
|
||||
|
||||
/* out_clr has only the pin bit set if this is an open-drain pin, which
|
||||
* means we need to disable the output. This needs to happen before changing
|
||||
* DATAOUT. */
|
||||
const uint32_t out_clr = mask & gpio_open_drain[GPIO_T_PORT(pin)];
|
||||
|
||||
base->OUTENCLR = out_clr;
|
||||
|
||||
base->DATAOUT |= mask;
|
||||
}
|
||||
|
||||
void gpio_clear(gpio_t pin)
|
||||
{
|
||||
GPIO_Type *const base = GPIO_T_ADDR(pin);
|
||||
const uint32_t mask = 1u << GPIO_T_PIN(pin);
|
||||
|
||||
base->DATAOUT &= ~mask;
|
||||
|
||||
/* out_clr has only the pin bit set if this is an open-drain pin, which
|
||||
* means we need to enable the output. This needs to happen after changing
|
||||
* DATAOUT. */
|
||||
const uint32_t out_clr = mask & gpio_open_drain[GPIO_T_PORT(pin)];
|
||||
base->OUTENSET = out_clr;
|
||||
}
|
||||
|
||||
void gpio_toggle(gpio_t pin)
|
||||
{
|
||||
GPIO_Type *const base = GPIO_T_ADDR(pin);
|
||||
const uint32_t mask = 1u << GPIO_T_PIN(pin);
|
||||
const uint32_t out_clr = mask & gpio_open_drain[GPIO_T_PORT(pin)];
|
||||
const uint32_t dataout = base->DATAOUT;
|
||||
|
||||
/* The output is disabled if the pin is an open-drain pin and DATAOUT is
|
||||
* not set for that pin. This avoids having if conditions. */
|
||||
base->OUTENCLR = out_clr & ~dataout;
|
||||
base->DATAOUT ^= mask;
|
||||
/* The output is disabled if the pin is an open-drain and DATAOUT at the
|
||||
* beginning of the function was set. */
|
||||
base->OUTENSET = out_clr & dataout;
|
||||
}
|
||||
|
||||
void gpio_write(gpio_t pin, int value)
|
||||
{
|
||||
if (value) {
|
||||
gpio_set(pin);
|
||||
}
|
||||
else {
|
||||
gpio_clear(pin);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MODULE_PERIPH_GPIO_IRQ
|
||||
|
||||
static inline void irq_handler(GPIO_Type *base, uint32_t port_num)
|
||||
{
|
||||
uint32_t status = base->INTSTATUS;
|
||||
|
||||
while (status) {
|
||||
/* Clear all the flags immediately and process them in order. This gives
|
||||
* a chance to execute every pin's interrupt handler even if another pin
|
||||
* is always on.
|
||||
* Note: to *clear* the interrupt flag you write a 1 to that bit.
|
||||
*/
|
||||
base->INTSTATUS = status;
|
||||
while (status) {
|
||||
uint8_t pin;
|
||||
status = bitarithm_test_and_clear(status, &pin);
|
||||
uint32_t gpio_num = port_num * PINS_PER_PORT + pin;
|
||||
gpio_cb_t cb = gpio_isr_state[gpio_num].cb;
|
||||
if (cb) {
|
||||
cb(gpio_isr_state[gpio_num].arg);
|
||||
}
|
||||
}
|
||||
status = base->INTSTATUS;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GPIOA_BASE
|
||||
void isr_gpioa(void)
|
||||
{
|
||||
irq_handler(GPIOA, 0);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
#endif /* GPIOA_BASE */
|
||||
|
||||
#ifdef GPIOB_BASE
|
||||
void isr_gpiob(void)
|
||||
{
|
||||
irq_handler(GPIOB, 1);
|
||||
cortexm_isr_end();
|
||||
}
|
||||
#endif /* GPIOB_BASE */
|
||||
|
||||
#endif /* MODULE_PERIPH_GPIO_IRQ */
|
32
cpu/qn908x/periph/gpio_mux.c
Normal file
32
cpu/qn908x/periph/gpio_mux.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 Common Pin MUX functions.
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "gpio_mux.h"
|
||||
|
||||
#include "vendor/drivers/fsl_iocon.h"
|
||||
|
||||
void gpio_init_mux(gpio_t pin, uint32_t func)
|
||||
{
|
||||
if (pin == GPIO_UNDEF) {
|
||||
return;
|
||||
}
|
||||
IOCON_PinMuxSet(IOCON, GPIO_T_PORT(pin), GPIO_T_PIN(pin), func);
|
||||
}
|
191
cpu/qn908x/periph/wdt.c
Normal file
191
cpu/qn908x/periph/wdt.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* 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
|
||||
* @ingroup cpu_qn908x_wdt
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level WDOG driver implementation
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "periph/wdt.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "vendor/drivers/fsl_clock.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
/* The number of cycles to refresh the WDT with when kicked. */
|
||||
static uint32_t wdt_load_value = 0xffffffff;
|
||||
|
||||
/* The maximum value the WDT counter could have when kicked. The WDT counter
|
||||
* always decrements starting from wdt_load_value, so when used in WINDOW mode
|
||||
* a counter value larger than this means that WDT was kicked before the lower
|
||||
* bound of the window.
|
||||
*/
|
||||
static uint32_t wdt_load_window_value = 0xffffffff;
|
||||
|
||||
/* The value that will be loaded in the WDT counter after the first interrupt
|
||||
* triggers. The WDT doesn't not reset the device automatically once the WDT
|
||||
* counter reaches 0, instead it first triggers an interrupt and restarts the
|
||||
* count again. This value will be loaded by the ISR after it triggers. A value
|
||||
* of 0 means to reset immediately after the ISR triggers, which is used if no
|
||||
* callback is provided. */
|
||||
static uint32_t wdt_load_after_isr = 0;
|
||||
|
||||
#ifdef MODULE_PERIPH_WDT_CB
|
||||
static wdt_cb_t wdt_cb;
|
||||
static void *wdt_arg;
|
||||
static bool wdt_kick_disabled = false;
|
||||
#endif /* MODULE_PERIPH_WDT_CB */
|
||||
|
||||
/**
|
||||
* Before making any change to the WDT it is required to "unlock" it by writing
|
||||
* this value to the LOCK register. Call @ref _wdt_lock() to lock it again.
|
||||
*/
|
||||
static void _wdt_unlock(void)
|
||||
{
|
||||
WDT->LOCK = 0x1acce551;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the WDT block to prevent accidental changes.
|
||||
*/
|
||||
static void _wdt_lock(void)
|
||||
{
|
||||
WDT->LOCK = 0x10c1ced; /* Any other value is as good. */
|
||||
}
|
||||
|
||||
void wdt_start(void)
|
||||
{
|
||||
CLOCK_EnableClock(kCLOCK_Wdt);
|
||||
}
|
||||
|
||||
void wdt_stop(void)
|
||||
{
|
||||
/* This only stops the clock of the watchdog and therefore the counter
|
||||
* stops, but leaves it otherwise configured. */
|
||||
CLOCK_DisableClock(kCLOCK_Wdt);
|
||||
}
|
||||
|
||||
void wdt_kick(void)
|
||||
{
|
||||
#ifdef MODULE_PERIPH_WDT_CB
|
||||
if (wdt_kick_disabled) {
|
||||
return;
|
||||
}
|
||||
#endif /* MODULE_PERIPH_WDT_CB */
|
||||
if (WDT->VALUE > wdt_load_window_value) {
|
||||
DEBUG("wdt_kick() called before the minimum window time.");
|
||||
/* In this condition we simulate the WDT triggering immediately by
|
||||
* setting its LOAD value to 0. This will cause the ISR (and the
|
||||
* callback if there is one) if it wasn't called yet, which will update
|
||||
* the LOAD value with the time derived from CONFIG_WDT_WARNING_PERIOD
|
||||
* if needed and reset the device afterwards. */
|
||||
_wdt_unlock();
|
||||
WDT->LOAD = 0;
|
||||
_wdt_lock();
|
||||
while (true) {}
|
||||
}
|
||||
_wdt_unlock();
|
||||
WDT->LOAD = wdt_load_value;
|
||||
_wdt_lock();
|
||||
}
|
||||
|
||||
static void wdt_setup(uint32_t min_time, uint32_t max_time, uint32_t isr_time)
|
||||
{
|
||||
/* Check reset time limit */
|
||||
assert((max_time > NWDT_TIME_LOWER_LIMIT)
|
||||
&& (max_time < NWDT_TIME_UPPER_LIMIT));
|
||||
assert(min_time <= max_time);
|
||||
|
||||
/* The clock is stopped after setup and calling wdt_start() is required. */
|
||||
wdt_stop();
|
||||
|
||||
const uint32_t tick_per_ms = CLOCK_GetFreq(kCLOCK_WdtClk) / 1000;
|
||||
wdt_load_value = tick_per_ms * max_time;
|
||||
wdt_load_window_value = tick_per_ms * (max_time - min_time);
|
||||
wdt_load_after_isr = tick_per_ms * isr_time;
|
||||
/* The ISR is always called as it is needed to trigger the reset after the
|
||||
* appropriate delay even in the no callback case. */
|
||||
_wdt_unlock();
|
||||
WDT->LOAD = wdt_load_value;
|
||||
WDT->CTRL = WDT_CTRL_RESEN_MASK | WDT_CTRL_INTEN_MASK;
|
||||
_wdt_lock();
|
||||
NVIC_EnableIRQ(WDT_IRQn);
|
||||
}
|
||||
|
||||
void wdt_setup_reboot(uint32_t min_time, uint32_t max_time)
|
||||
{
|
||||
#ifdef MODULE_PERIPH_WDT_CB
|
||||
wdt_cb = NULL;
|
||||
wdt_arg = NULL;
|
||||
#endif /* MODULE_PERIPH_WDT_CB */
|
||||
wdt_setup(min_time, max_time, 0);
|
||||
}
|
||||
|
||||
#ifdef MODULE_PERIPH_WDT_CB
|
||||
void wdt_setup_reboot_with_callback(uint32_t min_time, uint32_t max_time,
|
||||
wdt_cb_t cb, void *arg)
|
||||
{
|
||||
wdt_cb = cb;
|
||||
wdt_arg = arg;
|
||||
assert(max_time >= CONFIG_WDT_WARNING_PERIOD);
|
||||
/* We don't support having a min_time that falls within the
|
||||
* CONFIG_WDT_WARNING_PERIOD since that would mean that you can't call
|
||||
* wdt_kick() until some time after the callback is called which is pretty
|
||||
* useless considering that the purpose of the callback is to perform
|
||||
* "specific safety operations of data logging before the actual reboot."
|
||||
* before the reboot happens. After the callback is called the reboot is
|
||||
* inevitable and calling wdt_kick() has no effect. This code moves the
|
||||
* min_time back to at least the point where the callback is called which is
|
||||
* a similar behavior. */
|
||||
if (max_time - CONFIG_WDT_WARNING_PERIOD < min_time) {
|
||||
min_time = max_time - CONFIG_WDT_WARNING_PERIOD;
|
||||
}
|
||||
wdt_setup(min_time, max_time - CONFIG_WDT_WARNING_PERIOD,
|
||||
CONFIG_WDT_WARNING_PERIOD);
|
||||
}
|
||||
#endif /* MODULE_PERIPH_WDT_CB */
|
||||
|
||||
void isr_wdt(void)
|
||||
{
|
||||
DEBUG("[wdt] isr_wdt with LOAD=%" PRIu32 "\n", WDT->LOAD);
|
||||
|
||||
/* Set the timer to reset the device after CONFIG_WDT_WARNING_PERIOD but not
|
||||
* clear the interrupt bit in the WDT->INT_CLR register. This will cause the
|
||||
* WDT to reset the device the next time the counter reaches 0, which now
|
||||
* will happen again in CONFIG_WDT_WARNING_PERIOD ms.
|
||||
* Since the wdt_cb may return before the new WDT counter triggers, which is
|
||||
* the normal case if we expect the callback to do some short safety
|
||||
* operations, we would exit the ISR without clearing the interrupt bit in
|
||||
* WDT->INT_CLR which would cause the interrupt to be called again. To avoid
|
||||
* this situation, we disable the IRQ source in the NVIC.
|
||||
* After this ISR triggers, further wdt_kicks() are ignored to prevent the
|
||||
* software from kicking the WDT during the CONFIG_WDT_WARNING_PERIOD. */
|
||||
NVIC_DisableIRQ(WDT_IRQn);
|
||||
_wdt_unlock();
|
||||
WDT->LOAD = wdt_load_after_isr;
|
||||
_wdt_lock();
|
||||
|
||||
#ifdef MODULE_PERIPH_WDT_CB
|
||||
wdt_kick_disabled = true;
|
||||
if (wdt_cb) {
|
||||
wdt_cb(wdt_arg);
|
||||
}
|
||||
#endif /* MODULE_PERIPH_WDT_CB */
|
||||
cortexm_isr_end();
|
||||
}
|
52
cpu/qn908x/system.c
Normal file
52
cpu/qn908x/system.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 CMSIS system setup wrapper functions for NXP QN908x
|
||||
*
|
||||
* The system_QN908XC.h header is used by several vendor headers (including
|
||||
* QN908XC.h which defines all the registers and some drivers). The
|
||||
* system_QN908XC.c file in the vendor SDK implements the system initialization
|
||||
* via the SystemInit() function and provides the current system clock
|
||||
* frequency, however part of the system initialization is more appropriate in
|
||||
* the board module (in `board_init`) or in the cpu module (in `cpu_init`) and
|
||||
* some values like the XTAL or BUCK configuration depend on the actual board
|
||||
* used while in the SDK code they are set to the QN9080DK developer module.
|
||||
* Because of this we can't include that source file here.
|
||||
*
|
||||
* This file implements the minimum required to make some of the drivers in the
|
||||
* vendor code work by providing the global SystemCoreClock variable and a
|
||||
* function to update its value with the current clock configuration.
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cpu.h"
|
||||
|
||||
#include "vendor/drivers/fsl_clock.h"
|
||||
|
||||
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Do nothing here. The system initialization is done in board_init() and
|
||||
* cpu_init() as needed. This function shouldn't be called anyway.
|
||||
*/
|
||||
}
|
||||
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
SystemCoreClock = CLOCK_GetFreq(kCLOCK_CoreSysClk);
|
||||
}
|
77
cpu/qn908x/vectors.c
Normal file
77
cpu/qn908x/vectors.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 Interrupt vector for NXP QN908x MCUs
|
||||
*
|
||||
* @author iosabi <iosabi@protonmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Interrupt vector definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "vectors_cortexm.h"
|
||||
#include "vectors_qn908x.h"
|
||||
|
||||
/* CPU specific interrupt vector table */
|
||||
ISR_VECTOR(1) const isr_t vector_cpu[CPU_IRQ_NUMOF] = {
|
||||
[EXT_GPIO_WAKEUP_IRQn] = isr_ext_gpio_wakeup, /* Ext GPIO wakeup */
|
||||
[OSC_IRQn ] = isr_osc, /* BLE wakeup */
|
||||
[ACMP0_IRQn ] = isr_acmp0, /* Analog comparator0 */
|
||||
[ACMP1_IRQn ] = isr_acmp1, /* Analog comparator1 */
|
||||
[RTC_SEC_IRQn ] = isr_rtc_sec, /* RTC second */
|
||||
[RTC_FR_IRQn ] = isr_rtc_fr, /* RTC free running */
|
||||
[CS_WAKEUP_IRQn ] = isr_cs_wakeup, /* Capacitive sense wakeup */
|
||||
[CS_IRQn ] = isr_cs, /* Capacitive sense */
|
||||
[GPIOA_IRQn ] = isr_gpioa, /* GPIO group A */
|
||||
[GPIOB_IRQn ] = isr_gpiob, /* GPIO group B */
|
||||
[DMA0_IRQn ] = isr_dma0, /* DMA controller */
|
||||
[PIN_INT0_IRQn ] = isr_pin_int0, /* pin or pattern match engine slice 0 */
|
||||
[PIN_INT1_IRQn ] = isr_pin_int1, /* pin or pattern match engine slice 1 */
|
||||
[PIN_INT2_IRQn ] = isr_pin_int2, /* pin or pattern match engine slice 2 */
|
||||
[PIN_INT3_IRQn ] = isr_pin_int3, /* pin or pattern match engine slice 3 */
|
||||
[OSC_INT_LOW_IRQn ] = isr_osc_int_low, /* Inverse of OSC */
|
||||
[USB0_IRQn ] = isr_usb0, /* USB device */
|
||||
[FLEXCOMM0_IRQn ] = isr_flexcomm0, /* Flexcomm Interface 0 (USART) */
|
||||
[FLEXCOMM1_IRQn ] = isr_flexcomm1, /* Flexcomm Interface 1 (USART, I2C) */
|
||||
[FLEXCOMM2_IRQn ] = isr_flexcomm2, /* Flexcomm Interface 2 (SPI, I2C) */
|
||||
[FLEXCOMM3_IRQn ] = isr_flexcomm3, /* Flexcomm Interface 3 (SPI) */
|
||||
[BLE_IRQn ] = isr_ble, /* BLE interrupts */
|
||||
[FSP_IRQn ] = isr_fsp, /* FSP */
|
||||
[QDEC0_IRQn ] = isr_qdec0, /* QDEC0 */
|
||||
[QDEC1_IRQn ] = isr_qdec1, /* QDEC1 */
|
||||
[CTIMER0_IRQn ] = isr_ctimer0, /* Standard counter/timer CTIMER0 */
|
||||
[CTIMER1_IRQn ] = isr_ctimer1, /* Standard counter/timer CTIMER1 */
|
||||
[CTIMER2_IRQn ] = isr_ctimer2, /* Standard counter/timer CTIMER2 */
|
||||
[CTIMER3_IRQn ] = isr_ctimer3, /* Standard counter/timer CTIMER3 */
|
||||
[WDT_IRQn ] = isr_wdt, /* Watch dog timer */
|
||||
[ADC_IRQn ] = isr_adc, /* ADC */
|
||||
[DAC_IRQn ] = isr_dac, /* DAC */
|
||||
[XTAL_READY_IRQn ] = isr_xtal_ready, /* High frequency crystal ready */
|
||||
[FLASH_IRQn ] = isr_flash, /* Flash */
|
||||
[SPIFI0_IRQn ] = isr_spifi0, /* SPI flash interface */
|
||||
[SCT0_IRQn ] = isr_sct0, /* SCTimer/PWM */
|
||||
[RNG_IRQn ] = isr_rng, /* Random number generator */
|
||||
[CALIB_IRQn ] = isr_calib, /* Calibration */
|
||||
[BLE_TX_IRQn ] = isr_ble_tx, /* ble tx flag */
|
||||
[BLE_RX_IRQn ] = isr_ble_rx, /* ble rx flag */
|
||||
[BLE_FREQ_HOP_IRQn] = isr_ble_freq_hop, /* ble frequency hop */
|
||||
[BOD_IRQn ] = isr_bod, /* Brown out detect */
|
||||
};
|
||||
|
||||
__attribute__((weak)) const uint32_t isp_configuration = 0;
|
||||
|
||||
/** @} */
|
14
cpu/qn908x/vendor/Makefile
vendored
Normal file
14
cpu/qn908x/vendor/Makefile
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
MODULE := vendor
|
||||
|
||||
# Enable submodules, although these are all compiled into the same "vendor.a"
|
||||
# library since vendor_% is marked as a pseudomodule.
|
||||
SUBMODULES := 1
|
||||
SUBMODULES_NOFORCE := 1
|
||||
|
||||
CFLAGS += -Wno-unused-parameter -Wno-sign-compare
|
||||
INCLUDES += \
|
||||
-I$(RIOTCPU)/$(CPU)/include/vendor/ \
|
||||
-I$(RIOTCPU)/$(CPU)/include/vendor/drivers/ \
|
||||
#
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
334
cpu/qn908x/vendor/fsl_clock.c
vendored
Normal file
334
cpu/qn908x/vendor/fsl_clock.c
vendored
Normal file
@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright (c) 2016 - 2017 , NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_clock.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define getSysconClkMux() ((SYSCON->CLK_CTRL & SYSCON_CLK_CTRL_SYS_CLK_SEL_MASK) >> SYSCON_CLK_CTRL_SYS_CLK_SEL_SHIFT)
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t crcClkRefCnt;
|
||||
uint8_t dmaClkRefCnt;
|
||||
} ref_cnt_t;
|
||||
uint8_t clkRefCnt[2];
|
||||
} clock_ref_cnt_t;
|
||||
|
||||
/** Clock reference count */
|
||||
static clock_ref_cnt_t clk_ref_cnt;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static void Clk32KConfig(uint8_t choice)
|
||||
{
|
||||
SYSCON->CLK_CTRL = (SYSCON->CLK_CTRL & ~SYSCON_CLK_CTRL_CLK_32K_SEL_MASK) | SYSCON_CLK_CTRL_CLK_32K_SEL(choice);
|
||||
}
|
||||
|
||||
static void ClkSysConfig(uint8_t choice)
|
||||
{
|
||||
if (choice == 0)
|
||||
{
|
||||
/* RCO 32MHz ,wait for ready */
|
||||
while (!(SYSCON->SYS_MODE_CTRL & SYSCON_SYS_MODE_CTRL_OSC32M_RDY_MASK))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/* Switch to the clock source */
|
||||
SYSCON->CLK_CTRL = (SYSCON->CLK_CTRL & ~SYSCON_CLK_CTRL_SYS_CLK_SEL_MASK) | SYSCON_CLK_CTRL_SYS_CLK_SEL(choice);
|
||||
}
|
||||
|
||||
static void ClkWdtConfig(uint8_t choice)
|
||||
{
|
||||
SYSCON->CLK_CTRL = (SYSCON->CLK_CTRL & ~SYSCON_CLK_CTRL_CLK_WDT_SEL_MASK) | SYSCON_CLK_CTRL_CLK_WDT_SEL(choice);
|
||||
}
|
||||
|
||||
static void ClkBleConfig(uint8_t choice)
|
||||
{
|
||||
SYSCON->CLK_CTRL = (SYSCON->CLK_CTRL & ~SYSCON_CLK_CTRL_CLK_BLE_SEL_MASK) | SYSCON_CLK_CTRL_CLK_BLE_SEL(choice);
|
||||
}
|
||||
|
||||
static void ClkXTALConfig(uint8_t choice)
|
||||
{
|
||||
switch (choice)
|
||||
{
|
||||
/* 16M XTAL */
|
||||
case 0:
|
||||
SYSCON->CLK_CTRL &= ~SYSCON_CLK_CTRL_CLK_XTAL_SEL_MASK;
|
||||
break;
|
||||
/* 32M XTAL */
|
||||
case 1:
|
||||
SYSCON->CLK_CTRL |= SYSCON_CLK_CTRL_CLK_XTAL_SEL_MASK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* wait for ready */
|
||||
while (!(SYSCON->SYS_MODE_CTRL & SYSCON_SYS_MODE_CTRL_XTAL_RDY_MASK))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void CLOCK_EnableClock(clock_ip_name_t clk)
|
||||
{
|
||||
uint32_t regPrimask = 0U;
|
||||
if ((clk == kCLOCK_Crc) || (clk == kCLOCK_Dma))
|
||||
{
|
||||
regPrimask = DisableGlobalIRQ();
|
||||
clk_ref_cnt.clkRefCnt[clk - kCLOCK_Crc] += 1U;
|
||||
EnableGlobalIRQ(regPrimask);
|
||||
}
|
||||
SYSCON->CLK_EN = (1U << clk);
|
||||
}
|
||||
|
||||
void CLOCK_DisableClock(clock_ip_name_t clk)
|
||||
{
|
||||
uint32_t regPrimask = 0U;
|
||||
if (((clk == kCLOCK_Crc) || (clk == kCLOCK_Dma)) && (clk_ref_cnt.clkRefCnt[clk - kCLOCK_Crc] > 0))
|
||||
{
|
||||
regPrimask = DisableGlobalIRQ();
|
||||
clk_ref_cnt.clkRefCnt[clk - kCLOCK_Crc] -= 1U;
|
||||
EnableGlobalIRQ(regPrimask);
|
||||
if (clk_ref_cnt.clkRefCnt[clk - kCLOCK_Crc] > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
SYSCON->CLK_DIS = (1U << clk);
|
||||
}
|
||||
|
||||
void CLOCK_AttachClk(clock_attach_id_t connection)
|
||||
{
|
||||
uint8_t mux, choice;
|
||||
|
||||
mux = (uint8_t)connection;
|
||||
choice = (uint8_t)(((connection & 0xf00) >> 8) - 1);
|
||||
|
||||
switch (mux)
|
||||
{
|
||||
case CM_32KCLKSEL:
|
||||
Clk32KConfig(choice);
|
||||
break;
|
||||
case CM_SYSCLKSEL:
|
||||
ClkSysConfig(choice);
|
||||
break;
|
||||
case CM_WDTCLKSEL:
|
||||
ClkWdtConfig(choice);
|
||||
break;
|
||||
case CM_BLECLKSEL:
|
||||
ClkBleConfig(choice);
|
||||
break;
|
||||
case CM_XTALCLKSEL:
|
||||
ClkXTALConfig(choice);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value)
|
||||
{
|
||||
switch (div_name)
|
||||
{
|
||||
case kCLOCK_DivXtalClk:
|
||||
/* F(XTAL) = F(XTAL) / (divided_by_value + 1), occupy 1 bit, take effect only when k32M_to_XTAL_CLK attached */
|
||||
SYSCON->XTAL_CTRL =
|
||||
(SYSCON->XTAL_CTRL & ~SYSCON_XTAL_CTRL_XTAL_DIV_MASK) | SYSCON_XTAL_CTRL_XTAL_DIV(divided_by_value);
|
||||
break;
|
||||
case kCLOCK_DivOsc32mClk:
|
||||
/* F(OSC32M) = F(OSC32M) / (divided_by_value + 1), occupy 1 bit */
|
||||
SYSCON->CLK_CTRL = (SYSCON->CLK_CTRL & ~SYSCON_CLK_CTRL_CLK_OSC32M_DIV_MASK) |
|
||||
SYSCON_CLK_CTRL_CLK_OSC32M_DIV(divided_by_value);
|
||||
break;
|
||||
case kCLOCK_DivAhbClk:
|
||||
/* F(AHB) = F(SYS) / (divided_by_value + 1), occupy 13 bits
|
||||
* Note: If ble core's clock is enabled by setting SYSCON_CLK_EN_CLK_BLE_EN to 1, ahb clock can only be 8M,
|
||||
* 16M or 32M.
|
||||
*/
|
||||
SYSCON->CLK_CTRL =
|
||||
(SYSCON->CLK_CTRL & ~SYSCON_CLK_CTRL_AHB_DIV_MASK) | SYSCON_CLK_CTRL_AHB_DIV(divided_by_value);
|
||||
break;
|
||||
case kCLOCK_DivApbClk:
|
||||
/* F(APB) = F(AHB) / (divided_by_value + 1), occupy 4 bits */
|
||||
SYSCON->CLK_CTRL =
|
||||
(SYSCON->CLK_CTRL & ~SYSCON_CLK_CTRL_APB_DIV_MASK) | SYSCON_CLK_CTRL_APB_DIV(divided_by_value);
|
||||
break;
|
||||
case kCLOCK_DivFrg0:
|
||||
/* F(Flexcomm0) = F(AHB) / (1 + MULT/DIV), DIV = 0xFF */
|
||||
SYSCON->FC_FRG = (SYSCON->FC_FRG & ~SYSCON_FC_FRG_FRG_MULT0_MASK) |
|
||||
SYSCON_FC_FRG_FRG_MULT0(divided_by_value) | SYSCON_FC_FRG_FRG_DIV0_MASK;
|
||||
break;
|
||||
case kCLOCK_DivFrg1:
|
||||
/* F(Flexcomm1) = F(AHB) / (1 + MULT/DIV), DIV = 0xFF */
|
||||
SYSCON->FC_FRG = (SYSCON->FC_FRG & ~SYSCON_FC_FRG_FRG_MULT1_MASK) |
|
||||
SYSCON_FC_FRG_FRG_MULT1(divided_by_value) | SYSCON_FC_FRG_FRG_DIV1_MASK;
|
||||
break;
|
||||
case kCLOCK_DivClkOut:
|
||||
/* F(ClkOut) = F(XTAL) / (2 * divided_by_value), occupy 4bits, take effect only when clock out source is
|
||||
* XTAL */
|
||||
SYSCON->CLK_CTRL = (SYSCON->CLK_CTRL & ~SYSCON_CLK_CTRL_XTAL_OUT_DIV_MASK) |
|
||||
SYSCON_CLK_CTRL_XTAL_OUT_DIV(divided_by_value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t CLOCK_GetRco32MFreq(void)
|
||||
{
|
||||
return (SYSCON->CLK_CTRL & SYSCON_CLK_CTRL_CLK_OSC32M_DIV_MASK) ? CLK_OSC_32MHZ / 2 : CLK_OSC_32MHZ;
|
||||
}
|
||||
|
||||
static uint32_t CLOCK_GetXinFreq(void)
|
||||
{
|
||||
return ((SYSCON->CLK_CTRL & SYSCON_CLK_CTRL_CLK_XTAL_SEL_MASK) &&
|
||||
(!(SYSCON->XTAL_CTRL & SYSCON_XTAL_CTRL_XTAL_DIV_MASK))) ?
|
||||
CLK_XTAL_32MHZ :
|
||||
CLK_XTAL_16MHZ;
|
||||
}
|
||||
|
||||
static uint32_t CLOCK_Get32KFreq(void)
|
||||
{
|
||||
return (SYSCON->CLK_CTRL & SYSCON_CLK_CTRL_CLK_32K_SEL_MASK) ? CLK_RCO_32KHZ : CLK_XTAL_32KHZ;
|
||||
}
|
||||
|
||||
static uint32_t CLOCK_GetCoreSysClkFreq(void)
|
||||
{
|
||||
return (getSysconClkMux() == 0) ? CLOCK_GetRco32MFreq() : (getSysconClkMux() == 1) ?
|
||||
CLOCK_GetXinFreq() :
|
||||
(getSysconClkMux() == 2) ? CLOCK_Get32KFreq() : 0;
|
||||
}
|
||||
|
||||
static uint32_t CLOCK_GetAhbClkFreq(void)
|
||||
{
|
||||
return CLOCK_GetCoreSysClkFreq() /
|
||||
(((SYSCON->CLK_CTRL & SYSCON_CLK_CTRL_AHB_DIV_MASK) >> SYSCON_CLK_CTRL_AHB_DIV_SHIFT) + 1);
|
||||
}
|
||||
|
||||
static uint32_t CLOCK_GetApbClkFreq(void)
|
||||
{
|
||||
return CLOCK_GetAhbClkFreq() /
|
||||
(((SYSCON->CLK_CTRL & SYSCON_CLK_CTRL_APB_DIV_MASK) >> SYSCON_CLK_CTRL_APB_DIV_SHIFT) + 1);
|
||||
}
|
||||
|
||||
static uint32_t CLOCK_GetWdtFreq(void)
|
||||
{
|
||||
return (SYSCON->CLK_CTRL & SYSCON_CLK_CTRL_CLK_WDT_SEL_MASK) ? CLOCK_GetApbClkFreq() : CLOCK_Get32KFreq();
|
||||
}
|
||||
|
||||
uint32_t CLOCK_GetFreq(clock_name_t clk)
|
||||
{
|
||||
uint32_t freq;
|
||||
switch (clk)
|
||||
{
|
||||
case kCLOCK_CoreSysClk:
|
||||
freq = CLOCK_GetCoreSysClkFreq();
|
||||
break;
|
||||
case kCLOCK_BusClk:
|
||||
freq = CLOCK_GetAhbClkFreq();
|
||||
break;
|
||||
case kCLOCK_ApbClk:
|
||||
freq = CLOCK_GetApbClkFreq();
|
||||
break;
|
||||
case kCLOCK_WdtClk:
|
||||
freq = CLOCK_GetWdtFreq();
|
||||
break;
|
||||
case kCLOCK_FroHf:
|
||||
freq = CLOCK_GetRco32MFreq();
|
||||
break;
|
||||
case kCLOCK_Xin:
|
||||
freq = CLOCK_GetXinFreq();
|
||||
break;
|
||||
case kCLOCK_32KClk:
|
||||
freq = CLOCK_Get32KFreq();
|
||||
break;
|
||||
default:
|
||||
freq = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
bool CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src, uint32_t freq)
|
||||
{
|
||||
CLOCK_EnableClock(kCLOCK_Usbd0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CLOCK_EnableClkoutSource(uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
SYSCON->CLK_CTRL |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
SYSCON->CLK_CTRL &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
void CLOCK_EnableClkoutPin(uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
SYSCON->PIO_WAKEUP_EN1 |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
SYSCON->PIO_WAKEUP_EN1 &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CLOCK_GetFRGInputClock(void)
|
||||
{
|
||||
return CLOCK_GetFreq(kCLOCK_BusClk);
|
||||
}
|
||||
|
||||
uint32_t CLOCK_SetFRGClock(clock_div_name_t div_name, uint32_t freq)
|
||||
{
|
||||
uint32_t input = CLOCK_GetFRGInputClock();
|
||||
uint32_t mul;
|
||||
|
||||
if ((freq > 32000000) || (freq > input) || (input / freq >= 2))
|
||||
{
|
||||
/* FRG output frequency should be less than equal to 32MHz */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mul = ((uint64_t)(input - freq) * 256) / ((uint64_t)freq);
|
||||
if (div_name == kCLOCK_DivFrg0)
|
||||
{
|
||||
SYSCON->FC_FRG = (SYSCON->FC_FRG & ~SYSCON_FC_FRG_FRG_MULT0_MASK) | SYSCON_FC_FRG_FRG_MULT0(mul) |
|
||||
SYSCON_FC_FRG_FRG_DIV0_MASK;
|
||||
}
|
||||
else if (div_name == kCLOCK_DivFrg1)
|
||||
{
|
||||
SYSCON->FC_FRG = (SYSCON->FC_FRG & ~SYSCON_FC_FRG_FRG_MULT1_MASK) | SYSCON_FC_FRG_FRG_MULT1(mul) |
|
||||
SYSCON_FC_FRG_FRG_DIV1_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add for avoid the misra 2004 rule 14.10 */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user