soc: arm: ke1xf: add NXP Kinetis KE1xF SoC series support

Add initial support for the NXP Kinetis KE1xF SoC series (MKE14F16,
MKE16F16, and MKE18F16).

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2019-05-05 00:01:56 +02:00 committed by Maureen Helm
parent d4b9c0d600
commit 918579ebbf
25 changed files with 1150 additions and 0 deletions

View file

@ -213,6 +213,7 @@
/include/drivers/mvic.h @andrewboie
/include/drivers/pcie/ @gnuless
/include/drivers/serial/uart_ns16550.h @gnuless
/include/dt-bindings/clock/kinetis_scg.h @henrikbrixandersen
/include/dt-bindings/pcie/ @gnuless
/include/fs.h @nashif @wentongwu
/include/fs/ @nashif @wentongwu

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nxp/nxp_ke1xf256vlx16.dtsi>

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nxp/nxp_ke1xf512vlx16.dtsi>

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nxp/nxp_ke1xf256vlx16.dtsi>

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nxp/nxp_ke1xf512vlx16.dtsi>

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nxp/nxp_ke1xf256vlx16.dtsi>

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nxp/nxp_ke1xf512vlx16.dtsi>

186
dts/arm/nxp/nxp_ke1xf.dtsi Normal file
View file

@ -0,0 +1,186 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <arm/armv7-m.dtsi>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/i2c/i2c.h>
/ {
aliases {
uart-0 = &uart0;
uart-1 = &uart1;
uart-2 = &uart2;
pinmux-a = &pinmux_a;
pinmux-b = &pinmux_b;
pinmux-c = &pinmux_c;
pinmux-d = &pinmux_d;
pinmux-e = &pinmux_e;
gpio-a = &gpioa;
gpio-b = &gpiob;
gpio-c = &gpioc;
gpio-d = &gpiod;
gpio-e = &gpioe;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-m4f";
reg = <0>;
};
};
soc {
mpu: mpu@4000d000 {
compatible = "nxp,kinetis-mpu";
reg = <0x4000d000 0x1000>;
status = "disabled";
};
sim: sim@40048000 {
compatible = "nxp,kinetis-sim";
reg = <0x40048000 0x1000>;
label = "SIM";
};
scg: scg@40064000 {
compatible = "nxp,kinetis-scg";
reg = <0x40064000 0x1000>;
label = "SCG";
};
pcc: pcc@40065000 {
compatible = "nxp,kinetis-pcc";
reg = <0x40065000 0x1000>;
label = "PCC";
clock-controller;
#clock-cells = <1>;
};
flash_controller: flash-controller@40020000 {
compatible = "nxp,kinetis-ftfe";
label = "FLASH_CTRL";
reg = <0x40020000 0x1000>;
interrupts = <18 0>, <19 0>;
interrupt-names = "command-complete", "read-collision";
#address-cells = <1>;
#size-cells = <1>;
};
uart0: uart@4006a000 {
compatible = "nxp,kinetis-lpuart";
reg = <0x4006a000 0x1000>;
interrupts = <31 0>, <32 0>;
interrupt-names = "transmit", "receive";
clocks = <&pcc 0x1a8>;
label = "UART_0";
status = "disabled";
};
uart1: uart@4006b000 {
compatible = "nxp,kinetis-lpuart";
reg = <0x4006b000 0x1000>;
interrupts = <33 0>, <34 0>;
interrupt-names = "transmit", "receive";
clocks = <&pcc 0x1ac>;
label = "UART_1";
status = "disabled";
};
uart2: uart@4006c000 {
compatible = "nxp,kinetis-lpuart";
reg = <0x4006c000 0x1000>;
interrupts = <35 0>, <36 0>;
interrupt-names = "transmit", "receive";
clocks = <&pcc 0x1b0>;
label = "UART_2";
status = "disabled";
};
pinmux_a: pinmux@40049000 {
compatible = "nxp,kinetis-pinmux";
reg = <0x40049000 0x1000>;
clocks = <&pcc 0x124>;
};
pinmux_b: pinmux@4004a000 {
compatible = "nxp,kinetis-pinmux";
reg = <0x4004a000 0x1000>;
clocks = <&pcc 0x128>;
};
pinmux_c: pinmux@4004b000 {
compatible = "nxp,kinetis-pinmux";
reg = <0x4004b000 0x1000>;
clocks = <&pcc 0x12c>;
};
pinmux_d: pinmux@4004c000 {
compatible = "nxp,kinetis-pinmux";
reg = <0x4004c000 0x1000>;
clocks = <&pcc 0x130>;
};
pinmux_e: pinmux@4004d000 {
compatible = "nxp,kinetis-pinmux";
reg = <0x4004d000 0x1000>;
clocks = <&pcc 0x134>;
};
gpioa: gpio@400ff000 {
compatible = "nxp,kinetis-gpio";
reg = <0x400ff000 0x40>;
interrupts = <59 2>;
label = "GPIO_0";
gpio-controller;
#gpio-cells = <2>;
};
gpiob: gpio@400ff040 {
compatible = "nxp,kinetis-gpio";
reg = <0x400ff040 0x40>;
interrupts = <60 2>;
label = "GPIO_1";
gpio-controller;
#gpio-cells = <2>;
};
gpioc: gpio@400ff080 {
compatible = "nxp,kinetis-gpio";
reg = <0x400ff080 0x40>;
interrupts = <61 2>;
label = "GPIO_2";
gpio-controller;
#gpio-cells = <2>;
};
gpiod: gpio@400ff0c0 {
compatible = "nxp,kinetis-gpio";
reg = <0x400ff0c0 0x40>;
interrupts = <62 2>;
label = "GPIO_3";
gpio-controller;
#gpio-cells = <2>;
};
gpioe: gpio@400ff100 {
compatible = "nxp,kinetis-gpio";
reg = <0x400ff100 0x40>;
interrupts = <63 2>;
label = "GPIO_4";
gpio-controller;
#gpio-cells = <2>;
};
};
};
&nvic {
arm,num-irq-priority-bits = <4>;
};

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <mem.h>
#include <nxp/nxp_ke1xf.dtsi>
/ {
/* The on-chip SRAM is split into SRAM_L and SRAM_U regions that form a
* contiguous block in the memory map, however misaligned accesses
* across the 0x2000_0000 boundary are not supported in the Arm
* Cortex-M4 architecture. For clarity and to avoid the temptation for
* someone to extend sram0 without solving this issue, we define two
* separate memory nodes here and only use the upper one for now. A
* potential solution has been proposed in binutils:
* https://sourceware.org/ml/binutils/2017-02/msg00250.html
*/
sram_l: memory@1fffc000 {
device_type = "memory";
compatible = "mmio-sram";
reg = <0x1fffc000 DT_SIZE_K(16)>;
};
sram0: memory@20000000 {
device_type = "memory";
compatible = "mmio-sram";
reg = <0x20000000 DT_SIZE_K(16)>;
};
};
&flash_controller {
flash0: flash@0 {
compatible = "soc-nv-flash";
label = "MCUX_FLASH";
reg = <0 DT_SIZE_K(256)>;
erase-block-size = <DT_SIZE_K(4)>;
write-block-size = <8>;
};
};

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <mem.h>
#include <nxp/nxp_ke1xf.dtsi>
/ {
/* The on-chip SRAM is split into SRAM_L and SRAM_U regions that form a
* contiguous block in the memory map, however misaligned accesses
* across the 0x2000_0000 boundary are not supported in the Arm
* Cortex-M4 architecture. For clarity and to avoid the temptation for
* someone to extend sram0 without solving this issue, we define two
* separate memory nodes here and only use the upper one for now. A
* potential solution has been proposed in binutils:
* https://sourceware.org/ml/binutils/2017-02/msg00250.html
*/
sram_l: memory@1fff8000 {
device_type = "memory";
compatible = "mmio-sram";
reg = <0x1fff8000 DT_SIZE_K(32)>;
};
sram0: memory@20000000 {
device_type = "memory";
compatible = "mmio-sram";
reg = <0x20000000 DT_SIZE_K(32)>;
};
};
&flash_controller {
flash0: flash@0 {
compatible = "soc-nv-flash";
label = "MCUX_FLASH";
reg = <0 DT_SIZE_K(512)>;
erase-block-size = <DT_SIZE_K(4)>;
write-block-size = <8>;
};
};

View file

@ -0,0 +1,153 @@
#
# Copyright (c) 2019 Vestas Wind Systems A/S
#
# SPDX-License-Identifier: Apache-2.0
#
---
title: NXP Kinetis SCG (System Clock Generator)
version: 0.1
description: >
This is a representation of the NXP Kinetis SCG IP node
properties:
compatible:
type: string
category: required
description: compatible strings
constraint: "nxp,kinetis-scg"
generation: define
reg:
type: int
description: mmio register space
generation: define
category: required
label:
type: string
category: required
description: Human readable string describing the device (used by Zephyr for API name)
generation: define
clk-divider-slow:
type: int
description: system clock to slow clock divider
generation: define
category: required
clk-divider-bus:
type: int
description: system clock to bus clock divider
generation: define
category: required
clk-divider-core:
type: int
description: system clock to core clock divider
generation: define
category: required
clk-source:
type: int
description: system clock source
generation: define
category: optional
sosc-freq:
type: int
description: system oscillator (e.g. xtal) frequency
generation: define
category: optional
sosc-mode:
type: int
description: system oscillator mode
generation: define
category: optional
sosc-divider-1:
type: int
description: system oscillator divider 1
generation: define
category: optional
sosc-divider-2:
type: int
description: system oscillator divider 2
generation: define
category: optional
sirc-range:
type: int
description: slow internal reference clock range in MHz
generation: define
category: required
sirc-divider-1:
type: int
description: slow internal reference clock divider 1
generation: define
category: required
sirc-divider-2:
type: int
description: slow internal reference clock divider 2
generation: define
category: required
firc-range:
type: int
description: fast internal reference clock range in MHz
generation: define
category: required
firc-divider-1:
type: int
description: fast internal reference clock divider 1
generation: define
category: required
firc-divider-2:
type: int
description: fast internal reference clock divider 2
generation: define
category: required
spll-source:
type: int
description: system phase-locked loop clock source
generation: define
category: required
spll-divider-pre:
type: int
description: system phase-locked loop reference clock divider
generation: define
category: required
spll-multiplier:
type: int
description: system phase-locked loop reference clock multiplier
generation: define
category: required
spll-divider-1:
type: int
description: system phase-locked loop divider 1
generation: define
category: required
spll-divider-2:
type: int
description: system phase-locked loop divider 2
generation: define
category: required
clkout-source:
type: int
description: clockout clock source
generation: define
category: optional
...

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_KINETIS_SCG_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_KINETIS_SCG_H_
/* SCG system clock source value */
#define KINETIS_SCG_SCLK_SRC_SOSC 1U
#define KINETIS_SCG_SCLK_SRC_SIRC 2U
#define KINETIS_SCG_SCLK_SRC_FIRC 3U
#define KINETIS_SCG_SCLK_SRC_SPLL 6U
/* SCG system oscillator mode */
#define KINETIS_SCG_SOSC_MODE_EXT 0U
#define KINETIS_SCG_SOSC_MODE_LOW_POWER 4U
#define KINETIS_SCG_SOSC_MODE_HIGH_GAIN 12U
/* SCG system phase-locked loop source */
#define KINETIS_SCG_SPLL_SRC_SOSC 0U
#define KINETIS_SCG_SPLL_SRC_FIRC 1U
/* SCG clockout source */
#define KINETIS_SCG_CLKOUT_SRC_SLOW 0U
#define KINETIS_SCG_CLKOUT_SRC_SOSC 1U
#define KINETIS_SCG_CLKOUT_SRC_SIRC 2U
#define KINETIS_SCG_CLKOUT_SRC_FIRC 3U
#define KINETIS_SCG_CLKOUT_SRC_SPLL 6U
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_KINETIS_SCG_H_ */

View file

@ -22,6 +22,7 @@ config SOC_PART_NUMBER
default SOC_PART_NUMBER_KINETIS_K6X if SOC_SERIES_KINETIS_K6X
default SOC_PART_NUMBER_KINETIS_KWX if SOC_SERIES_KINETIS_KWX
default SOC_PART_NUMBER_KINETIS_KL2X if SOC_SERIES_KINETIS_KL2X
default SOC_PART_NUMBER_KINETIS_KE1XF if SOC_SERIES_KINETIS_KE1XF
help
This string holds the full part number of the SoC. It is a hidden option
that you should not set directly. The part number selection choice defines

View file

@ -0,0 +1,9 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(
CONFIG_ARM_MPU
nxp_mpu_regions.c
)

View file

@ -0,0 +1,14 @@
# Kconfig - Kinetis KE14F16 configuration options
#
# Copyright (c) 2019 Vestas Wind Systems A/S
#
# SPDX-License-Identifier: Apache-2.0
#
if SOC_MKE14F16
config SOC
string
default "mke14f16"
endif # SOC_MKE14F16

View file

@ -0,0 +1,14 @@
# Kconfig - Kinetis KE16F16 configuration options
#
# Copyright (c) 2019 Vestas Wind Systems A/S
#
# SPDX-License-Identifier: Apache-2.0
#
if SOC_MKE16F16
config SOC
string
default "mke16f16"
endif # SOC_MKE16F16

View file

@ -0,0 +1,14 @@
# Kconfig - Kinetis KE18F16 configuration options
#
# Copyright (c) 2019 Vestas Wind Systems A/S
#
# SPDX-License-Identifier: Apache-2.0
#
if SOC_MKE18F16
config SOC
string
default "mke18f16"
endif # SOC_MKE18F16

View file

@ -0,0 +1,61 @@
# Kconfig - Kinetis KE1xF series configuration options
#
# Copyright (c) 2019 Vestas Wind Systems A/S
#
# SPDX-License-Identifier: Apache-2.0
#
if SOC_SERIES_KINETIS_KE1XF
config SOC_SERIES
default "ke1xf"
config NUM_IRQS
int
# must be >= the highest interrupt number used
default 91
if CLOCK_CONTROL
config CLOCK_CONTROL_MCUX_SIM
default y
config CLOCK_CONTROL_MCUX_PCC
default y
endif # CLOCK_CONTROL
if PINMUX
config PINMUX_MCUX
default y
endif # PINMUX
config GPIO
default y
if GPIO
config GPIO_MCUX
default y
endif # GPIO
if FLASH
config SOC_FLASH_MCUX
default y
endif # FLASH
if SERIAL
config UART_MCUX_LPUART
default y
endif # SERIAL
source "soc/arm/nxp_kinetis/ke1xf/Kconfig.defconfig.mke*"
endif # SOC_SERIES_KINETIS_KE1XF

View file

@ -0,0 +1,21 @@
# Kconfig - Kinetis KE1xF series MCU
#
# Copyright (c) 2019 Vestas Wind Systems A/S
#
# SPDX-License-Identifier: Apache-2.0
#
config SOC_SERIES_KINETIS_KE1XF
bool "Kinetis KE1xF Series MCU"
select CPU_CORTEX_M4
select SOC_FAMILY_KINETIS
select CPU_HAS_NXP_MPU
select CPU_HAS_FPU
select CLOCK_CONTROL
select HAS_MCUX
select HAS_MCUX_FTFX
select HAS_MCUX_LPUART
select HAS_MCUX_PCC
select HAS_MCUX_SIM
help
Enable support for Kinetis KE1xF MCU series

View file

@ -0,0 +1,90 @@
# Kconfig - Kinetis KE1xF MCU line
#
# Copyright (c) 2019 Vestas Wind Systems A/S
#
# SPDX-License-Identifier: Apache-2.0
#
choice
prompt "Kinetis KE1xF MCU Selection"
depends on SOC_SERIES_KINETIS_KE1XF
config SOC_MKE14F16
bool "MKE14F16"
config SOC_MKE16F16
bool "MKE16F16"
config SOC_MKE18F16
bool "MKE18F16"
endchoice
if SOC_SERIES_KINETIS_KE1XF
config SOC_PART_NUMBER_MKE14F256VLH16
bool
config SOC_PART_NUMBER_MKE14F256VLL16
bool
config SOC_PART_NUMBER_MKE14F512VLH16
bool
config SOC_PART_NUMBER_MKE14F512VLL16
bool
config SOC_PART_NUMBER_MKE16F256VLH16
bool
config SOC_PART_NUMBER_MKE16F256VLL16
bool
config SOC_PART_NUMBER_MKE16F512VLH16
bool
config SOC_PART_NUMBER_MKE16F512VLL16
bool
config SOC_PART_NUMBER_MKE18F256VLH16
bool
config SOC_PART_NUMBER_MKE18F256VLL16
bool
config SOC_PART_NUMBER_MKE18F512VLH16
bool
config SOC_PART_NUMBER_MKE18F512VLL16
bool
config SOC_PART_NUMBER_KINETIS_KE1XF
string
default "MKE14F256VLH16" if SOC_PART_NUMBER_MKE14F256VLH16
default "MKE14F256VLL16" if SOC_PART_NUMBER_MKE14F256VLL16
default "MKE14F512VLH16" if SOC_PART_NUMBER_MKE14F512VLH16
default "MKE14F512VLL16" if SOC_PART_NUMBER_MKE14F512VLL16
default "MKE16F256VLH16" if SOC_PART_NUMBER_MKE16F256VLH16
default "MKE16F256VLL16" if SOC_PART_NUMBER_MKE16F256VLL16
default "MKE16F512VLH16" if SOC_PART_NUMBER_MKE16F512VLH16
default "MKE16F512VLL16" if SOC_PART_NUMBER_MKE16F512VLL16
default "MKE18F256VLH16" if SOC_PART_NUMBER_MKE18F256VLH16
default "MKE18F256VLL16" if SOC_PART_NUMBER_MKE18F256VLL16
default "MKE18F512VLH16" if SOC_PART_NUMBER_MKE18F512VLH16
default "MKE18F512VLL16" if SOC_PART_NUMBER_MKE18F512VLL16
help
This string holds the full part number of the SoC. It is a
hidden option that you should not set directly. The part
number selection choice defines the default value for this
string.
config WDOG_INIT
def_bool y
# omit prompt to signify a "hidden" option
help
This processor enables the watchdog timer with a short
window for configuration upon reset. Therefore, this
requires that the watchdog be configured during reset
handling.
endif # SOC_SERIES_KINETIS_KE1XF

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
/* SoC level DTS fixup file */
#define DT_NUM_IRQ_PRIO_BITS DT_ARM_V7M_NVIC_E000E100_ARM_NUM_IRQ_PRIORITY_BITS
#define DT_SIM_NAME DT_NXP_KINETIS_SIM_40048000_LABEL
#ifdef DT_NXP_KINETIS_SIM_40048000_CLKOUT_DIVIDER
#define DT_SIM_CLKOUT_DIVIDER DT_NXP_KINETIS_SIM_40048000_CLKOUT_DIVIDER
#endif /* DT_NXP_KINETIS_SIM_40048000_CLKOUT_DIVIDER */
#ifdef DT_NXP_KINETIS_SIM_40048000_CLKOUT_SOURCE
#define DT_SIM_CLKOUT_SOURCE DT_NXP_KINETIS_SIM_40048000_CLKOUT_SOURCE
#endif /* DT_NXP_KINETIS_SIM_40048000_CLKOUT_SOURCE */
#define DT_MCUX_PCC_0_NAME DT_NXP_KINETIS_PCC_40065000_LABEL
#define DT_MCUX_PCC_0_BASE_ADDRESS DT_NXP_KINETIS_PCC_40065000_BASE_ADDRESS
#define DT_FLASH_DEV_BASE_ADDRESS DT_NXP_KINETIS_FTFE_40020000_BASE_ADDRESS
#define DT_FLASH_DEV_NAME DT_NXP_KINETIS_FTFE_40020000_LABEL
#define DT_UART_MCUX_LPUART_0_BAUD_RATE DT_NXP_KINETIS_LPUART_4006A000_CURRENT_SPEED
#define DT_UART_MCUX_LPUART_0_NAME DT_NXP_KINETIS_LPUART_4006A000_LABEL
#define DT_UART_MCUX_LPUART_0_IRQ_0 DT_NXP_KINETIS_LPUART_4006A000_IRQ_RECEIVE
#define DT_UART_MCUX_LPUART_0_IRQ_0_PRI DT_NXP_KINETIS_LPUART_4006A000_IRQ_RECEIVE_PRIORITY
#define DT_UART_MCUX_LPUART_0_IRQ_1 DT_NXP_KINETIS_LPUART_4006A000_IRQ_TRANSMIT
#define DT_UART_MCUX_LPUART_0_IRQ_1_PRI DT_NXP_KINETIS_LPUART_4006A000_IRQ_TRANSMIT_PRIORITY
#define DT_UART_MCUX_LPUART_0_HW_FLOW_CONTROL DT_NXP_KINETIS_LPUART_4006A000_HW_FLOW_CONTROL
#define DT_UART_MCUX_LPUART_0_CLOCK_NAME DT_NXP_KINETIS_LPUART_4006A000_CLOCK_CONTROLLER
#define DT_UART_MCUX_LPUART_0_CLOCK_SUBSYS DT_NXP_KINETIS_LPUART_4006A000_CLOCK_NAME
#define DT_UART_MCUX_LPUART_1_BAUD_RATE DT_NXP_KINETIS_LPUART_4006B000_CURRENT_SPEED
#define DT_UART_MCUX_LPUART_1_NAME DT_NXP_KINETIS_LPUART_4006B000_LABEL
#define DT_UART_MCUX_LPUART_1_IRQ_0 DT_NXP_KINETIS_LPUART_4006B000_IRQ_RECEIVE
#define DT_UART_MCUX_LPUART_1_IRQ_0_PRI DT_NXP_KINETIS_LPUART_4006B000_IRQ_RECEIVE_PRIORITY
#define DT_UART_MCUX_LPUART_1_IRQ_1 DT_NXP_KINETIS_LPUART_4006B000_IRQ_TRANSMIT
#define DT_UART_MCUX_LPUART_1_IRQ_1_PRI DT_NXP_KINETIS_LPUART_4006B000_IRQ_TRANSMIT_PRIORITY
#define DT_UART_MCUX_LPUART_1_HW_FLOW_CONTROL DT_NXP_KINETIS_LPUART_4006B000_HW_FLOW_CONTROL
#define DT_UART_MCUX_LPUART_1_CLOCK_NAME DT_NXP_KINETIS_LPUART_4006B000_CLOCK_CONTROLLER
#define DT_UART_MCUX_LPUART_1_CLOCK_SUBSYS DT_NXP_KINETIS_LPUART_4006B000_CLOCK_NAME
#define DT_UART_MCUX_LPUART_2_BAUD_RATE DT_NXP_KINETIS_LPUART_4006C000_CURRENT_SPEED
#define DT_UART_MCUX_LPUART_2_NAME DT_NXP_KINETIS_LPUART_4006C000_LABEL
#define DT_UART_MCUX_LPUART_2_IRQ_0 DT_NXP_KINETIS_LPUART_4006C000_IRQ_RECEIVE
#define DT_UART_MCUX_LPUART_2_IRQ_0_PRI DT_NXP_KINETIS_LPUART_4006C000_IRQ_RECEIVE_PRIORITY
#define DT_UART_MCUX_LPUART_2_IRQ_1 DT_NXP_KINETIS_LPUART_4006C000_IRQ_TRANSMIT
#define DT_UART_MCUX_LPUART_2_IRQ_1_PRI DT_NXP_KINETIS_LPUART_4006C000_IRQ_TRANSMIT_PRIORITY
#define DT_UART_MCUX_LPUART_2_HW_FLOW_CONTROL DT_NXP_KINETIS_LPUART_4006C000_HW_FLOW_CONTROL
#define DT_UART_MCUX_LPUART_2_CLOCK_NAME DT_NXP_KINETIS_LPUART_4006C000_CLOCK_CONTROLLER
#define DT_UART_MCUX_LPUART_2_CLOCK_SUBSYS DT_NXP_KINETIS_LPUART_4006C000_CLOCK_NAME

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* This is the linker script for both standard images and XIP images.
*/
#include <autoconf.h>
/*
* KE1xF Flash configuration fields
* These are 16 bytes, which must be loaded to address 0x400, and include
* default protection and security settings.
* They are loaded at reset to various Flash Memory module (FTFE) registers.
*/
/*
* No need to account for this when running a RAM-only image since that
* security feature resides in ROM.
*/
#if defined(CONFIG_XIP)
#define SKIP_TO_KINETIS_FLASH_CONFIG . = 0x400;
#endif
#include <arch/arm/cortex_m/scripts/linker.ld>

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc.h>
#include <arch/arm/cortex_m/mpu/nxp_mpu.h>
static const struct nxp_mpu_region mpu_regions[] = {
/* Region 0 */
MPU_REGION_ENTRY("DEBUGGER_0",
0,
0xFFFFFFFF,
REGION_DEBUG_ATTR),
/* The NXP MPU does not give precedence to memory regions like the ARM
* MPU, which means that if one region grants access then another
* region cannot revoke access. If an application enables hardware
* stack protection, we need to disable supervisor writes from the core
* to the stack guard region. As a result, we cannot have a single
* background region that enables supervisor read/write access from the
* core to the entire address space, and instead define two background
* regions that together cover the entire address space except for
* SRAM.
*/
/* Region 1 */
MPU_REGION_ENTRY("BACKGROUND_0",
0,
CONFIG_SRAM_BASE_ADDRESS-1,
REGION_BACKGROUND_ATTR),
/* Region 2 */
MPU_REGION_ENTRY("BACKGROUND_1",
CONFIG_SRAM_BASE_ADDRESS +
(CONFIG_SRAM_SIZE * 1024),
0xFFFFFFFF,
REGION_BACKGROUND_ATTR),
/* Region 3 */
MPU_REGION_ENTRY("FLASH_0",
CONFIG_FLASH_BASE_ADDRESS,
(CONFIG_FLASH_BASE_ADDRESS +
(CONFIG_FLASH_SIZE * 1024) - 1),
REGION_FLASH_ATTR),
/* Region 4 */
MPU_REGION_ENTRY("RAM_U_0",
CONFIG_SRAM_BASE_ADDRESS,
(CONFIG_SRAM_BASE_ADDRESS +
(CONFIG_SRAM_SIZE * 1024) - 1),
REGION_RAM_ATTR),
};
const struct nxp_mpu_config mpu_config = {
.num_regions = ARRAY_SIZE(mpu_regions),
.mpu_regions = mpu_regions,
.sram_region = 4,
};

View file

@ -0,0 +1,278 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* Based on NXP k6x soc.c, which is:
* Copyright (c) 2014-2015 Wind River Systems, Inc.
* Copyright (c) 2016, Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <fsl_clock.h>
#include <cortex_m/exc.h>
/*
* KE1xF flash configuration fields
* These 16 bytes, which must be loaded to address 0x400, include default
* protection, boot options and security settings.
* They are loaded at reset to various Flash Memory module (FTFE) registers.
*/
u8_t __kinetis_flash_config_section __kinetis_flash_config[] = {
/* Backdoor Comparison Key (unused) */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/* Program flash protection */
0xFF, 0xFF, 0xFF, 0xFF,
/*
* Flash security: Backdoor key disabled, Mass erase enabled,
* Factory access enabled, MCU is unsecure
*/
0xFE,
/*
* Flash nonvolatile option: Boot from ROM with BOOTCFG0/NMI
* pin low, boot from flash with
* BOOTCFG0/NMI pin high, RESET_b
* pin dedicated, NMI enabled,
* normal boot
*/
0x7d,
/* EEPROM protection */
0xFF,
/* Data flash protection */
0xFF,
};
#define ASSERT_WITHIN_RANGE(val, min, max, str) \
BUILD_ASSERT_MSG(val >= min && val <= max, str)
#define ASSERT_ASYNC_CLK_DIV_VALID(val, str) \
BUILD_ASSERT_MSG(val == 0 || val == 1 || val == 2 || val == 4 || \
val == 8 || val == 16 || val == 2 || val == 64, str)
#define TO_SYS_CLK_DIV(val) _DO_CONCAT(kSCG_SysClkDivBy, val)
#define kSCG_AsyncClkDivBy0 kSCG_AsyncClkDisable
#define TO_ASYNC_CLK_DIV(val) _DO_CONCAT(kSCG_AsyncClkDivBy, val)
/* System Clock configuration */
ASSERT_WITHIN_RANGE(DT_NXP_KINETIS_SCG_0_CLK_DIVIDER_SLOW, 2, 8,
"Invalid SCG slow clock divider value");
ASSERT_WITHIN_RANGE(DT_NXP_KINETIS_SCG_0_CLK_DIVIDER_BUS, 1, 16,
"Invalid SCG bus clock divider value");
#if DT_NXP_KINETIS_SCG_0_CLK_SOURCE == KINETIS_SCG_SCLK_SRC_SPLL
/* Core divider range is 1 to 4 with SPLL as clock source */
ASSERT_WITHIN_RANGE(DT_NXP_KINETIS_SCG_0_CLK_DIVIDER_CORE, 1, 4,
"Invalid SCG core clock divider value");
#else
ASSERT_WITHIN_RANGE(DT_NXP_KINETIS_SCG_0_CLK_DIVIDER_CORE, 1, 16,
"Invalid SCG core clock divider value");
#endif
static const scg_sys_clk_config_t scg_sys_clk_config = {
.divSlow = TO_SYS_CLK_DIV(DT_NXP_KINETIS_SCG_0_CLK_DIVIDER_SLOW),
.divBus = TO_SYS_CLK_DIV(DT_NXP_KINETIS_SCG_0_CLK_DIVIDER_BUS),
.divCore = TO_SYS_CLK_DIV(DT_NXP_KINETIS_SCG_0_CLK_DIVIDER_CORE),
.src = DT_NXP_KINETIS_SCG_0_CLK_SOURCE
};
#ifdef DT_NXP_KINETIS_SCG_0_SOSC_FREQ
/* System Oscillator (SOSC) configuration */
ASSERT_ASYNC_CLK_DIV_VALID(DT_NXP_KINETIS_SCG_0_SOSC_DIVIDER_1,
"Invalid SCG SOSC divider 1 value");
ASSERT_ASYNC_CLK_DIV_VALID(DT_NXP_KINETIS_SCG_0_SOSC_DIVIDER_2,
"Invalid SCG SOSC divider 2 value");
static const scg_sosc_config_t scg_sosc_config = {
.freq = DT_NXP_KINETIS_SCG_0_SOSC_FREQ,
.monitorMode = kSCG_SysOscMonitorDisable,
.enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableInLowPower,
.div1 = TO_ASYNC_CLK_DIV(DT_NXP_KINETIS_SCG_0_SOSC_DIVIDER_1),
.div2 = TO_ASYNC_CLK_DIV(DT_NXP_KINETIS_SCG_0_SOSC_DIVIDER_2),
.workMode = DT_NXP_KINETIS_SCG_0_SOSC_MODE
};
#endif /* DT_NXP_KINETIS_SCG_0_SOSC_FREQ */
/* Slow Internal Reference Clock (SIRC) configuration */
ASSERT_ASYNC_CLK_DIV_VALID(DT_NXP_KINETIS_SCG_0_SIRC_DIVIDER_1,
"Invalid SCG SIRC divider 1 value");
ASSERT_ASYNC_CLK_DIV_VALID(DT_NXP_KINETIS_SCG_0_SIRC_DIVIDER_2,
"Invalid SCG SIRC divider 2 value");
static const scg_sirc_config_t scg_sirc_config = {
.enableMode = kSCG_SircEnable,
.div1 = TO_ASYNC_CLK_DIV(DT_NXP_KINETIS_SCG_0_SIRC_DIVIDER_1),
.div2 = TO_ASYNC_CLK_DIV(DT_NXP_KINETIS_SCG_0_SIRC_DIVIDER_2),
#if MHZ(2) == DT_NXP_KINETIS_SCG_0_SIRC_RANGE
.range = kSCG_SircRangeLow
#elif MHZ(8) == DT_NXP_KINETIS_SCG_0_SIRC_RANGE
.range = kSCG_SircRangeHigh
#else
#error Invalid SCG SIRC range
#endif
};
/* Fast Internal Reference Clock (FIRC) configuration */
ASSERT_ASYNC_CLK_DIV_VALID(DT_NXP_KINETIS_SCG_0_FIRC_DIVIDER_1,
"Invalid SCG FIRC divider 1 value");
ASSERT_ASYNC_CLK_DIV_VALID(DT_NXP_KINETIS_SCG_0_FIRC_DIVIDER_2,
"Invalid SCG FIRC divider 2 value");
static const scg_firc_config_t scg_firc_config = {
.enableMode = kSCG_FircEnable,
.div1 = TO_ASYNC_CLK_DIV(DT_NXP_KINETIS_SCG_0_FIRC_DIVIDER_1),
.div2 = TO_ASYNC_CLK_DIV(DT_NXP_KINETIS_SCG_0_FIRC_DIVIDER_2),
#if MHZ(48) == DT_NXP_KINETIS_SCG_0_FIRC_RANGE
.range = kSCG_FircRange48M,
#elif MHZ(52) == DT_NXP_KINETIS_SCG_0_FIRC_RANGE
.range = kSCG_FircRange52M,
#elif MHZ(56) == DT_NXP_KINETIS_SCG_0_FIRC_RANGE
.range = kSCG_FircRange56M,
#elif MHZ(60) == DT_NXP_KINETIS_SCG_0_FIRC_RANGE
.range = kSCG_FircRange60M,
#else
#error Invalid SCG FIRC range
#endif
.trimConfig = NULL
};
/* System Phase-Locked Loop (SPLL) configuration */
ASSERT_ASYNC_CLK_DIV_VALID(DT_NXP_KINETIS_SCG_0_SPLL_DIVIDER_1,
"Invalid SCG SPLL divider 1 value");
ASSERT_ASYNC_CLK_DIV_VALID(DT_NXP_KINETIS_SCG_0_SPLL_DIVIDER_2,
"Invalid SCG SPLL divider 2 value");
ASSERT_WITHIN_RANGE(DT_NXP_KINETIS_SCG_0_SPLL_DIVIDER_PRE, 1, 8,
"Invalid SCG SPLL pre divider value");
ASSERT_WITHIN_RANGE(DT_NXP_KINETIS_SCG_0_SPLL_MULTIPLIER, 16, 47,
"Invalid SCG SPLL multiplier value");
static const scg_spll_config_t scg_spll_config = {
.enableMode = kSCG_SysPllEnable,
.monitorMode = kSCG_SysPllMonitorDisable,
.div1 = TO_ASYNC_CLK_DIV(DT_NXP_KINETIS_SCG_0_SPLL_DIVIDER_1),
.div2 = TO_ASYNC_CLK_DIV(DT_NXP_KINETIS_SCG_0_SPLL_DIVIDER_2),
#if DT_NXP_KINETIS_SCG_0_SPLL_SOURCE == KINETIS_SCG_SPLL_SRC_SOSC
.src = kSCG_SysPllSrcSysOsc,
#elif DT_NXP_KINETIS_SCG_0_SPLL_SOURCE == KINETIS_SCG_SPLL_SRC_FIRC
.src = kSCG_SysPllSrcFirc,
#else
#error Invalid SCG SPLL source
#endif
.prediv = (DT_NXP_KINETIS_SCG_0_SPLL_DIVIDER_PRE - 1U),
.mult = (DT_NXP_KINETIS_SCG_0_SPLL_MULTIPLIER - 16U)
};
static ALWAYS_INLINE void clk_init(void)
{
const scg_sys_clk_config_t scg_sys_clk_config_safe = {
.divSlow = kSCG_SysClkDivBy4,
.divBus = kSCG_SysClkDivBy1,
.divCore = kSCG_SysClkDivBy1,
.src = kSCG_SysClkSrcSirc
};
scg_sys_clk_config_t current;
#ifdef DT_NXP_KINETIS_SCG_0_SOSC_FREQ
/* Optionally initialize system oscillator */
CLOCK_InitSysOsc(&scg_sosc_config);
CLOCK_SetXtal0Freq(scg_sosc_config.freq);
#endif
/* Configure SIRC */
CLOCK_InitSirc(&scg_sirc_config);
/* Temporary switch to safe SIRC in order to configure FIRC */
CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config_safe);
do {
CLOCK_GetCurSysClkConfig(&current);
} while (current.src != scg_sys_clk_config_safe.src);
CLOCK_InitFirc(&scg_firc_config);
/* Configure System PLL */
CLOCK_InitSysPll(&scg_spll_config);
/* Only RUN mode supported for now */
CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config);
do {
CLOCK_GetCurSysClkConfig(&current);
} while (current.src != scg_sys_clk_config.src);
#ifdef CONFIG_UART_MCUX_LPUART_0
CLOCK_SetIpSrc(kCLOCK_Lpuart0, kCLOCK_IpSrcFircAsync);
#endif
#ifdef CONFIG_UART_MCUX_LPUART_1
CLOCK_SetIpSrc(kCLOCK_Lpuart1, kCLOCK_IpSrcFircAsync);
#endif
#ifdef CONFIG_UART_MCUX_LPUART_2
CLOCK_SetIpSrc(kCLOCK_Lpuart2, kCLOCK_IpSrcFircAsync);
#endif
#ifdef DT_NXP_KINETIS_SCG_0_CLKOUT_SOURCE
CLOCK_SetClkOutSel(DT_NXP_KINETIS_SCG_0_CLKOUT_SOURCE);
#endif
}
static int ke1xf_init(struct device *arg)
{
ARG_UNUSED(arg);
unsigned int old_level; /* old interrupt lock level */
#if !defined(CONFIG_ARM_MPU)
u32_t temp_reg;
#endif /* !CONFIG_ARM_MPU */
/* Disable interrupts */
old_level = irq_lock();
#if !defined(CONFIG_ARM_MPU)
/*
* Disable memory protection and clear slave port errors.
* Note that the KE1xF does not implement the optional ARMv7-M memory
* protection unit (MPU), specified by the architecture (PMSAv7), in the
* Cortex-M4 core. Instead, the processor includes its own MPU module.
*/
temp_reg = SYSMPU->CESR;
temp_reg &= ~SYSMPU_CESR_VLD_MASK;
temp_reg |= SYSMPU_CESR_SPERR_MASK;
SYSMPU->CESR = temp_reg;
#endif /* !CONFIG_ARM_MPU */
z_clearfaults();
/* Initialize system clocks and PLL */
clk_init();
/*
* Install default handler that simply resets the CPU if
* configured in the kernel, NOP otherwise
*/
NMI_INIT();
/* Restore interrupt state */
irq_unlock(old_level);
return 0;
}
void _WdogInit(void)
{
/*
* NOTE: DO NOT SINGLE STEP THROUGH THIS FUNCTION!!! Watchdog
* reconfiguration must take place within 128 bus clocks from
* unlocking. Single stepping through the code will cause the
* watchdog to close the unlock window again.
*/
/* Unlock watchdog to enable reconfiguration after bootloader */
WDOG->CNT = WDOG_UPDATE_KEY;
while (!(WDOG->CS & WDOG_CS_ULK_MASK)) {
;
}
/*
* Watchdog reconfiguration only takes effect after writing to
* both TOVAL and CS registers.
*/
WDOG->TOVAL = 1024;
WDOG->CS = WDOG_CS_EN(0) | WDOG_CS_UPDATE(1);
while (!(WDOG->CS & WDOG_CS_RCS_MASK)) {
;
}
}
SYS_INIT(ke1xf_init, PRE_KERNEL_1, 0);

View file

@ -0,0 +1,12 @@
/*
* Copyright (c) 2019 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SOC__H_
#define _SOC__H_
#include <misc/util.h>
#endif /* _SOC__H_ */