diff --git a/compiler/arm-none-eabi-m33/compiler.yml b/compiler/arm-none-eabi-m33/compiler.yml index 4fd085fc8b..654a53c3e6 100644 --- a/compiler/arm-none-eabi-m33/compiler.yml +++ b/compiler/arm-none-eabi-m33/compiler.yml @@ -26,6 +26,7 @@ compiler.path.objsize: arm-none-eabi-size compiler.path.objcopy: arm-none-eabi-objcopy compiler.flags.base: -mcpu=cortex-m33+nodsp -mthumb-interwork -mthumb -Wall -Werror -fno-exceptions -ffunction-sections -fdata-sections -fno-common + #-E -P compiler.flags.default: [compiler.flags.base, -O1, -ggdb] compiler.flags.optimized: [compiler.flags.base, -Os, -ggdb] compiler.flags.speed: [compiler.flags.base, -O3, -ggdb] diff --git a/hw/bsp/nordic_pca10095/boot-nrf5340.ld b/hw/bsp/nordic_pca10095/boot-nrf5340.ld index 1d60514633..839b1ef26b 100644 --- a/hw/bsp/nordic_pca10095/boot-nrf5340.ld +++ b/hw/bsp/nordic_pca10095/boot-nrf5340.ld @@ -20,6 +20,8 @@ MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x8000 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x80000 + sram_ipc0_tx (rw) : ORIGIN = 0x20070000, LENGTH = 0x4000 + sram_ipc0_rx (rw) : ORIGIN = 0x20074000, LENGTH = 0x4000 } /* The bootloader does not contain an image header */ diff --git a/hw/bsp/nordic_pca10095/nrf5340.ld b/hw/bsp/nordic_pca10095/nrf5340.ld index 6ee5122a54..82e41d1cad 100644 --- a/hw/bsp/nordic_pca10095/nrf5340.ld +++ b/hw/bsp/nordic_pca10095/nrf5340.ld @@ -20,6 +20,8 @@ MEMORY { FLASH (rx) : ORIGIN = 0x0000c000, LENGTH = 0x76000 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x80000 + sram_ipc0_tx (rw) : ORIGIN = 0x20070000, LENGTH = 0x4000 + sram_ipc0_rx (rw) : ORIGIN = 0x20074000, LENGTH = 0x4000 } /* This linker script is used for images and thus contains an image header */ diff --git a/hw/bsp/nordic_pca10095/syscfg.yml b/hw/bsp/nordic_pca10095/syscfg.yml index 33292f7e8f..50dfefb58f 100644 --- a/hw/bsp/nordic_pca10095/syscfg.yml +++ b/hw/bsp/nordic_pca10095/syscfg.yml @@ -108,15 +108,30 @@ syscfg.vals.BLE_TRANSPORT: BLE_TRANSPORT_LL: nrf5340 syscfg.vals.BSP_NRF5340_NET_ENABLE: - BSP_NRF5340_NET_FLASH_ENABLE: 1 BLE_HCI_VS: 1 +syscfg.vals.'BSP_NRF5340_NET_ENABLE && BLE_TRANSPORT_LL != "ipc"': + BSP_NRF5340_NET_FLASH_ENABLE: 1 + syscfg.vals.BSP_NRF5340_NET_FLASH_ENABLE: IPC_NRF5340_CHANNELS: 4 syscfg.vals.IPC_NRF5340_FLASH_CLIENT: HAL_FLASH_MAX_DEVICE_COUNT: 3 +syscfg.vals.'BLE_TRANSPORT_LL=="ipc" || BLE_TRANSPORT_IPC_BACKEND=="icbmsg"': + # The APP core have the same values but switched directions + BLE_TRANSPORT_IPC_TX_CHANNEL: 0 + BLE_TRANSPORT_IPC_RX_CHANNEL: 1 + IPC_SYNC_TX_CHANNEL: 0 + IPC_SYNC_RX_CHANNEL: 1 + IPC_ICBMSG_TX_REGION_NAME: "\".ipc0_tx\"" + IPC_ICBMSG_RX_REGION_NAME: "\".ipc0_rx\"" + IPC_ICBMSG_NUM_TX_BLOCKS: 16 + IPC_ICBMSG_NUM_RX_BLOCKS: 24 + IPC_ICBMSG_TX_REGION_SIZE: 0x4000 + IPC_ICBMSG_RX_REGION_SIZE: 0x4000 + syscfg.restrictions.BSP_NRF5340_NET_FLASH_ENABLE: - 'IPC_NRF5340_CHANNELS >= 4' diff --git a/hw/bsp/nordic_pca10095_net/boot-nrf5340_net.ld b/hw/bsp/nordic_pca10095_net/boot-nrf5340_net.ld index 8a2a152fca..629cbb360a 100644 --- a/hw/bsp/nordic_pca10095_net/boot-nrf5340_net.ld +++ b/hw/bsp/nordic_pca10095_net/boot-nrf5340_net.ld @@ -21,6 +21,8 @@ MEMORY FLASH (rx) : ORIGIN = 0x01000000, LENGTH = 0x4000 RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x10000 IPC (rw) : ORIGIN = 0x20000400, LENGTH = 0x400 + sram_ipc0_tx (rw) : ORIGIN = 0x20070000, LENGTH = 0x4000 + sram_ipc0_rx (rw) : ORIGIN = 0x20074000, LENGTH = 0x4000 } /* The bootloader does not contain an image header */ diff --git a/hw/bsp/nordic_pca10095_net/nrf5340_net.ld b/hw/bsp/nordic_pca10095_net/nrf5340_net.ld index 91bfe1c497..b28ab837ff 100644 --- a/hw/bsp/nordic_pca10095_net/nrf5340_net.ld +++ b/hw/bsp/nordic_pca10095_net/nrf5340_net.ld @@ -21,6 +21,8 @@ MEMORY FLASH (rx) : ORIGIN = 0x01008000, LENGTH = 0x30000 RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x10000 IPC (rw) : ORIGIN = 0x20000400, LENGTH = 0x400 + sram_ipc0_tx (rw) : ORIGIN = 0x20070000, LENGTH = 0x4000 + sram_ipc0_rx (rw) : ORIGIN = 0x20074000, LENGTH = 0x4000 } /* This linker script is used for images and thus contains an image header */ diff --git a/hw/bsp/nordic_pca10095_net/pkg.yml b/hw/bsp/nordic_pca10095_net/pkg.yml index 8e6ce7dc6f..e6ccea70ea 100644 --- a/hw/bsp/nordic_pca10095_net/pkg.yml +++ b/hw/bsp/nordic_pca10095_net/pkg.yml @@ -34,5 +34,7 @@ pkg.deps: - "@apache-mynewt-core/hw/scripts" - "@apache-mynewt-core/hw/mcu/nordic/nrf5340_net" - "@apache-mynewt-core/libc" + +pkg.deps.'BLE_TRANSPORT == 1 && BLE_TRANSPORT_HS != "ipc"': - "@apache-mynewt-core/sys/flash_map" - "@apache-mynewt-core/hw/drivers/flash/ipc_nrf5340_flash" diff --git a/hw/bsp/nordic_pca10095_net/syscfg.yml b/hw/bsp/nordic_pca10095_net/syscfg.yml index 915b502cfc..5f61e9d6f0 100644 --- a/hw/bsp/nordic_pca10095_net/syscfg.yml +++ b/hw/bsp/nordic_pca10095_net/syscfg.yml @@ -79,3 +79,16 @@ syscfg.vals.BLE_CONTROLLER: syscfg.vals.BLE_TRANSPORT: BLE_TRANSPORT_HS: nrf5340 + +syscfg.vals.'BLE_TRANSPORT_HS=="ipc" || BLE_TRANSPORT_IPC_BACKEND=="icbmsg"': + # The APP core have the same values but switched directions + BLE_TRANSPORT_IPC_TX_CHANNEL: 1 + BLE_TRANSPORT_IPC_RX_CHANNEL: 0 + IPC_SYNC_TX_CHANNEL: 1 + IPC_SYNC_RX_CHANNEL: 0 + IPC_ICBMSG_TX_REGION_NAME: "\".ipc0_rx\"" + IPC_ICBMSG_RX_REGION_NAME: "\".ipc0_tx\"" + IPC_ICBMSG_NUM_TX_BLOCKS: 24 + IPC_ICBMSG_NUM_RX_BLOCKS: 16 + IPC_ICBMSG_TX_REGION_SIZE: 0x4000 + IPC_ICBMSG_RX_REGION_SIZE: 0x4000 diff --git a/hw/bsp/nordic_pca10175/boot-nrf54h20.ld b/hw/bsp/nordic_pca10175/boot-nrf54h20.ld new file mode 100644 index 0000000000..8a2a152fca --- /dev/null +++ b/hw/bsp/nordic_pca10175/boot-nrf54h20.ld @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x01000000, LENGTH = 0x4000 + RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x10000 + IPC (rw) : ORIGIN = 0x20000400, LENGTH = 0x400 +} + +/* The bootloader does not contain an image header */ +_imghdr_size = 0x0; diff --git a/hw/bsp/nordic_pca10175/bsp.yml b/hw/bsp/nordic_pca10175/bsp.yml new file mode 100644 index 0000000000..9b176425b3 --- /dev/null +++ b/hw/bsp/nordic_pca10175/bsp.yml @@ -0,0 +1,72 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +bsp.name: "nRF54H20 DK (Net Core)" +bsp.url: https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF54H20-DK +bsp.maker: "Nordic Semiconductor" +bsp.arch: cortex_m33 +bsp.exclude_site: 1 +bsp.compiler: "@apache-mynewt-core/compiler/arm-none-eabi-m33" +bsp.linkerscript: + - "hw/bsp/nordic_pca10175/nrf54h20.ld" + - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20/nrf54h20.ld" +bsp.linkerscript.BOOT_LOADER.OVERWRITE: + - "hw/bsp/nordic_pca10175/boot-nrf54h20.ld" + - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20/nrf54h20.ld" +bsp.part2linkerscript: "hw/bsp/nordic_pca10175/split-nordic_pca10175.ld" +bsp.downloadscript: "hw/scripts/download.sh" +bsp.debugscript: "hw/bsp/nordic_pca10175/nordic_pca10175_debug.sh" + +bsp.flash_map: + areas: + # System areas. + FLASH_AREA_BOOTLOADER: + device: 0 + offset: 0x01000000 + size: 16kB + FLASH_AREA_IMAGE_0: + device: 0 + offset: 0x01008000 + size: 128kB + FLASH_AREA_COREDUMP: + user_id: 2 + device: 0 + offset: 0x01028000 + size: 68kB + # This maps to app flash and uses vflash + FLASH_AREA_IMAGE_1: + device: 1 + offset: 0x00000000 + size: 128kB + FLASH_AREA_IMAGE_SCRATCH: + device: 0 + offset: 0x0103a000 + size: 8kB + + # User areas. + FLASH_AREA_REBOOT_LOG: + user_id: 0 + device: 0 + offset: 0x01004000 + size: 16kB + FLASH_AREA_NFFS: + user_id: 1 + device: 0 + offset: 0x010fc000 + size: 16kB diff --git a/hw/bsp/nordic_pca10175/include/bsp/bsp.h b/hw/bsp/nordic_pca10175/include/bsp/bsp.h new file mode 100644 index 0000000000..7773711b83 --- /dev/null +++ b/hw/bsp/nordic_pca10175/include/bsp/bsp.h @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _BSP_H_ +#define _BSP_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define special stackos sections */ +#define sec_data_core __attribute__((section(".data.core"))) +#define sec_bss_core __attribute__((section(".bss.core"))) +#define sec_bss_nz_core __attribute__((section(".bss.core.nz"))) + +/* More convenient section placement macros. */ +#define bssnz_t sec_bss_nz_core + +extern uint8_t _ram_start; +#define RAM_SIZE 0x10000 + +/* LED pins */ +#define LED_1 (288) +#define LED_2 (289) +#define LED_3 (290) +#define LED_4 (291) +#define LED_BLINK_PIN (LED_3) + +/* Buttons */ +#define BUTTON_1 (8) +#define BUTTON_2 (9) +#define BUTTON_3 (10) +#define BUTTON_4 (11) + +/* Arduino pins */ +#define ARDUINO_PIN_D0 32 +#define ARDUINO_PIN_D1 33 +#define ARDUINO_PIN_D2 36 +#define ARDUINO_PIN_D3 37 +#define ARDUINO_PIN_D4 38 +#define ARDUINO_PIN_D5 39 +#define ARDUINO_PIN_D6 40 +#define ARDUINO_PIN_D7 41 +#define ARDUINO_PIN_D8 42 +#define ARDUINO_PIN_D9 43 +#define ARDUINO_PIN_D10 44 +#define ARDUINO_PIN_D11 45 +#define ARDUINO_PIN_D12 46 +#define ARDUINO_PIN_D13 47 +#define ARDUINO_PIN_A0 4 +#define ARDUINO_PIN_A1 5 +#define ARDUINO_PIN_A2 6 +#define ARDUINO_PIN_A3 7 +#define ARDUINO_PIN_A4 25 +#define ARDUINO_PIN_A5 26 + +#define ARDUINO_PIN_RX ARDUINO_PIN_D0 +#define ARDUINO_PIN_TX ARDUINO_PIN_D1 + +#define ARDUINO_PIN_SCL 35 +#define ARDUINO_PIN_SDA 34 + +#define ARDUINO_PIN_SCK ARDUINO_PIN_D13 +#define ARDUINO_PIN_MOSI ARDUINO_PIN_D11 +#define ARDUINO_PIN_MISO ARDUINO_PIN_D12 + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_H_ */ diff --git a/hw/bsp/nordic_pca10175/nordic_pca10175_debug.sh b/hw/bsp/nordic_pca10175/nordic_pca10175_debug.sh new file mode 100755 index 0000000000..86abde52db --- /dev/null +++ b/hw/bsp/nordic_pca10175/nordic_pca10175_debug.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Called with following variables set: +# - CORE_PATH is absolute path to @apache-mynewt-core +# - BSP_PATH is absolute path to hw/bsp/bsp_name +# - BIN_BASENAME is the path to prefix to target binary, +# .elf appended to name is the ELF file +# - FEATURES holds the target features string +# - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software +# - RESET set if target should be reset when attaching +# - NO_GDB set if we should not start gdb to debug +# + +#Use custom ports for debuging so that newt debug works on both cores +EXTRA_JTAG_CMD="-port 3333" + +. $CORE_PATH/hw/scripts/jlink.sh + +FILE_NAME=$BIN_BASENAME.elf +JLINK_DEV="nrf54h20_xxaa_app" + +jlink_debug + diff --git a/hw/bsp/nordic_pca10175/nordic_pca10175_download.sh b/hw/bsp/nordic_pca10175/nordic_pca10175_download.sh new file mode 100755 index 0000000000..27afb9fbbb --- /dev/null +++ b/hw/bsp/nordic_pca10175/nordic_pca10175_download.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Called with following variables set: +# - CORE_PATH is absolute path to @apache-mynewt-core +# - BSP_PATH is absolute path to hw/bsp/bsp_name +# - BIN_BASENAME is the path to prefix to target binary, +# .elf appended to name is the ELF file +# - IMAGE_SLOT is the image slot to download to (for non-mfg-image, non-boot) +# - FEATURES holds the target features string +# - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software +# - MFG_IMAGE is "1" if this is a manufacturing image +# - FLASH_OFFSET contains the flash offset to download to +# - BOOT_LOADER is set if downloading a bootloader + +. $CORE_PATH/hw/scripts/jlink.sh + +if [ "$MFG_IMAGE" ]; then + FLASH_OFFSET=0x01000000 +fi + +JLINK_DEV="nrf54h20_xxaa_app" + +common_file_to_load +jlink_load diff --git a/hw/bsp/nordic_pca10175/nordic_pca10175_no_boot.ld b/hw/bsp/nordic_pca10175/nordic_pca10175_no_boot.ld new file mode 100644 index 0000000000..1b0dd456d3 --- /dev/null +++ b/hw/bsp/nordic_pca10175/nordic_pca10175_no_boot.ld @@ -0,0 +1,195 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x010000000, LENGTH = 0x40000 + RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x10000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + __text = .; + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + +INCLUDE "link_tables.ld.h" + *(.rodata*) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + *(.preinit_array) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + *(SORT(.init_array.*)) + *(.init_array) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM + + /* Non-zeroed BSS. This section is similar to BSS, with the following + * caveat: + * 1. It does not get zeroed at init-time. + */ + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} + diff --git a/hw/bsp/nordic_pca10175/nrf54h20.ld b/hw/bsp/nordic_pca10175/nrf54h20.ld new file mode 100644 index 0000000000..b28ab837ff --- /dev/null +++ b/hw/bsp/nordic_pca10175/nrf54h20.ld @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x01008000, LENGTH = 0x30000 + RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x10000 + IPC (rw) : ORIGIN = 0x20000400, LENGTH = 0x400 + sram_ipc0_tx (rw) : ORIGIN = 0x20070000, LENGTH = 0x4000 + sram_ipc0_rx (rw) : ORIGIN = 0x20074000, LENGTH = 0x4000 +} + +/* This linker script is used for images and thus contains an image header */ +_imghdr_size = 0x20; diff --git a/hw/bsp/nordic_pca10175/pkg.yml b/hw/bsp/nordic_pca10175/pkg.yml new file mode 100644 index 0000000000..fedd02a9b7 --- /dev/null +++ b/hw/bsp/nordic_pca10175/pkg.yml @@ -0,0 +1,44 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/bsp/nordic_pca10175 +pkg.type: bsp +pkg.description: BSP definition for the Nordic PCA10175 (nRF54h20 DK) - App Core +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - nrf54h20 + - nordic + - pca10175 + +pkg.init.TRNG: + hal_bsp_init_trng: 2 + +pkg.cflags: + - '-DNRF54H20_XXAA' + - '-DNRF_APPLICATION' + +pkg.deps: + - "@apache-mynewt-core/hw/scripts" + - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20" + - "@apache-mynewt-core/libc" + +# pkg.deps.'BLE_TRANSPORT_HS != "ipc"': +# - "@apache-mynewt-core/sys/flash_map" +# - "@apache-mynewt-core/hw/drivers/flash/ipc_nrf54h20_flash" diff --git a/hw/bsp/nordic_pca10175/src/hal_bsp.c b/hw/bsp/nordic_pca10175/src/hal_bsp.c new file mode 100644 index 0000000000..f7ee6c9dde --- /dev/null +++ b/hw/bsp/nordic_pca10175/src/hal_bsp.c @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * What memory to include in coredump. + */ +#if !MYNEWT_VAL(COREDUMP_SKIP_UNUSED_HEAP) +static const struct hal_bsp_mem_dump dump_cfg[] = { + [0] = { + .hbmd_start = &_ram_start, + .hbmd_size = RAM_SIZE + } +}; +#else +static struct hal_bsp_mem_dump dump_cfg[2]; +extern uint8_t __StackLimit; +extern uint8_t __StackTop; +#endif + +const struct hal_flash * +hal_bsp_flash_dev(uint8_t id) +{ + /* + * Internal flash mapped to id 0. + */ +// if (id == 0) { +// return &nrf54h20_flash_dev; +// } +//#if MCUBOOT_MYNEWT +// if (id == 1) { +// return &nrf54h20_vflash_dev.nv_flash; +// } +//#endif +//#if MYNEWT_VAL(IPC_NRF54H20_FLASH_CLIENT) +// if (id == 2) { +// return ipc_flash(); +// } +//#endif + + return NULL; +} + +const struct hal_bsp_mem_dump * +hal_bsp_core_dump(int *area_cnt) +{ +#if MYNEWT_VAL(COREDUMP_SKIP_UNUSED_HEAP) + /* Interrupt stack first */ + dump_cfg[0].hbmd_start = &__StackLimit; + dump_cfg[0].hbmd_size = &__StackTop - &__StackLimit; + /* RAM from _ram_start to end of used heap */ + dump_cfg[1].hbmd_start = &_ram_start; + dump_cfg[1].hbmd_size = (uint8_t *)_sbrk(0) - &_ram_start; +#endif + + *area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]); + return dump_cfg; +} + +int +hal_bsp_power_state(int state) +{ + return 0; +} + +void +hal_bsp_init(void) +{ + /* Make sure system clocks have started */ + hal_system_clock_start(); + + /* Create all available nRF54H20 Net Core peripherals */ + nrf54h20_periph_create(); +} + +void +hal_bsp_deinit(void) +{ +} diff --git a/hw/bsp/nordic_pca10175/syscfg.yml b/hw/bsp/nordic_pca10175/syscfg.yml new file mode 100644 index 0000000000..44e284697b --- /dev/null +++ b/hw/bsp/nordic_pca10175/syscfg.yml @@ -0,0 +1,92 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + # BLE_TRANSPORT_RADIOCORE? +# BLE_TRANSPORT_NETCORE: 1 + + BSP_NRF54_RAD: + description: 'Set to indicate that BSP has NRF54h20 RAD' + value: 0 + + COREDUMP_SKIP_UNUSED_HEAP: + description: > + Store whole RAM in crash dump. + When 1 only part of heap that was used will be dumped, that + can reduce size of crash dump. + value: 0 + +syscfg.vals: + MYNEWT_DOWNLOADER: nrfjprog + JLINK_TARGET: NRF5340_XXAA_NET + NRFJPROG_COPROCESSOR: CP_NETWORK + # Set default pins for peripherals + UART_0_PIN_TX: 20 + UART_0_PIN_RX: 22 + UART_0_PIN_RTS: 19 + UART_0_PIN_CTS: 21 + + SPI_0_MASTER_PIN_SCK: 45 + SPI_0_MASTER_PIN_MOSI: 46 + SPI_0_MASTER_PIN_MISO: 47 + SPI_0_SLAVE_PIN_SCK: 45 + SPI_0_SLAVE_PIN_MOSI: 46 + SPI_0_SLAVE_PIN_MISO: 47 + SPI_0_SLAVE_PIN_SS: 44 + + I2C_0_PIN_SCL: ARDUINO_PIN_A5 + I2C_0_PIN_SDA: ARDUINO_PIN_A4 + + CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS + REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG + NFFS_FLASH_AREA: FLASH_AREA_NFFS + COREDUMP_FLASH_AREA: FLASH_AREA_COREDUMP + #Net Core DCDC is enabled from application core + #MCU_DCDC_ENABLED: 1 + MCU_LFCLK_SOURCE: LFXO + FLASH_MAP_SYSINIT_STAGE: 15 + + # Always use non-blocking API + SPI_HAL_USE_NOBLOCK: 1 + + # nRF5340 Network Core doesn't have floating point unit + HARDFLOAT: 0 + + TRNG: 0 + + TIMER_0: 0 + TIMER_3: 1 + OS_CPUTIME_FREQ: 32768 + OS_CPUTIME_TIMER_NUM: 3 + +syscfg.vals.BLE_CONTROLLER: + BLE_TRANSPORT_HS: ipc + BLE_LL_RFMGMT_ENABLE_TIME: 1500 + BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: 1 + +syscfg.vals.BLE_TRANSPORT: + + # The APP core has the same values but switched directions + BLE_TRANSPORT_IPC_TX_CHANNEL: 12 + BLE_TRANSPORT_IPC_RX_CHANNEL: 18 + IPC_SYNC_TX_CHANNEL: 12 + IPC_SYNC_RX_CHANNEL: 18 + IPC_ICBMSG_TX_REGION_NAME: "\".ipc0_tx\"" + IPC_ICBMSG_RX_REGION_NAME: "\".ipc0_rx\"" + IPC_ICBMSG_NUM_TX_BLOCKS: 32 + IPC_ICBMSG_NUM_RX_BLOCKS: 32 diff --git a/hw/bsp/nordic_pca10175_rad/boot-nrf54h20_rad.ld b/hw/bsp/nordic_pca10175_rad/boot-nrf54h20_rad.ld new file mode 100644 index 0000000000..8a2a152fca --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/boot-nrf54h20_rad.ld @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x01000000, LENGTH = 0x4000 + RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x10000 + IPC (rw) : ORIGIN = 0x20000400, LENGTH = 0x400 +} + +/* The bootloader does not contain an image header */ +_imghdr_size = 0x0; diff --git a/hw/bsp/nordic_pca10175_rad/bsp.yml b/hw/bsp/nordic_pca10175_rad/bsp.yml new file mode 100644 index 0000000000..1a9df80abe --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/bsp.yml @@ -0,0 +1,72 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +bsp.name: "nRF54H20 DK (Net Core)" +bsp.url: https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF54H20-DK +bsp.maker: "Nordic Semiconductor" +bsp.arch: cortex_m33 +bsp.exclude_site: 1 +bsp.compiler: "@apache-mynewt-core/compiler/arm-none-eabi-m33" +bsp.linkerscript: + - "hw/bsp/nordic_pca10175_rad/nrf54h20_rad.ld" + - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20_rad/nrf54h20_rad.ld" +bsp.linkerscript.BOOT_LOADER.OVERWRITE: + - "hw/bsp/nordic_pca10175_rad/boot-nrf54h20_rad.ld" + - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20_rad/nrf54h20_rad.ld" +bsp.part2linkerscript: "hw/bsp/nordic_pca10175_rad/split-nordic_pca10175_rad.ld" +bsp.downloadscript: "hw/scripts/download.sh" +bsp.debugscript: "hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_debug.sh" + +bsp.flash_map: + areas: + # System areas. + FLASH_AREA_BOOTLOADER: + device: 0 + offset: 0x01000000 + size: 16kB + FLASH_AREA_IMAGE_0: + device: 0 + offset: 0x01008000 + size: 128kB + FLASH_AREA_COREDUMP: + user_id: 2 + device: 0 + offset: 0x01028000 + size: 68kB + # This maps to app flash and uses vflash + FLASH_AREA_IMAGE_1: + device: 1 + offset: 0x00000000 + size: 128kB + FLASH_AREA_IMAGE_SCRATCH: + device: 0 + offset: 0x0103a000 + size: 8kB + + # User areas. + FLASH_AREA_REBOOT_LOG: + user_id: 0 + device: 0 + offset: 0x01004000 + size: 16kB + FLASH_AREA_NFFS: + user_id: 1 + device: 0 + offset: 0x010fc000 + size: 16kB diff --git a/hw/bsp/nordic_pca10175_rad/include/bsp/bsp.h b/hw/bsp/nordic_pca10175_rad/include/bsp/bsp.h new file mode 100644 index 0000000000..afe4e95da4 --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/include/bsp/bsp.h @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _BSP_H_ +#define _BSP_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define special stackos sections */ +#define sec_data_core __attribute__((section(".data.core"))) +#define sec_bss_core __attribute__((section(".bss.core"))) +#define sec_bss_nz_core __attribute__((section(".bss.core.nz"))) + +/* More convenient section placement macros. */ +#define bssnz_t sec_bss_nz_core + +extern uint8_t _ram_start; +#define RAM_SIZE 0x10000 + +/* LED pins */ +#define LED_1 (288) +#define LED_2 (289) +#define LED_3 (290) +#define LED_4 (291) +#define LED_BLINK_PIN (LED_2) + +/* Buttons */ +#define BUTTON_1 (8) +#define BUTTON_2 (9) +#define BUTTON_3 (10) +#define BUTTON_4 (11) + +/* Arduino pins */ +#define ARDUINO_PIN_D0 32 +#define ARDUINO_PIN_D1 33 +#define ARDUINO_PIN_D2 36 +#define ARDUINO_PIN_D3 37 +#define ARDUINO_PIN_D4 38 +#define ARDUINO_PIN_D5 39 +#define ARDUINO_PIN_D6 40 +#define ARDUINO_PIN_D7 41 +#define ARDUINO_PIN_D8 42 +#define ARDUINO_PIN_D9 43 +#define ARDUINO_PIN_D10 44 +#define ARDUINO_PIN_D11 45 +#define ARDUINO_PIN_D12 46 +#define ARDUINO_PIN_D13 47 +#define ARDUINO_PIN_A0 4 +#define ARDUINO_PIN_A1 5 +#define ARDUINO_PIN_A2 6 +#define ARDUINO_PIN_A3 7 +#define ARDUINO_PIN_A4 25 +#define ARDUINO_PIN_A5 26 + +#define ARDUINO_PIN_RX ARDUINO_PIN_D0 +#define ARDUINO_PIN_TX ARDUINO_PIN_D1 + +#define ARDUINO_PIN_SCL 35 +#define ARDUINO_PIN_SDA 34 + +#define ARDUINO_PIN_SCK ARDUINO_PIN_D13 +#define ARDUINO_PIN_MOSI ARDUINO_PIN_D11 +#define ARDUINO_PIN_MISO ARDUINO_PIN_D12 + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_H_ */ diff --git a/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_debug.sh b/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_debug.sh new file mode 100755 index 0000000000..5f6a50944a --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_debug.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Called with following variables set: +# - CORE_PATH is absolute path to @apache-mynewt-core +# - BSP_PATH is absolute path to hw/bsp/bsp_name +# - BIN_BASENAME is the path to prefix to target binary, +# .elf appended to name is the ELF file +# - FEATURES holds the target features string +# - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software +# - RESET set if target should be reset when attaching +# - NO_GDB set if we should not start gdb to debug +# + +#Use custom ports for debuging so that newt debug works on both cores +EXTRA_JTAG_CMD="-port 3334" + +. $CORE_PATH/hw/scripts/jlink.sh + +FILE_NAME=$BIN_BASENAME.elf +JLINK_DEV="nrf54h20_xxaa_rad" + +jlink_debug + diff --git a/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_download.sh b/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_download.sh new file mode 100755 index 0000000000..32d1cf7496 --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_download.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Called with following variables set: +# - CORE_PATH is absolute path to @apache-mynewt-core +# - BSP_PATH is absolute path to hw/bsp/bsp_name +# - BIN_BASENAME is the path to prefix to target binary, +# .elf appended to name is the ELF file +# - IMAGE_SLOT is the image slot to download to (for non-mfg-image, non-boot) +# - FEATURES holds the target features string +# - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software +# - MFG_IMAGE is "1" if this is a manufacturing image +# - FLASH_OFFSET contains the flash offset to download to +# - BOOT_LOADER is set if downloading a bootloader + +. $CORE_PATH/hw/scripts/jlink.sh + +if [ "$MFG_IMAGE" ]; then + FLASH_OFFSET=0x01000000 +fi + +JLINK_DEV="nrf54h20_xxaa_rad" + +common_file_to_load +jlink_load diff --git a/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_no_boot.ld b/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_no_boot.ld new file mode 100644 index 0000000000..1b0dd456d3 --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/nordic_pca10175_rad_no_boot.ld @@ -0,0 +1,195 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x010000000, LENGTH = 0x40000 + RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x10000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + __text = .; + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + +INCLUDE "link_tables.ld.h" + *(.rodata*) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + *(.preinit_array) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + *(SORT(.init_array.*)) + *(.init_array) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM + + /* Non-zeroed BSS. This section is similar to BSS, with the following + * caveat: + * 1. It does not get zeroed at init-time. + */ + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} + diff --git a/hw/bsp/nordic_pca10175_rad/nrf54h20_rad.ld b/hw/bsp/nordic_pca10175_rad/nrf54h20_rad.ld new file mode 100644 index 0000000000..b28ab837ff --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/nrf54h20_rad.ld @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x01008000, LENGTH = 0x30000 + RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x10000 + IPC (rw) : ORIGIN = 0x20000400, LENGTH = 0x400 + sram_ipc0_tx (rw) : ORIGIN = 0x20070000, LENGTH = 0x4000 + sram_ipc0_rx (rw) : ORIGIN = 0x20074000, LENGTH = 0x4000 +} + +/* This linker script is used for images and thus contains an image header */ +_imghdr_size = 0x20; diff --git a/hw/bsp/nordic_pca10175_rad/pkg.yml b/hw/bsp/nordic_pca10175_rad/pkg.yml new file mode 100644 index 0000000000..ba22f913f3 --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/pkg.yml @@ -0,0 +1,44 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/bsp/nordic_pca10175_rad +pkg.type: bsp +pkg.description: BSP definition for the Nordic PCA10175 (nRF54h20 DK) - Net Core +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - nrf54h20 + - nordic + - pca10175 + +pkg.init: + hal_bsp_init_trng: 2 + +pkg.cflags: + - '-DNRF54H20_XXAA' + - '-DNRF_RADIOCORE' + +pkg.deps: + - "@apache-mynewt-core/hw/scripts" + - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20_rad" + - "@apache-mynewt-core/libc" + +# pkg.deps.'BLE_TRANSPORT_HS != "ipc"': +# - "@apache-mynewt-core/sys/flash_map" +# - "@apache-mynewt-core/hw/drivers/flash/ipc_nrf54h20_flash" diff --git a/hw/bsp/nordic_pca10175_rad/src/hal_bsp.c b/hw/bsp/nordic_pca10175_rad/src/hal_bsp.c new file mode 100644 index 0000000000..a096deb80b --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/src/hal_bsp.c @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * What memory to include in coredump. + */ +#if !MYNEWT_VAL(COREDUMP_SKIP_UNUSED_HEAP) +static const struct hal_bsp_mem_dump dump_cfg[] = { + [0] = { + .hbmd_start = &_ram_start, + .hbmd_size = RAM_SIZE + } +}; +#else +static struct hal_bsp_mem_dump dump_cfg[2]; +extern uint8_t __StackLimit; +extern uint8_t __StackTop; +#endif + +const struct hal_flash * +hal_bsp_flash_dev(uint8_t id) +{ + /* + * Internal flash mapped to id 0. + */ +// if (id == 0) { +// return &nrf54h20_flash_dev; +// } +//#if MCUBOOT_MYNEWT +// if (id == 1) { +// return &nrf54h20_rad_vflash_dev.nv_flash; +// } +//#endif +//#if MYNEWT_VAL(IPC_NRF54H20_FLASH_CLIENT) +// if (id == 2) { +// return ipc_flash(); +// } +//#endif + + return NULL; +} + +const struct hal_bsp_mem_dump * +hal_bsp_core_dump(int *area_cnt) +{ +#if MYNEWT_VAL(COREDUMP_SKIP_UNUSED_HEAP) + /* Interrupt stack first */ + dump_cfg[0].hbmd_start = &__StackLimit; + dump_cfg[0].hbmd_size = &__StackTop - &__StackLimit; + /* RAM from _ram_start to end of used heap */ + dump_cfg[1].hbmd_start = &_ram_start; + dump_cfg[1].hbmd_size = (uint8_t *)_sbrk(0) - &_ram_start; +#endif + + *area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]); + return dump_cfg; +} + +int +hal_bsp_power_state(int state) +{ + return 0; +} + +void +hal_bsp_init(void) +{ + /* Make sure system clocks have started */ + hal_system_clock_start(); + + /* Create all available nRF54H20 Net Core peripherals */ + nrf54h20_rad_periph_create(); +} + +void +hal_bsp_deinit(void) +{ +} diff --git a/hw/bsp/nordic_pca10175_rad/syscfg.yml b/hw/bsp/nordic_pca10175_rad/syscfg.yml new file mode 100644 index 0000000000..764a8fc5c3 --- /dev/null +++ b/hw/bsp/nordic_pca10175_rad/syscfg.yml @@ -0,0 +1,89 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + # BLE_TRANSPORT_RADIOCORE? + BLE_TRANSPORT_NETCORE: 1 + + BSP_NRF54_RAD: + description: 'Set to indicate that BSP has NRF54h20 RAD' + value: 1 + + COREDUMP_SKIP_UNUSED_HEAP: + description: > + Store whole RAM in crash dump. + When 1 only part of heap that was used will be dumped, that + can reduce size of crash dump. + value: 0 + +syscfg.vals: + MYNEWT_DOWNLOADER: nrfjprog + JLINK_TARGET: NRF5340_XXAA_NET + NRFJPROG_COPROCESSOR: CP_NETWORK + # Set default pins for peripherals + UART_0_PIN_TX: 20 + UART_0_PIN_RX: 22 + UART_0_PIN_RTS: 19 + UART_0_PIN_CTS: 21 + + SPI_0_MASTER_PIN_SCK: 45 + SPI_0_MASTER_PIN_MOSI: 46 + SPI_0_MASTER_PIN_MISO: 47 + SPI_0_SLAVE_PIN_SCK: 45 + SPI_0_SLAVE_PIN_MOSI: 46 + SPI_0_SLAVE_PIN_MISO: 47 + SPI_0_SLAVE_PIN_SS: 44 + + I2C_0_PIN_SCL: ARDUINO_PIN_A5 + I2C_0_PIN_SDA: ARDUINO_PIN_A4 + + CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS + REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG + NFFS_FLASH_AREA: FLASH_AREA_NFFS + COREDUMP_FLASH_AREA: FLASH_AREA_COREDUMP + #Net Core DCDC is enabled from application core + #MCU_DCDC_ENABLED: 1 + MCU_LFCLK_SOURCE: LFXO + FLASH_MAP_SYSINIT_STAGE: 15 + + # Always use non-blocking API + SPI_HAL_USE_NOBLOCK: 1 + + # nRF5340 Network Core doesn't have floating point unit + HARDFLOAT: 0 + +syscfg.vals.BLE_CONTROLLER: + TIMER_0: 0 + TIMER_3: 1 + OS_CPUTIME_FREQ: 32768 + OS_CPUTIME_TIMER_NUM: 3 + BLE_LL_RFMGMT_ENABLE_TIME: 1500 + BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: 1 + +syscfg.vals.BLE_TRANSPORT: + BLE_TRANSPORT_HS: ipc + + # The APP core have the same values but switched directions + BLE_TRANSPORT_IPC_TX_CHANNEL: 18 + BLE_TRANSPORT_IPC_RX_CHANNEL: 12 + IPC_SYNC_TX_CHANNEL: 18 + IPC_SYNC_RX_CHANNEL: 12 + IPC_ICBMSG_TX_REGION_NAME: "\".ipc0_rx\"" + IPC_ICBMSG_RX_REGION_NAME: "\".ipc0_tx\"" + IPC_ICBMSG_NUM_TX_BLOCKS: 32 + IPC_ICBMSG_NUM_RX_BLOCKS: 32 diff --git a/hw/drivers/ipc/icbmsg/include/icbmsg/icbmsg.h b/hw/drivers/ipc/icbmsg/include/icbmsg/icbmsg.h new file mode 100644 index 0000000000..a8fa2fbd7c --- /dev/null +++ b/hw/drivers/ipc/icbmsg/include/icbmsg/icbmsg.h @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _HW_DRIVERS_IPC_ICBMSG_H +#define _HW_DRIVERS_IPC_ICBMSG_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ipc_service_cb { + void (*received)(const void *data, size_t len, void *user_data); +}; + +struct ipc_ept_cfg { + const char *name; + struct ipc_service_cb cb; + void *user_data; + uint8_t tx_channel; + uint8_t rx_channel; +}; + +struct ipc_icmsg_buf { + size_t block_id; + uint8_t *data; + uint16_t len; +}; + +typedef void (*ipc_icbmsg_recv_cb)(uint8_t ipc_id, void *user_data); + +uint8_t ipc_icmsg_register_ept(uint8_t ipc_id, struct ipc_ept_cfg *cfg); + +int ipc_icbmsg_send(uint8_t ipc_id, uint8_t ept_addr, const void *data, uint16_t len); + +int ipc_icbmsg_send_buf(uint8_t ipc_id, uint8_t ept_addr, struct ipc_icmsg_buf *buf); + +int ipc_icbmsg_alloc_tx_buf(uint8_t ipc_id, struct ipc_icmsg_buf *buf, uint32_t size); + +uint8_t ipc_icsmsg_ept_ready(uint8_t ipc_id, uint8_t ept_addr); + +#ifdef __cplusplus +} +#endif + +#endif /* _HW_DRIVERS_IPC_ICBMSG_H */ diff --git a/hw/drivers/ipc/icbmsg/pkg.yml b/hw/drivers/ipc/icbmsg/pkg.yml new file mode 100644 index 0000000000..41f0b0a832 --- /dev/null +++ b/hw/drivers/ipc/icbmsg/pkg.yml @@ -0,0 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/drivers/ipc/icbmsg +pkg.description: IPC driver with icbmsg backend +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ipc + +pkg.deps: + - "@apache-mynewt-core/hw/mcu/nordic" + - "@apache-mynewt-core/kernel/os" diff --git a/hw/drivers/ipc/icbmsg/src/icbmsg.c b/hw/drivers/ipc/icbmsg/src/icbmsg.c new file mode 100644 index 0000000000..28e05ad139 --- /dev/null +++ b/hw/drivers/ipc/icbmsg/src/icbmsg.c @@ -0,0 +1,974 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * ICBMsg backend. + * + * This is an IPC service backend that dynamically allocates buffers for data storage + * and uses ICMsg to send references to them. + * + * Shared memory organization + * -------------------------- + * + * Single channel (RX or TX) of the shared memory is divided into two areas: ICMsg area + * followed by Blocks area. ICMsg is used to send and receive short 3-byte messages. + * The ICMsg messages are queued inside the ICSM area using PBUF format. + * Blocks area is evenly divided into aligned blocks. Blocks are used to allocate + * buffers containing actual data. Data buffers can span multiple blocks. The first block + * starts with the size of the following data. + * + * +------------+-------------+ + * | ICMsg area | Blocks area | + * +------------+-------------+ + * _______/ \_________________________________________ + * / \ + * +-----------+-----------+-----------+-----------+- -+-----------+ + * | Block 0 | Block 1 | Block 2 | Block 3 | ... | Block N-1 | + * +-----------+-----------+-----------+-----------+- -+-----------+ + * _____/ \_____ + * / \ + * +------+--------------------------------+---------+ + * | size | data_buffer[size] ... | padding | + * +------+--------------------------------+---------+ + * + * The sender holds information about reserved blocks using bitarray and it is responsible + * for allocating and releasing the blocks. The receiver just tells the sender that it + * does not need a specific buffer anymore. + * + * Control messages + * ---------------- + * + * ICMsg is used to send and receive small 3-byte control messages. + * + * - Send data + * | MSG_DATA | endpoint address | block index | + * This message is used to send data buffer to specific endpoint. + * + * - Release data + * | MSG_RELEASE_DATA | 0 | block index | + * This message is a response to the "Send data" message and it is used to inform that + * specific buffer is not used anymore and can be released. Endpoint addresses does + * not matter here, so it is zero. + * + * - Bound endpoint + * | MSG_BOUND | endpoint address | block index | + * This message starts the bounding of the endpoint. The buffer contains a + * null-terminated endpoint name. + * + * - Release bound endpoint + * | MSG_RELEASE_BOUND | endpoint address | block index | + * This message is a response to the "Bound endpoint" message and it is used to inform + * that a specific buffer (starting at "block index") is not used anymore and + * a the endpoint is bounded and can now receive a data. + * + * Bounding endpoints + * ------------------ + * + * When ICMsg is bounded and user registers an endpoint on initiator side, the backend + * sends "Bound endpoint". Endpoint address is assigned by the initiator. When follower + * gets the message and user on follower side also registered the same endpoint, + * the backend calls "bound" callback and sends back "Release bound endpoint". + * The follower saves the endpoint address. The follower's endpoint is ready to send + * and receive data. When the initiator gets "Release bound endpoint" message or any + * data messages, it calls bound endpoint and it is ready to send data. + */ + + +#include +#include +#include +#include +#include +#include "utils.h" +#include "pbuf.h" + +#define TX_REGION MYNEWT_VAL(IPC_ICBMSG_TX_REGION_NAME) +#define RX_REGION MYNEWT_VAL(IPC_ICBMSG_RX_REGION_NAME) +#define TX_REGION_SIZE MYNEWT_VAL(IPC_ICBMSG_TX_REGION_SIZE) +#define RX_REGION_SIZE MYNEWT_VAL(IPC_ICBMSG_RX_REGION_SIZE) +__attribute__((section(TX_REGION))) static uint8_t ipc0_tx_start[TX_REGION_SIZE]; +__attribute__((section(RX_REGION))) static uint8_t ipc0_rx_start[RX_REGION_SIZE]; +#define ipc0_tx_end (ipc0_tx_start + sizeof(ipc0_tx_start)) +#define ipc0_rx_end (ipc0_rx_start + sizeof(ipc0_rx_start)) + +#define TX_BLOCKS_NUM MYNEWT_VAL(IPC_ICBMSG_NUM_TX_BLOCKS) +#define RX_BLOCKS_NUM MYNEWT_VAL(IPC_ICBMSG_NUM_RX_BLOCKS) +#define tx_BLOCKS_NUM TX_BLOCKS_NUM +#define rx_BLOCKS_NUM RX_BLOCKS_NUM + +/* A string used to synchronize cores */ +static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b, + 0x30, 0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34}; + + +#define PBUF_RX_READ_BUF_SIZE 128 +static uint8_t icmsg_rx_buffer[PBUF_RX_READ_BUF_SIZE] __attribute__((aligned(4))); + +/** Allowed number of endpoints within an IPC instance. */ +#define NUM_EPT MYNEWT_VAL(IPC_ICBMSG_NUM_EP) + +/** Special endpoint address indicating invalid (or empty) entry. */ +#define EPT_ADDR_INVALID 0xFF + +/** Special value for empty entry in bound message waiting table. */ +#define WAITING_BOUND_MSG_EMPTY 0xFFFF + +/** Size of the header (size field) of the block. */ +#define BLOCK_HEADER_SIZE (sizeof(struct block_header)) + +/** Flag indicating that ICMsg was bounded for this instance. */ +#define CONTROL_BOUNDED (1 << 31) + +/** Registered endpoints count mask in flags. */ +#define FLAG_EPT_COUNT_MASK 0xFFFF + +enum icmsg_state { + ICMSG_STATE_OFF, + ICMSG_STATE_BUSY, + ICMSG_STATE_READY, +}; + +enum msg_type { + /* Data message. */ + MSG_DATA = 0, + /* Release data buffer message. */ + MSG_RELEASE_DATA, + /* Endpoint bounding message. */ + MSG_BOUND, + /* Release endpoint bound message. + * This message is also indicator for the receiving side + * that the endpoint bounding was fully processed on + * the sender side. + */ + MSG_RELEASE_BOUND, +}; + +enum ept_bounding_state { + /* Endpoint in not configured (initial state). */ + EPT_UNCONFIGURED = 0, + /* Endpoint is configured, waiting for work queue to + * start bounding process. + */ + EPT_CONFIGURED, + /* Only on initiator. Bound message was send, + * but bound callback was not called yet, because + * we are waiting for any incoming messages. + */ + EPT_BOUNDING, + /* Bounding is done. Bound callback was called. */ + EPT_READY, +}; + +struct channel_config { + /* Address where the blocks start. */ + uint8_t *blocks_ptr; + /* Size of one block. */ + size_t block_size; + /* Number of blocks. */ + size_t block_count; +}; + +struct ipc_instance; + +struct ept_data { + struct ipc_instance *ipc; + struct ipc_ept_cfg *cfg; + /* Bounding state. */ + uint32_t state; + /* Endpoint address. */ + uint8_t addr; +}; + +struct ipc_instance { + /* Bit is set when TX block is in use */ + uint8_t tx_usage_bitmap[DIV_ROUND_UP(TX_BLOCKS_NUM, 8)]; + /* Bit is set, if the buffer starting at + * this block should be kept after exit + * from receive handler. + */ + uint8_t rx_usage_bitmap[DIV_ROUND_UP(RX_BLOCKS_NUM, 8)]; + /* TX ICSMsg Area packet buffer */ + struct pbuf tx_pb; + /* RX ICSMsg Area packet buffer */ + struct pbuf rx_pb; + /* TX channel config. */ + struct channel_config tx; + /* RX channel config. */ + struct channel_config rx; + /* Array of registered endpoints. */ + struct ept_data ept[NUM_EPT]; + uint16_t waiting_bound[NUM_EPT]; + /* Flags on higher bits, number of registered + * endpoints on lower. + */ + uint32_t flags; + /* This side has an initiator role. */ + bool is_initiator; + uint8_t state; + uint8_t ipc_id; +}; +struct block_header { + /* Size of the data field. It must be volatile, because + * when this value is read and validated for security + * reasons, compiler cannot generate code that reads + * it again after validation. + */ + volatile size_t size; +}; + +struct block_content { + struct block_header header; + /* Buffer data. */ + uint8_t data[]; +}; + +struct control_message { + /* Message type. */ + uint8_t msg_type; + /* Endpoint address or zero for MSG_RELEASE_DATA. */ + uint8_t ept_addr; + /* Block index to send or release. */ + uint8_t block_index; +}; + +static struct ipc_instance ipc_instances[1]; + +/** + * Calculate pointer to block from its index and channel configuration (RX or TX). + * No validation is performed. + */ +static struct block_content * +block_from_index(const struct channel_config *ch_conf, size_t block_index) +{ + return (struct block_content *)(ch_conf->blocks_ptr + block_index * ch_conf->block_size); +} + +/** + * Calculate pointer to data buffer from block index and channel configuration (RX or TX). + * Also validate the index and optionally the buffer size allocated on the this block. + */ +static uint8_t * +buffer_from_index_validate(const struct channel_config *ch_conf, + size_t block_index, size_t *size) +{ + size_t allocable_size; + size_t buffer_size; + uint8_t *end_ptr; + struct block_content *block; + + if (block_index >= ch_conf->block_count) { + /* Block index invalid */ + return NULL; + } + + block = block_from_index(ch_conf, block_index); + + if (size != NULL) { + allocable_size = ch_conf->block_count * ch_conf->block_size; + end_ptr = ch_conf->blocks_ptr + allocable_size; + buffer_size = block->header.size; + + if ((buffer_size > allocable_size - BLOCK_HEADER_SIZE) || + (&block->data[buffer_size] > end_ptr)) { + /* Block corrupted */ + return NULL; + } + + *size = buffer_size; + } + + return block->data; +} + +static int +find_zero_bits(uint8_t bitmap[], size_t total_bits, + size_t n, size_t *start_index) +{ + size_t zero_count = 0; + size_t first_zero_bit_pos; + size_t bit_id; + size_t byte_id; + uint8_t bit_pos; + + /* Find the first sequence of n consecutive 0 bits */ + for (bit_id = 0; bit_id < total_bits; ++bit_id) { + byte_id = bit_id / 8; + bit_pos = bit_id % 8; + + if ((bitmap[byte_id] & (1 << bit_pos)) == 0) { + if (zero_count == 0) { + first_zero_bit_pos = bit_id; + } + zero_count++; + + if (zero_count == n) { + *start_index = first_zero_bit_pos; + return 0; + } + } else { + zero_count = 0; + } + } + + return -1; +} + +static void +alloc_bitmap_bits(uint8_t bitmap[], size_t n, size_t start_index) +{ + for (size_t i = 0; i < n; ++i) { + size_t bit_index = start_index + i; + size_t byte_index = bit_index / 8; + size_t bit_pos = bit_index % 8; + + bitmap[byte_index] |= (1 << bit_pos); + } +} + +static void +free_bitmap_bits(uint8_t bitmap[], size_t n, size_t start_index) +{ + for (size_t i = 0; i < n; ++i) { + size_t bit_index = start_index + i; + size_t byte_index = bit_index / 8; + size_t bit_pos = bit_index % 8; + + bitmap[byte_index] &= ~(1 << bit_pos); + } +} + +static int +alloc_tx_buffer(struct ipc_instance *ipc, uint32_t size, uint8_t **buffer, + size_t *tx_block_index) +{ + int rc; + struct block_content *block; + size_t total_bits = sizeof(ipc->tx_usage_bitmap) * 8; + size_t total_size = size + BLOCK_HEADER_SIZE; + size_t num_blocks = DIV_ROUND_UP(total_size, ipc->tx.block_size); + + rc = find_zero_bits(ipc->tx_usage_bitmap, total_bits, + num_blocks, tx_block_index); + if (rc) { + return rc; + } + + alloc_bitmap_bits(ipc->tx_usage_bitmap, num_blocks, *tx_block_index); + + /* Get block pointer and adjust size to actually allocated space. */ + size = ipc->tx.block_size * num_blocks - BLOCK_HEADER_SIZE; + block = block_from_index(&ipc->tx, *tx_block_index); + block->header.size = size; + *buffer = block->data; + + return 0; +} + +/** + * Allocate buffer for transmission. + */ +int +ipc_icbmsg_alloc_tx_buf(uint8_t ipc_id, struct ipc_icmsg_buf *buf, uint32_t size) +{ + struct ipc_instance *ipc = &ipc_instances[ipc_id]; + + return alloc_tx_buffer(ipc, size, &buf->data, &buf->block_id); +} + +/** + * Release all or part of the blocks occupied by the buffer. + */ +static void +release_tx_blocks(struct ipc_instance *ipc, size_t release_index, size_t size) +{ + size_t num_blocks; + size_t total_size; + + /* Calculate number of blocks. */ + total_size = size + BLOCK_HEADER_SIZE; + num_blocks = DIV_ROUND_UP(total_size, ipc->tx.block_size); + + if (num_blocks > 0) { + free_bitmap_bits(ipc->tx_usage_bitmap, num_blocks, release_index); + } +} + +/** + * Send control message over ICMsg with mutex locked. Mutex must be locked because + * ICMsg may return error on concurrent invocations even when there is enough space + * in queue. + */ +static int +send_control_message(struct ept_data *ept, enum msg_type msg_type, uint8_t block_index) +{ + int ret; + struct ipc_instance *ipc = ept->ipc; + + const struct control_message message = { + .msg_type = (uint8_t)msg_type, + .ept_addr = ept->addr, + .block_index = block_index, + }; + + if (ipc->state != ICMSG_STATE_READY) { + return -EBUSY; + } + + ret = pbuf_write(&ipc->tx_pb, (const char *)&message, sizeof(message)); + + if (ret < 0) { + return ret; + } else if (ret < sizeof(message)) { + return -EBADMSG; + } + + ipc_signal(ept->cfg->tx_channel); + + return 0; +} + +/** + * Send data contained in specified block. + */ +static int +send_block(struct ept_data *ept, enum msg_type msg_type, size_t tx_block_index, size_t size) +{ + int r; + struct ipc_instance *ipc = ept->ipc; + struct block_content *block; + + block = block_from_index(&ipc->tx, tx_block_index); + block->header.size = size; + + r = send_control_message(ept, msg_type, tx_block_index); + if (r < 0) { + release_tx_blocks(ipc, tx_block_index, size); + } + + return r; +} + +/** + * Find endpoint that was registered with name that matches name + * contained in the endpoint bound message received from remote. + */ +static int +find_ept_by_name(struct ipc_instance *ipc, const char *name) +{ + const struct channel_config *rx_conf = &ipc->rx; + const char *buffer_end = (const char *)rx_conf->blocks_ptr + + rx_conf->block_count * rx_conf->block_size; + struct ept_data *ept; + size_t name_size; + size_t i; + + /* Requested name is in shared memory, so we have to assume that it + * can be corrupted. Extra care must be taken to avoid out of + * bounds reads. + */ + name_size = strnlen(name, buffer_end - name - 1) + 1; + + for (i = 0; i < NUM_EPT; i++) { + ept = &ipc->ept[i]; + if (ept->state == EPT_CONFIGURED && + strncmp(ept->cfg->name, name, name_size) == 0) { + return i; + } + } + + return -ENOENT; +} + +/** + * Send bound message on specified endpoint. + */ +static int +send_bound_message(struct ept_data *ept) +{ + int rc; + size_t msg_len; + uint8_t *buffer; + size_t tx_block_index; + + msg_len = strlen(ept->cfg->name) + 1; + rc = alloc_tx_buffer(ept->ipc, msg_len, &buffer, &tx_block_index); + if (rc >= 0) { + strcpy((char *)buffer, ept->cfg->name); + rc = send_block(ept, MSG_BOUND, tx_block_index, msg_len); + } + + return rc; +} + +/** + * Get endpoint from endpoint address. Also validates if the address is correct and + * endpoint is in correct state for receiving. + */ +static struct ept_data * +get_ept_and_rx_validate(struct ipc_instance *ipc, uint8_t ept_addr) +{ + struct ept_data *ept; + + if (ept_addr >= NUM_EPT) { + return NULL; + } + + ept = &ipc->ept[ept_addr]; + + if (ept->state == EPT_READY) { + /* Valid state - nothing to do. */ + } else if (ept->state == EPT_BOUNDING) { + /* The remote endpoint is ready */ + ept->state = EPT_READY; + } else { + return NULL; + } + + return ept; +} + +/** + * Data message received. + */ +static int +received_data(struct ipc_instance *ipc, size_t rx_block_index, uint8_t ept_addr) +{ + uint8_t *buffer; + struct ept_data *ept; + size_t size; + + /* Validate. */ + buffer = buffer_from_index_validate(&ipc->rx, rx_block_index, &size); + ept = get_ept_and_rx_validate(ipc, ept_addr); + if (buffer == NULL || ept == NULL) { + return -EINVAL; + } + + /* Call the endpoint callback. */ + ept->cfg->cb.received(buffer, size, ept->cfg->user_data); + + /* Release the buffer */ + send_control_message(ept, MSG_RELEASE_DATA, rx_block_index); + + return 0; +} + +/** + * Release data message received. + */ +static int +received_release_data(struct ipc_instance *ipc, size_t tx_block_index) +{ + size_t size; + uint8_t *buffer; + + /* Validate. */ + buffer = buffer_from_index_validate(&ipc->tx, tx_block_index, &size); + if (buffer == NULL) { + return -EINVAL; + } + + /* Release. */ + release_tx_blocks(ipc, tx_block_index, size); + + return 0; +} + +/** + * Bound endpoint message received. + */ +static int +received_bound(struct ipc_instance *ipc, size_t rx_block_index, uint8_t rem_ept_addr) +{ + int rc; + struct ept_data *ept; + uint8_t *buffer; + size_t size; + uint8_t ept_addr; + + /* Validate */ + buffer = buffer_from_index_validate(&ipc->rx, rx_block_index, &size); + if (buffer == NULL) { + /* Received invalid block index */ + return -1; + } + + rc = find_ept_by_name(ipc, (const char *)buffer); + if (rc < 0) { + assert(rem_ept_addr < NUM_EPT); + /* Put message to waiting array. */ + ipc->waiting_bound[rem_ept_addr] = rx_block_index; + + return 0; + } + + /* Set the remote endpoint address */ + ept_addr = rc; + assert(ept_addr < NUM_EPT); + ept = &ipc->ept[ept_addr]; + ept->addr = rem_ept_addr; + + if (ept->state != EPT_CONFIGURED) { + /* Unexpected bounding from remote on endpoint */ + return -EINVAL; + } + + ept->state = EPT_READY; + + send_control_message(ept, MSG_RELEASE_BOUND, rx_block_index); + + return 0; +} + +/** + * Handles ICMsg control messages received from the remote. + */ +static void +control_received(struct ipc_instance *ipc, const struct control_message *message) +{ + uint8_t ept_addr; + + ept_addr = message->ept_addr; + if (ept_addr >= NUM_EPT) { + return; + } + + switch (message->msg_type) { + case MSG_RELEASE_DATA: + received_release_data(ipc, message->block_index); + break; + case MSG_RELEASE_BOUND: + assert(received_release_data(ipc, message->block_index) == 0); + assert(get_ept_and_rx_validate(ipc, ept_addr) != NULL); + break; + case MSG_BOUND: + received_bound(ipc, message->block_index, ept_addr); + break; + case MSG_DATA: + received_data(ipc, message->block_index, ept_addr); + break; + default: + /* Silently ignore other messages types. They can be used in future + * protocol version. + */ + break; + } +} + +static void +process_ipc_data(uint8_t ipc_id) +{ + struct ipc_instance *ipc = &ipc_instances[ipc_id]; + int icmsg_len = pbuf_read(&ipc->rx_pb, (char *)icmsg_rx_buffer, sizeof(icmsg_rx_buffer)); + + if (ipc->state == ICMSG_STATE_READY) { + if (icmsg_len < sizeof(struct control_message)) { + return; + } + + control_received(ipc, (const struct control_message *)icmsg_rx_buffer); + } else { + /* After core restart, the first message in ICMsg area should be + * the magic string. + */ + assert(ipc->state == ICMSG_STATE_BUSY); + + /* Allow magic number longer than sizeof(magic) for future protocol version. */ + bool endpoint_invalid = (icmsg_len < sizeof(magic) || + memcmp(magic, icmsg_rx_buffer, sizeof(magic))); + + assert(!endpoint_invalid); + + /* Set flag that ICMsg is bounded and now, endpoint bounding may start. */ + ipc->flags |= CONTROL_BOUNDED; + ipc->state = ICMSG_STATE_READY; + } +} + +void +ipc_process_signal(uint8_t ipc_id) +{ + int icmsg_len; + struct ipc_instance *ipc = &ipc_instances[ipc_id]; + + do { + icmsg_len = pbuf_read(&ipc->rx_pb, NULL, 0); + if (icmsg_len <= 0) { + /* Unlikely, no data in buffer. */ + return; + } + + if (sizeof(icmsg_rx_buffer) < icmsg_len) { + return; + } + + process_ipc_data(ipc_id); + } while(true); +} + +/** + * Send to endpoint (without copy). + */ +int +ipc_icbmsg_send_buf(uint8_t ipc_id, uint8_t ept_addr, struct ipc_icmsg_buf *buf) +{ + struct ipc_instance *ipc = &ipc_instances[ipc_id]; + struct ept_data *ept = &ipc->ept[ept_addr]; + + /* Send data message. */ + return send_block(ept, MSG_DATA, buf->block_id, buf->len); +} + +/** + * Send to endpoint (with copy). + */ +int +ipc_icbmsg_send(uint8_t ipc_id, uint8_t ept_addr, const void *data, uint16_t len) +{ + int rc; + uint8_t *buffer; + struct ipc_instance *ipc = &ipc_instances[ipc_id]; + struct ept_data *ept = &ipc->ept[ept_addr]; + size_t tx_block_index; + + /* Allocate the buffer. */ + rc = alloc_tx_buffer(ipc, len, &buffer, &tx_block_index); + if (rc < 0) { + return rc; + } + + /* Copy data to allocated buffer. */ + memcpy(buffer, data, len); + + /* Send data message. */ + rc = send_block(ept, MSG_DATA, tx_block_index, len); + if (rc < 0) { + return rc; + } + + return 0; +} + +/** + * Register new endpoint + */ +uint8_t +ipc_icmsg_register_ept(uint8_t ipc_id, struct ipc_ept_cfg *cfg) +{ + int rc; + size_t i; + struct ipc_instance *ipc; + struct ept_data *ept = NULL; + uint8_t ept_addr; + + assert(ipc_id < sizeof(ipc_instances)); + ipc = &ipc_instances[ipc_id]; + + /* Reserve new endpoint index. */ + ept_addr = (ipc->flags++) & FLAG_EPT_COUNT_MASK; + assert(ept_addr < NUM_EPT); + + /* Add new endpoint. */ + ept = &ipc->ept[ept_addr]; + ept->ipc = ipc; + ept->state = EPT_CONFIGURED; + ept->cfg = cfg; + + if (ipc->is_initiator) { + ept->addr = ept_addr; + ept->state = EPT_BOUNDING; + + rc = send_bound_message(ept); + assert(rc == 0); + } else { + ept->addr = EPT_ADDR_INVALID; + + /* Respond to pending bounds */ + for (i = 0; i < NUM_EPT; ++i) { + if (ipc->waiting_bound[i] != WAITING_BOUND_MSG_EMPTY) { + received_bound(ipc, ipc->waiting_bound[i], i); + ipc->waiting_bound[i] = WAITING_BOUND_MSG_EMPTY; + } + } + } + + return ept_addr; +} + +/** + * Number of bytes per each ICMsg message. It is used to calculate size of ICMsg area. + */ +#define BYTES_PER_ICMSG_MESSAGE (ROUND_UP(sizeof(struct control_message), \ + sizeof(void *)) + PBUF_PACKET_LEN_SZ) + +/** + * Maximum ICMsg overhead. It is used to calculate size of ICMsg area. + */ +#define ICMSG_BUFFER_OVERHEAD(i) \ + (PBUF_HEADER_OVERHEAD(GET_CACHE_ALIGNMENT(i)) + 2 * BYTES_PER_ICMSG_MESSAGE) + +/** + * Returns required block alignment for instance "i". + */ +#define GET_CACHE_ALIGNMENT(i) (sizeof(uint32_t)) + +/** + * Calculates minimum size required for ICMsg region for specific number of local + * and remote blocks. The minimum size ensures that ICMsg queue is will never overflow + * because it can hold data message for each local block and release message + * for each remote block. + */ +#define GET_ICMSG_MIN_SIZE(i, local_blocks, remote_blocks) \ + (ICMSG_BUFFER_OVERHEAD(i) + BYTES_PER_ICMSG_MESSAGE * \ + (local_blocks + remote_blocks)) + +/** + * Calculate aligned block size by evenly dividing remaining space after removing + * the space for ICMsg. + */ +#define GET_BLOCK_SIZE(i, total_size, local_blocks, remote_blocks) ROUND_DOWN( \ + ((total_size) - GET_ICMSG_MIN_SIZE(i, (local_blocks), (remote_blocks))) / \ + (local_blocks), GET_CACHE_ALIGNMENT(i)) + +/** + * Calculate offset where area for blocks starts which is just after the ICMsg. + */ +#define GET_BLOCKS_OFFSET(i, total_size, local_blocks, remote_blocks) \ + ((total_size) - GET_BLOCK_SIZE(i, (total_size), (local_blocks), \ + (remote_blocks)) * (local_blocks)) + +/** + * Return shared memory start address aligned to block alignment and cache line. + */ +#define GET_MEM_ADDR_INST(i, direction) \ + ROUND_UP(ipc ## i ## _ ## direction ## _start, GET_CACHE_ALIGNMENT(i)) + +/** + * Return shared memory end address aligned to block alignment and cache line. + */ +#define GET_MEM_END_INST(i, direction) \ + ROUND_DOWN(ipc ## i ## _ ## direction ## _end, GET_CACHE_ALIGNMENT(i)) + +/** + * Return shared memory size aligned to block alignment and cache line. + */ +#define GET_MEM_SIZE_INST(i, direction) \ + (GET_MEM_END_INST(i, direction) - GET_MEM_ADDR_INST(i, direction)) + +/** + * Returns GET_ICMSG_SIZE, but for specific instance and direction. + * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx" + * or "rx, tx". + */ +#define GET_ICMSG_SIZE_INST(i, loc, rem) \ + GET_BLOCKS_OFFSET(i, \ + GET_MEM_SIZE_INST(i, loc), \ + loc ## _BLOCKS_NUM, \ + rem ## _BLOCKS_NUM) + +/** + * Returns address where area for blocks starts for specific instance and direction. + * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx" + * or "rx, tx". + */ +#define GET_BLOCKS_ADDR_INST(i, loc, rem) \ + GET_MEM_ADDR_INST(i, loc) + \ + GET_ICMSG_SIZE_INST(i, loc, rem) + +/** + * Returns block size for specific instance and direction. + * 'loc' and 'rem' parameters tells the direction. They can be either "tx, rx" + * or "rx, tx". + */ +#define GET_BLOCK_SIZE_INST(i, loc, rem) \ + GET_BLOCK_SIZE(i, \ + GET_MEM_SIZE_INST(i, loc), \ + loc ## _BLOCKS_NUM, \ + rem ## _BLOCKS_NUM) + +#define IPC_INSTANCE_INIT(i) (struct ipc_instance) { \ + .tx_pb = { \ + .cfg = PBUF_CFG_INIT(GET_MEM_ADDR_INST(i, tx), \ + GET_ICMSG_SIZE_INST(i, tx, rx), \ + GET_CACHE_ALIGNMENT(i)), \ + }, \ + .rx_pb = { \ + .cfg = PBUF_CFG_INIT(GET_MEM_ADDR_INST(i, rx), \ + GET_ICMSG_SIZE_INST(i, rx, tx), \ + GET_CACHE_ALIGNMENT(i)), \ + }, \ + .tx = { \ + .blocks_ptr = (uint8_t *)GET_BLOCKS_ADDR_INST(i, tx, rx), \ + .block_count = TX_BLOCKS_NUM, \ + .block_size = GET_BLOCK_SIZE_INST(i, tx, rx), \ + }, \ + .rx = { \ + .blocks_ptr = (uint8_t *)GET_BLOCKS_ADDR_INST(i, rx, tx), \ + .block_count = RX_BLOCKS_NUM, \ + .block_size = GET_BLOCK_SIZE_INST(i, rx, tx), \ + }, \ +} + +/** + * Backend initialization. + */ +int +ipc_open(uint8_t ipc_id) +{ + int rc; + struct ipc_instance *ipc; + + assert(ipc_id < sizeof(ipc_instances)); + + ipc = &ipc_instances[ipc_id]; + memset(ipc, 0, sizeof(*ipc)); + *ipc = IPC_INSTANCE_INIT(0); + + assert(ipc->state == ICMSG_STATE_OFF); + ipc->state = ICMSG_STATE_BUSY; + + memset(ipc->tx_usage_bitmap, 0, DIV_ROUND_UP(TX_BLOCKS_NUM, 8)); + memset(ipc->rx_usage_bitmap, 0, DIV_ROUND_UP(RX_BLOCKS_NUM, 8)); + + ipc->is_initiator = (ipc->rx.blocks_ptr < ipc->tx.blocks_ptr); + memset(&ipc->waiting_bound, 0xFF, sizeof(ipc->waiting_bound)); + + rc = pbuf_init(&ipc->tx_pb); + assert(rc == 0); + + /* Initialize local copies of rx_pb. */ + ipc->rx_pb.data.wr_idx = 0; + ipc->rx_pb.data.rd_idx = 0; + + rc = pbuf_write(&ipc->tx_pb, (char *)magic, sizeof(magic)); + assert(rc == sizeof(magic)); + + return 0; +} + +uint8_t +ipc_ready(uint8_t ipc_id) +{ + struct ipc_instance *ipc = &ipc_instances[ipc_id]; + + if (ipc->state == ICMSG_STATE_READY) { + return 1; + } + + return 0; +} + +uint8_t +ipc_icsmsg_ept_ready(uint8_t ipc_id, uint8_t ept_addr) +{ + struct ipc_instance *ipc = &ipc_instances[ipc_id]; + + if (ipc->ept[ept_addr].state == EPT_READY) { + return 1; + } + + return 0; +} diff --git a/hw/drivers/ipc/icbmsg/src/pbuf.c b/hw/drivers/ipc/icbmsg/src/pbuf.c new file mode 100644 index 0000000000..b3dc52dae7 --- /dev/null +++ b/hw/drivers/ipc/icbmsg/src/pbuf.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "pbuf.h" +#include "utils.h" + +/* Helper funciton for getting numer of bytes being written to the bufer. */ +static uint32_t +idx_occupied(uint32_t len, uint32_t wr_idx, uint32_t rd_idx) +{ + /* It is implicitly assumed wr_idx and rd_idx cannot differ by more then len. */ + return (rd_idx > wr_idx) ? (len - (rd_idx - wr_idx)) : (wr_idx - rd_idx); +} + +/* Helper function for wrapping the index from the begging if above buffer len. */ +static uint32_t +idx_wrap(uint32_t len, uint32_t idx) +{ + return (idx >= len) ? (idx % len) : (idx); +} + +static int +validate_cfg(const struct pbuf_cfg *cfg) +{ + /* Validate pointers. */ + if (!cfg || !cfg->rd_idx_loc || !cfg->wr_idx_loc || !cfg->data_loc) { + return -EINVAL; + } + + /* Validate pointer alignment. */ + if (!IS_PTR_ALIGNED_BYTES(cfg->rd_idx_loc, MAX(cfg->dcache_alignment, _PBUF_IDX_SIZE)) || + !IS_PTR_ALIGNED_BYTES(cfg->wr_idx_loc, MAX(cfg->dcache_alignment, _PBUF_IDX_SIZE)) || + !IS_PTR_ALIGNED_BYTES(cfg->data_loc, _PBUF_IDX_SIZE)) { + return -EINVAL; + } + + /* Validate len. */ + if (cfg->len < _PBUF_MIN_DATA_LEN || !IS_PTR_ALIGNED_BYTES(cfg->len, _PBUF_IDX_SIZE)) { + return -EINVAL; + } + + /* Validate pointer values. */ + if (!(cfg->rd_idx_loc < cfg->wr_idx_loc) || + !((uint8_t *)cfg->wr_idx_loc < cfg->data_loc) || + !(((uint8_t *)cfg->rd_idx_loc + MAX(_PBUF_IDX_SIZE, cfg->dcache_alignment)) == + (uint8_t *)cfg->wr_idx_loc)) { + return -EINVAL; + } + + return 0; +} + +int +pbuf_init(struct pbuf *pb) +{ + if (validate_cfg(&pb->cfg) != 0) { + return -EINVAL; + } + + /* Initialize local copy of indexes. */ + pb->data.wr_idx = 0; + pb->data.rd_idx = 0; + + /* Clear shared memory. */ + *(pb->cfg.wr_idx_loc) = pb->data.wr_idx; + *(pb->cfg.rd_idx_loc) = pb->data.rd_idx; + + return 0; +} + +int +pbuf_write(struct pbuf *pb, const char *data, uint16_t len) +{ + if (pb == NULL || len == 0 || data == NULL) { + /* Incorrect call. */ + return -EINVAL; + } + + uint8_t *const data_loc = pb->cfg.data_loc; + const uint32_t blen = pb->cfg.len; + uint32_t rd_idx = *(pb->cfg.rd_idx_loc); + uint32_t wr_idx = pb->data.wr_idx; + + /* wr_idx must always be aligned. */ + assert(IS_PTR_ALIGNED_BYTES(wr_idx, _PBUF_IDX_SIZE)); + /* rd_idx shall always be aligned, but its value is received from the reader. + * Can not assert. + */ + if (!IS_PTR_ALIGNED_BYTES(rd_idx, _PBUF_IDX_SIZE)) { + return -EINVAL; + } + + assert(wr_idx < blen); + uint32_t free_space = blen - idx_occupied(blen, wr_idx, rd_idx) - _PBUF_IDX_SIZE; + + /* Packet length, data + packet length size. */ + uint32_t plen = len + PBUF_PACKET_LEN_SZ; + + /* Check if packet will fit into the buffer. */ + if (free_space < plen) { + return -ENOMEM; + } + + /* Clear packet len with zeros and update. Clearing is done for possible versioning in the + * future. Writing is allowed now, because shared wr_idx value is updated at the very end. + */ + *((uint32_t *)(&data_loc[wr_idx])) = 0; + put_be16(&data_loc[wr_idx], len); + + wr_idx = idx_wrap(blen, wr_idx + PBUF_PACKET_LEN_SZ); + + /* Write until end of the buffer, if data will be wrapped. */ + uint32_t tail = MIN(len, blen - wr_idx); + + memcpy(&data_loc[wr_idx], data, tail); + + if (len > tail) { + /* Copy remaining data to buffer front. */ + memcpy(&data_loc[0], data + tail, len - tail); + } + + wr_idx = idx_wrap(blen, ROUND_UP(wr_idx + len, _PBUF_IDX_SIZE)); + /* Update wr_idx. */ + pb->data.wr_idx = wr_idx; + *(pb->cfg.wr_idx_loc) = wr_idx; + + return len; +} + +int +pbuf_read(struct pbuf *pb, char *buf, uint16_t len) +{ + if (pb == NULL) { + /* Incorrect call. */ + return -EINVAL; + } + + uint8_t *const data_loc = pb->cfg.data_loc; + const uint32_t blen = pb->cfg.len; + uint32_t wr_idx = *(pb->cfg.wr_idx_loc); + uint32_t rd_idx = pb->data.rd_idx; + + /* rd_idx must always be aligned. */ + assert(IS_PTR_ALIGNED_BYTES(rd_idx, _PBUF_IDX_SIZE)); + /* wr_idx shall always be aligned, but its value is received from the + * writer. Can not assert. + */ + if (!IS_PTR_ALIGNED_BYTES(wr_idx, _PBUF_IDX_SIZE)) { + return -EINVAL; + } + + if (rd_idx == wr_idx) { + /* Buffer is empty. */ + return 0; + } + + /* Get packet len.*/ + uint16_t plen = get_be16(&data_loc[rd_idx]); + + if (!buf) { + return (int)plen; + } + + if (plen > len) { + return -ENOMEM; + } + + uint32_t occupied_space = idx_occupied(blen, wr_idx, rd_idx); + + if (occupied_space < plen + PBUF_PACKET_LEN_SZ) { + /* This should never happen. */ + return -EAGAIN; + } + + rd_idx = idx_wrap(blen, rd_idx + PBUF_PACKET_LEN_SZ); + + /* Packet will fit into provided buffer, truncate len if provided len + * is bigger than necessary. + */ + len = MIN(plen, len); + + /* Read until end of the buffer, if data are wrapped. */ + uint32_t tail = MIN(blen - rd_idx, len); + + memcpy(buf, &data_loc[rd_idx], tail); + + if (len > tail) { + memcpy(&buf[tail], &pb->cfg.data_loc[0], len - tail); + } + + /* Update rd_idx. */ + rd_idx = idx_wrap(blen, ROUND_UP(rd_idx + len, _PBUF_IDX_SIZE)); + + pb->data.rd_idx = rd_idx; + *(pb->cfg.rd_idx_loc) = rd_idx; + + return len; +} diff --git a/hw/drivers/ipc/icbmsg/src/pbuf.h b/hw/drivers/ipc/icbmsg/src/pbuf.h new file mode 100644 index 0000000000..5dd26108bf --- /dev/null +++ b/hw/drivers/ipc/icbmsg/src/pbuf.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_IPC_PBUF_H_ +#define ZEPHYR_INCLUDE_IPC_PBUF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Packed buffer API + * @defgroup pbuf Packed Buffer API + * @ingroup ipc + * @{ + */ + +/** @brief Size of packet length field. */ +#define PBUF_PACKET_LEN_SZ sizeof(uint32_t) + +/* Amount of data that is left unused to distinguish between empty and full. */ +#define _PBUF_IDX_SIZE sizeof(uint32_t) + +/* Minimal length of the data field in the buffer to store the smalest packet + * possible. + * (+1) for at least one byte of data. + * (+_PBUF_IDX_SIZE) to distinguish buffer full and buffer empty. + * Rounded up to keep wr/rd indexes pointing to aligned address. + */ +#define _PBUF_MIN_DATA_LEN ROUND_UP(PBUF_PACKET_LEN_SZ + 1 + _PBUF_IDX_SIZE, _PBUF_IDX_SIZE) + +/** @brief Control block of packet buffer. + * + * The structure contains configuration data. + */ +struct pbuf_cfg { + /* Address of the variable holding index value of + * the first valid byte in data[]. + */ + volatile uint32_t *rd_idx_loc; + /* Address of the variable holding index value of + * the first free byte in data[]. + */ + volatile uint32_t *wr_idx_loc; + /* CPU data cache line size in bytes. Used for validation + * TODO: To be replaced by flags. + */ + uint32_t dcache_alignment; + /* Length of data[] in bytes. */ + uint32_t len; + /* Location of the data[]. */ + uint8_t *data_loc; +}; + +/** + * @brief Data block of the packed buffer. + * + * The structure contains local copies of wr and rd indexes used by writer and + * reader respectively. + */ +struct pbuf_data { + /* Index of the first holding first free byte in data[]. + * Used for writing. + */ + volatile uint32_t wr_idx; + /* Index of the first holding first valid byte in data[]. + * Used for reading. + */ + volatile uint32_t rd_idx; +}; + +/** + * @brief Scure packed buffer. + * + * The packet buffer implements lightweight unidirectional packet + * buffer with read/write semantics on top of a memory region shared + * by the reader and writer. It embeds cache and memory barrier management to + * ensure correct data access. + * + * This structure supports single writer and reader. Data stored in the buffer + * is encapsulated to a message (with length header). The read/write API is + * written in a way to protect the data from being corrupted. + */ +struct pbuf { + /* Configuration of the buffer. */ + struct pbuf_cfg cfg; + /* Data used to read and write to the buffer */ + struct pbuf_data data; +}; + +/** + * @brief Macro for configuration initialization. + * + * It is recommended to use this macro to initialize packed buffer + * configuration. + * + * @param mem_addr Memory address for pbuf. + * @param size Size of the memory. + * @param dcache_align Data cache alignment. + */ +#define PBUF_CFG_INIT(mem_addr, size, dcache_align) \ + { \ + .rd_idx_loc = (uint32_t *)(mem_addr), \ + .wr_idx_loc = (uint32_t *)((uint8_t *)(mem_addr) + \ + MAX(dcache_align, _PBUF_IDX_SIZE)), \ + .data_loc = (uint8_t *)((uint8_t *)(mem_addr) + \ + MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE), \ + .len = (uint32_t)((uint32_t)(size) - MAX(dcache_align, _PBUF_IDX_SIZE) - \ + _PBUF_IDX_SIZE), \ + .dcache_alignment = (dcache_align), \ + } + +/** + * @brief Macro calculates memory overhead taken by the header in shared memory. + * + * It contains the read index, write index and padding. + * + * @param dcache_align Data cache alignment. + */ +#define PBUF_HEADER_OVERHEAD(dcache_align) \ + (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE) + +/** + * @brief Initialize the packet buffer. + * + * This function initializes the packet buffer based on provided configuration. + * If the configuration is incorrect, the function will return error. + * + * @param pb Pointer to the packed buffer containing + * configuration and data. Configuration has to be + * fixed before the initialization. + * @retval 0 on success. + * @retval -EINVAL when the input parameter is incorrect. + */ +int pbuf_init(struct pbuf *pb); + +/** + * @brief Write specified amount of data to the packet buffer. + * + * This function call writes specified amount of data to the packet buffer if + * the buffer will fit the data. + * + * @param pb A buffer to which to write. + * @param buf Pointer to the data to be written to the buffer. + * @param len Number of bytes to be written to the buffer. Must be positive. + * @retval int Number of bytes written, negative error code on fail. + * -EINVAL, if any of input parameter is incorrect. + * -ENOMEM, if len is bigger than the buffer can fit. + */ + +int pbuf_write(struct pbuf *pb, const char *buf, uint16_t len); + +/** + * @brief Read specified amount of data from the packet buffer. + * + * Single read allows to read the message send by the single write. + * The provided %p buf must be big enough to store the whole message. + * + * @param pb A buffer from which data will be read. + * @param buf Data pointer to which read data will be written. + * If NULL, len of stored message is returned. + * @param len Number of bytes to be read from the buffer. + * @retval int Bytes read, negative error code on fail. + * Bytes to be read, if buf == NULL. + * -EINVAL, if any of input parameter is incorrect. + * -ENOMEM, if message can not fit in provided buf. + * -EAGAIN, if not whole message is ready yet. + */ +int pbuf_read(struct pbuf *pb, char *buf, uint16_t len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_IPC_PBUF_H_ */ diff --git a/hw/drivers/ipc/icbmsg/src/utils.h b/hw/drivers/ipc/icbmsg/src/utils.h new file mode 100644 index 0000000000..a5d6a49541 --- /dev/null +++ b/hw/drivers/ipc/icbmsg/src/utils.h @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _HW_DRIVERS_IPC_ICBMSG_UTILS_H +#define _HW_DRIVERS_IPC_ICBMSG_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) + +/* Value of x rounded up to the next multiple of align. */ +#define ROUND_UP(x, align) \ + ((((unsigned long)(x) + ((unsigned long)(align) - 1)) / \ + (unsigned long)(align)) * (unsigned long)(align)) + +#define ROUND_DOWN(x, align) \ + (((unsigned long)(x) / (unsigned long)(align)) * (unsigned long)(align)) + +/* Check if a pointer is aligned for against a specific byte boundary */ +#define IS_PTR_ALIGNED_BYTES(ptr, bytes) ((((uintptr_t)ptr) % bytes) == 0) + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _HW_DRIVERS_IPC_ICBMSG_UTILS_H */ diff --git a/hw/drivers/ipc/icbmsg/syscfg.yml b/hw/drivers/ipc/icbmsg/syscfg.yml new file mode 100644 index 0000000000..67547e13b6 --- /dev/null +++ b/hw/drivers/ipc/icbmsg/syscfg.yml @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + IPC_ICBMSG_NUM_EP: + description: > + Allowed number of endpoints within an IPC instance. + value: 2 + IPC_ICBMSG_TX_REGION_SIZE: + description: > + Size of IPC TX region. + value: 0x800 + IPC_ICBMSG_RX_REGION_SIZE: + description: > + Size of IPC RX region. + value: 0x800 + IPC_ICBMSG_TX_REGION_NAME: + description: > + Name of IPC TX region. + value: "\".ipc0_tx\"" + IPC_ICBMSG_RX_REGION_NAME: + description: > + Size of IPC RX region. + value: "\".ipc0_rx\"" + IPC_ICBMSG_NUM_TX_BLOCKS: + description: > + Number of blocks within IPC TX region. + value: 24 + IPC_ICBMSG_NUM_RX_BLOCKS: + description: > + Number of blocks within IPC RX region. + value: 24 diff --git a/hw/drivers/ipc/include/ipc/ipc.h b/hw/drivers/ipc/include/ipc/ipc.h new file mode 100644 index 0000000000..93c5910034 --- /dev/null +++ b/hw/drivers/ipc/include/ipc/ipc.h @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _HW_DRIVERS_IPC_H +#define _HW_DRIVERS_IPC_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ipc_init(void); +int ipc_open(uint8_t ipc_id); +int ipc_signal(uint8_t ipc_id); +void ipc_process_signal(uint8_t ipc_id); +uint8_t ipc_ready(uint8_t ipc_id); + +#ifdef __cplusplus +} +#endif + +#endif /* _HW_DRIVERS_IPC_H */ diff --git a/hw/drivers/ipc/pkg.yml b/hw/drivers/ipc/pkg.yml new file mode 100644 index 0000000000..c79155ee65 --- /dev/null +++ b/hw/drivers/ipc/pkg.yml @@ -0,0 +1,32 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/drivers/ipc +pkg.description: IPC driver +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ipc + +pkg.deps: + - "@apache-mynewt-core/hw/mcu/nordic" + - "@apache-mynewt-core/kernel/os" + +pkg.init: + ipc_init: 10 diff --git a/hw/drivers/ipc/src/ipc.c b/hw/drivers/ipc/src/ipc.c new file mode 100644 index 0000000000..76565506a3 --- /dev/null +++ b/hw/drivers/ipc/src/ipc.c @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include + +#define IPC_MAX_CHANS MYNEWT_VAL(IPC_CHANNELS) +#define IPC_SYNC_ID 0 + +/* IPC channels used for startup sync */ +#define IPC_SYNC_TX_CHANNEL MYNEWT_VAL(IPC_SYNC_TX_CHANNEL) +#define IPC_SYNC_RX_CHANNEL MYNEWT_VAL(IPC_SYNC_RX_CHANNEL) + +static void +ipc_cb(uint8_t channel) +{ + assert(channel == IPC_SYNC_RX_CHANNEL); + + os_trace_isr_enter(); + + ipc_process_signal(IPC_SYNC_ID); + + os_trace_isr_exit(); +} + +int +ipc_signal(uint8_t channel) +{ + return hal_ipc_signal(channel); +} + +void +ipc_init(void) +{ + uint32_t start; + + hal_ipc_init(); + + hal_ipc_register_callback(IPC_SYNC_RX_CHANNEL, ipc_cb); + + ipc_open(IPC_SYNC_ID); + + hal_ipc_enable_irq(IPC_SYNC_RX_CHANNEL, 1); + + hal_ipc_start(); + + ipc_signal(IPC_SYNC_TX_CHANNEL); + start = os_cputime_ticks_to_usecs(os_cputime_get32()); + + while (!ipc_ready(IPC_SYNC_ID)) { + ipc_cb(IPC_SYNC_RX_CHANNEL); + + if ((os_cputime_ticks_to_usecs(os_cputime_get32()) - start) > 1000) { + ipc_signal(IPC_SYNC_TX_CHANNEL); + start = os_cputime_ticks_to_usecs(os_cputime_get32()); + } + } +} diff --git a/hw/drivers/ipc/syscfg.yml b/hw/drivers/ipc/syscfg.yml new file mode 100644 index 0000000000..ae87b8b823 --- /dev/null +++ b/hw/drivers/ipc/syscfg.yml @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + IPC_CHANNELS: + description: > + Number of enabled IPC channels + value: 5 + range: 1..16 + + IPC_SYNC_TX_CHANNEL: + description: > + Select IPC TX channel to be used for sync. + range: 0..31 + value: 1 + + IPC_SYNC_RX_CHANNEL: + description: > + Select IPC RX channel to be used for sync. + range: 0..31 + value: 0 + +syscfg.vals.'BSP_NRF5340_NET || BSP_NRF54_RAD': + IPC_CHANNELS: 16 diff --git a/hw/hal/include/hal/hal_ipc.h b/hw/hal/include/hal/hal_ipc.h new file mode 100644 index 0000000000..88add13e16 --- /dev/null +++ b/hw/hal/include/hal/hal_ipc.h @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @addtogroup HAL + * @{ + * @defgroup HALIPC HAL IPC + * @{ + */ + +#ifndef H_HAL_IPC_ +#define H_HAL_IPC_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*hal_ipc_cb)(uint8_t channel); + +void hal_ipc_init(void); +void hal_ipc_start(void); +void hal_ipc_register_callback(uint8_t channel, hal_ipc_cb cb); +void hal_ipc_enable_irq(uint8_t channel, bool enable); +int hal_ipc_signal(uint8_t channel); + +#ifdef __cplusplus +} +#endif + +#endif /* H_HAL_IPC_ */ + +/** + * @} HALIPC + * @} HAL + */ diff --git a/hw/mcu/nordic/include/nrfx_config.h b/hw/mcu/nordic/include/nrfx_config.h index 17dacacd70..302dcee552 100644 --- a/hw/mcu/nordic/include/nrfx_config.h +++ b/hw/mcu/nordic/include/nrfx_config.h @@ -65,6 +65,10 @@ #include #elif defined(NRF54L15_ENGA_XXAA) && defined(NRF_APPLICATION) #include +#elif defined(NRF54H20_XXAA) && defined(NRF_APPLICATION) + #include +#elif defined(NRF54H20_XXAA) && defined(NRF_RADIOCORE) + #include #elif defined(NRF9120_XXAA) || defined(NRF9160_XXAA) #include #else diff --git a/hw/mcu/nordic/include/nrfx_config_common.h b/hw/mcu/nordic/include/nrfx_config_common.h index c23a793e36..7587997041 100644 --- a/hw/mcu/nordic/include/nrfx_config_common.h +++ b/hw/mcu/nordic/include/nrfx_config_common.h @@ -45,7 +45,7 @@ /** @brief Symbol specifying minor version of the nrfx API to be used. */ #ifndef NRFX_CONFIG_API_VER_MINOR -#define NRFX_CONFIG_API_VER_MINOR 1 +#define NRFX_CONFIG_API_VER_MINOR 2 #endif /** @brief Symbol specifying micro version of the nrfx API to be used. */ diff --git a/hw/mcu/nordic/nrf5340/nrf5340.ld b/hw/mcu/nordic/nrf5340/nrf5340.ld index 339ac60abe..6a304d48b0 100644 --- a/hw/mcu/nordic/nrf5340/nrf5340.ld +++ b/hw/mcu/nordic/nrf5340/nrf5340.ld @@ -147,6 +147,22 @@ INCLUDE "link_tables.ld.h" . = ALIGN(4); } > RAM + /* Section for IPC RX */ + .ipc0_rx (NOLOAD): + { + . = ALIGN(4); + *(.ipc0_rx) + . = ALIGN(4); + } > sram_ipc0_rx + + /* Section for IPC TX */ + .ipc0_tx (NOLOAD): + { + . = ALIGN(4); + *(.ipc0_tx) + . = ALIGN(4); + } > sram_ipc0_tx + /* This section will be zeroed by RTT package init */ .rtt (NOLOAD): { diff --git a/hw/mcu/nordic/nrf5340/pkg.yml b/hw/mcu/nordic/nrf5340/pkg.yml index ddc93e25a7..c936d5b20a 100644 --- a/hw/mcu/nordic/nrf5340/pkg.yml +++ b/hw/mcu/nordic/nrf5340/pkg.yml @@ -30,6 +30,12 @@ pkg.deps: - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" - "@apache-mynewt-core/hw/mcu/nordic/nrf5340/tfm" +pkg.deps.'BLE_TRANSPORT_LL == "nrf5340"': + - "@apache-mynewt-core/hw/drivers/ipc_nrf5340" + +pkg.deps.'BLE_TRANSPORT_LL == "ipc"': + - "@apache-mynewt-core/hw/drivers/ipc" + pkg.deps.BUS_DRIVER_PRESENT: - "@apache-mynewt-core/hw/bus/drivers/spi_hal" - "@apache-mynewt-core/hw/bus/drivers/i2c_common" diff --git a/hw/mcu/nordic/nrf5340/src/hal_ipc.c b/hw/mcu/nordic/nrf5340/src/hal_ipc.c new file mode 100644 index 0000000000..b457d4e8ad --- /dev/null +++ b/hw/mcu/nordic/nrf5340/src/hal_ipc.c @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Always use unsecure peripheral for IPC, unless pre-TrusZone bootloader is present in netcore */ +#undef NRF_IPC +#if MYNEWT_VAL(IPC_NRF5340_PRE_TRUSTZONE_NETCORE_BOOT) +#define NRF_IPC NRF_IPC_S +#else +#define NRF_IPC NRF_IPC_NS +#endif + +#ifndef BIT +#define BIT(n) (1UL << (n)) +#endif + +#define IPC_MAX_CHANS 4 + +static hal_ipc_cb cbs[IPC_MAX_CHANS]; + +int +hal_ipc_signal(uint8_t channel) +{ + assert(channel < IPC_MAX_CHANS); + + nrf_ipc_task_trigger(NRF_IPC, nrf_ipc_send_task_get(channel)); + + return 0; +} + +void +hal_ipc_register_callback(uint8_t channel, hal_ipc_cb cb) +{ + assert(channel < IPC_MAX_CHANS); + + cbs[channel] = cb; +} + +void +hal_ipc_enable_irq(uint8_t channel, bool enable) +{ + assert(channel < IPC_MAX_CHANS); + + if (enable) { + NRF_IPC->RECEIVE_CNF[channel] = BIT(channel); + NRF_IPC->INTENSET = BIT(channel); + } else { + NRF_IPC->INTENCLR = BIT(channel); + NRF_IPC->RECEIVE_CNF[channel] = 0; + } +} + +static void +ipc_isr(void) +{ + uint32_t irq_pend; + uint8_t channel; + + os_trace_isr_enter(); + + /* Handle only interrupts that were enabled */ + irq_pend = NRF_IPC->INTPEND & NRF_IPC->INTEN; + + for (channel = 0; channel < IPC_MAX_CHANS; ++channel) { + if (irq_pend & BIT(channel)) { + NRF_IPC->EVENTS_RECEIVE[channel] = 0; + + if (cbs[channel] != NULL) { + cbs[channel](channel); + } + } + } + + os_trace_isr_exit(); +} + +void +hal_ipc_init(void) +{ + uint8_t i; +//#if MYNEWT_VAL(IPC_NRF5340_NET_GPIO) +#if MYNEWT_VAL(MCU_APP_CORE) +// unsigned int gpios[] = { UNMANGLE_MYNEWT_VAL(MYNEWT_VAL(IPC_NRF5340_NET_GPIO)) }; + unsigned int gpios[] = { 29, 30, 31 }; + NRF_GPIO_Type *nrf_gpio; +#endif + + /* Make sure network core if off when we set up IPC */ + nrf_reset_network_force_off(NRF_RESET, true); + + if (MYNEWT_VAL(MCU_APP_SECURE) && !MYNEWT_VAL(IPC_NRF5340_PRE_TRUSTZONE_NETCORE_BOOT)) { + /* + * When bootloader is secure and application is not all peripherals are + * in unsecure mode. This is done by bootloader. + * If application runs in secure mode IPC manually chooses to use unsecure version + * so net core can always use same peripheral. + */ + NRF_SPU->PERIPHID[42].PERM &= ~SPU_PERIPHID_PERM_SECATTR_Msk; + } + +#if MYNEWT_VAL(MCU_APP_CORE) + /* Configure GPIOs for Networking Core */ + for (i = 0; i < ARRAY_SIZE(gpios); i++) { + nrf_gpio = NRF_P0; //HAL_GPIO_PORT(gpios[i]); +// nrf_gpio->PIN_CNF[HAL_GPIO_INDEX(gpios[i])] = + nrf_gpio->PIN_CNF[gpios[i] & 0x1F] = + ((uint32_t)GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos); + } +#endif + + /* Enable IPC channels */ + for (i = 0; i < IPC_MAX_CHANS; ++i) { + NRF_IPC->SEND_CNF[i] = BIT(i); + NRF_IPC->RECEIVE_CNF[i] = 0; + } + + NRF_IPC->INTENCLR = 0xFFFF; + NVIC_ClearPendingIRQ(IPC_IRQn); + NVIC_SetVector(IPC_IRQn, (uint32_t)ipc_isr); + NVIC_EnableIRQ(IPC_IRQn); +} + +void +hal_ipc_start(void) +{ + if (MYNEWT_VAL(MCU_APP_SECURE)) { + /* this allows netcore to access appcore RAM */ + NRF_SPU_S->EXTDOMAIN[0].PERM = SPU_EXTDOMAIN_PERM_SECATTR_Secure << SPU_EXTDOMAIN_PERM_SECATTR_Pos; + } + + /* Start Network Core */ + nrf_reset_network_force_off(NRF_RESET, false); + + /* + * Wait for NET core to start and init it's side of IPC. + * It may take several seconds if there is net core + * embedded image in the application flash. + */ +} diff --git a/hw/mcu/nordic/nrf5340/syscfg.yml b/hw/mcu/nordic/nrf5340/syscfg.yml index cfa8e4374a..d127648c69 100644 --- a/hw/mcu/nordic/nrf5340/syscfg.yml +++ b/hw/mcu/nordic/nrf5340/syscfg.yml @@ -579,6 +579,17 @@ syscfg.defs: Adds default MPU configuration package value: 0 + IPC_NRF5340_PRE_TRUSTZONE_NETCORE_BOOT: + description: > + Set this to one only in case of the bootloader predates TrustZone + changes. With ARM TrusZone support added NRF_IPC_NS block is used + for both secure and non-secure application. Pre-TrustZone code + was always running in secure mode and network core code always + accessed NRF_IP_S (including code that is running in bootloader). + NRF_IP_S->GPMEM[] was used to pass address of net core application + image to net bootloader. + value: 0 + syscfg.vals: OS_TICKS_PER_SEC: 128 diff --git a/hw/mcu/nordic/nrf5340_net/nrf5340_net.ld b/hw/mcu/nordic/nrf5340_net/nrf5340_net.ld index 74a20ff494..8544f58425 100644 --- a/hw/mcu/nordic/nrf5340_net/nrf5340_net.ld +++ b/hw/mcu/nordic/nrf5340_net/nrf5340_net.ld @@ -138,6 +138,22 @@ INCLUDE "link_tables.ld.h" *(.ipc) } > IPC + /* Section for IPC RX */ + .ipc0_rx (NOLOAD): + { + . = ALIGN(4); + *(.ipc0_rx) + . = ALIGN(4); + } > sram_ipc0_rx + + /* Section for IPC TX */ + .ipc0_tx (NOLOAD): + { + . = ALIGN(4); + *(.ipc0_tx) + . = ALIGN(4); + } > sram_ipc0_tx + /* This section will be zeroed by RTT package init */ .rtt (NOLOAD): { diff --git a/hw/mcu/nordic/nrf5340_net/pkg.yml b/hw/mcu/nordic/nrf5340_net/pkg.yml index 83146c6566..55fe9de50a 100644 --- a/hw/mcu/nordic/nrf5340_net/pkg.yml +++ b/hw/mcu/nordic/nrf5340_net/pkg.yml @@ -28,8 +28,13 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/hw/mcu/nordic" - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" + +pkg.deps.'BLE_TRANSPORT_HS == "nrf5340"': - "@apache-mynewt-core/hw/drivers/ipc_nrf5340" +pkg.deps.'BLE_TRANSPORT_HS == "ipc"': + - "@apache-mynewt-core/hw/drivers/ipc" + pkg.cflags.NFC_PINS_AS_GPIO: - '-DCONFIG_NFCT_PINS_AS_GPIOS=1' diff --git a/hw/mcu/nordic/nrf5340_net/src/hal_ipc.c b/hw/mcu/nordic/nrf5340_net/src/hal_ipc.c new file mode 100644 index 0000000000..98d669cbd6 --- /dev/null +++ b/hw/mcu/nordic/nrf5340_net/src/hal_ipc.c @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef BIT +#define BIT(n) (1UL << (n)) +#endif + +#define IPC_MAX_CHANS 4 + +static hal_ipc_cb cbs[IPC_MAX_CHANS]; + +int +hal_ipc_signal(uint8_t channel) +{ + assert(channel < IPC_MAX_CHANS); + + nrf_ipc_task_trigger(NRF_IPC, nrf_ipc_send_task_get(channel)); + + return 0; +} + +void +hal_ipc_register_callback(uint8_t channel, hal_ipc_cb cb) +{ + assert(channel < IPC_MAX_CHANS); + + cbs[channel] = cb; +} + +void +hal_ipc_enable_irq(uint8_t channel, bool enable) +{ + assert(channel < IPC_MAX_CHANS); + + if (enable) { + NRF_IPC->RECEIVE_CNF[channel] = BIT(channel); + NRF_IPC->INTENSET = BIT(channel); + } else { + NRF_IPC->INTENCLR = BIT(channel); + NRF_IPC->RECEIVE_CNF[channel] = 0; + } +} + +static void +ipc_isr(void) +{ + uint32_t irq_pend; + uint8_t channel; + + os_trace_isr_enter(); + + /* Handle only interrupts that were enabled */ + irq_pend = NRF_IPC->INTPEND & NRF_IPC->INTEN; + + for (channel = 0; channel < IPC_MAX_CHANS; ++channel) { + if (irq_pend & BIT(channel)) { + NRF_IPC->EVENTS_RECEIVE[channel] = 0; + + if (cbs[channel] != NULL) { + cbs[channel](channel); + } + } + } + + os_trace_isr_exit(); +} + +void +hal_ipc_init(void) +{ + uint8_t i; + + /* Enable IPC channels */ + for (i = 0; i < IPC_MAX_CHANS; ++i) { + NRF_IPC->SEND_CNF[i] = BIT(i); + NRF_IPC->RECEIVE_CNF[i] = 0; + } + + NRF_IPC->INTENCLR = 0xFFFF; + NVIC_ClearPendingIRQ(IPC_IRQn); + NVIC_SetVector(IPC_IRQn, (uint32_t)ipc_isr); + NVIC_EnableIRQ(IPC_IRQn); +} + +void +hal_ipc_start(void) +{ +} diff --git a/hw/mcu/nordic/nrf5340_net/src/hal_os_tick.c b/hw/mcu/nordic/nrf5340_net/src/hal_os_tick.c index 3d85ae9066..7a2132335c 100644 --- a/hw/mcu/nordic/nrf5340_net/src/hal_os_tick.c +++ b/hw/mcu/nordic/nrf5340_net/src/hal_os_tick.c @@ -29,10 +29,6 @@ #endif #define RTC_FREQ 32768 /* in Hz */ -#define OS_TICK_TIMER NRF_RTC1_NS -#define OS_TICK_IRQ RTC1_IRQn -#define OS_TICK_CMPREG 3 -#define RTC_COMPARE_INT_MASK(ccreg) (1UL << ((ccreg) + 16)) struct hal_os_tick { int ticks_per_ostick; @@ -41,6 +37,7 @@ struct hal_os_tick { }; struct hal_os_tick g_hal_os_tick; +struct hal_timer os_tick_timer; /* * Implement (x - y) where the range of both 'x' and 'y' is limited to 24-bits. @@ -72,39 +69,19 @@ sub24(uint32_t x, uint32_t y) static inline uint32_t nrf5340_net_os_tick_counter(void) { - return OS_TICK_TIMER->COUNTER; + return os_cputime_get32(); } static inline void nrf5340_net_os_tick_set_ocmp(uint32_t ocmp) { - int delta; - uint32_t counter; - OS_ASSERT_CRITICAL(); - while (1) { - ocmp &= 0xffffff; - OS_TICK_TIMER->CC[OS_TICK_CMPREG] = ocmp; - counter = nrf5340_net_os_tick_counter(); - /* - * From nRF5340 Product specification - * - * - If Counter is 'N' writing (N) or (N + 1) to CC register - * may not trigger a compare event. - * - * - If Counter is 'N' writing (N + 2) to CC register is guaranteed - * to trigger a compare event at 'N + 2'. - */ - delta = sub24(ocmp, counter); - if (delta > 2) { - break; - } - ocmp += g_hal_os_tick.ticks_per_ostick; - } + ocmp &= 0xffffff; + os_cputime_timer_start(&os_tick_timer, ocmp); } static void -nrf5340_net_timer_handler(void) +nrf5340_net_timer_handler(void *arg) { int delta; int ticks; @@ -122,7 +99,6 @@ nrf5340_net_timer_handler(void) os_time_advance(ticks); /* Clear timer interrupt */ - OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0; /* Update the time associated with the most recent tick */ g_hal_os_tick.lastocmp = (g_hal_os_tick.lastocmp + @@ -161,15 +137,13 @@ os_tick_idle(os_time_t ticks) * Update OS time before anything else when coming out of * the tickless regime. */ - nrf5340_net_timer_handler(); + nrf5340_net_timer_handler(NULL); } } void os_tick_init(uint32_t os_ticks_per_sec, int prio) { - uint32_t sr; - assert(RTC_FREQ % os_ticks_per_sec == 0); g_hal_os_tick.lastocmp = 0; @@ -182,29 +156,6 @@ os_tick_init(uint32_t os_ticks_per_sec, int prio) */ g_hal_os_tick.max_idle_ticks = (1UL << 22) / g_hal_os_tick.ticks_per_ostick; - /* disable interrupts */ - OS_ENTER_CRITICAL(sr); - - /* Set isr in vector table and enable interrupt */ - NVIC_SetPriority(OS_TICK_IRQ, prio); - NVIC_SetVector(OS_TICK_IRQ, (uint32_t)nrf5340_net_timer_handler); - NVIC_EnableIRQ(OS_TICK_IRQ); - - /* - * Program the OS_TICK_TIMER to operate at 32KHz and trigger an output - * compare interrupt at a rate of 'os_ticks_per_sec'. - */ - OS_TICK_TIMER->TASKS_STOP = 1; - OS_TICK_TIMER->TASKS_CLEAR = 1; - - OS_TICK_TIMER->EVTENCLR = 0xffffffff; - OS_TICK_TIMER->INTENCLR = 0xffffffff; - OS_TICK_TIMER->INTENSET = RTC_COMPARE_INT_MASK(OS_TICK_CMPREG); - - OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0; - OS_TICK_TIMER->CC[OS_TICK_CMPREG] = g_hal_os_tick.ticks_per_ostick; - - OS_TICK_TIMER->TASKS_START = 1; - - OS_EXIT_CRITICAL(sr); + os_cputime_timer_init(&os_tick_timer, nrf5340_net_timer_handler, NULL); + os_cputime_timer_start(&os_tick_timer, g_hal_os_tick.ticks_per_ostick); } diff --git a/hw/mcu/nordic/nrf5340_net/src/hal_vflash.c b/hw/mcu/nordic/nrf5340_net/src/hal_vflash.c index 8024ce4517..dd06a729c7 100644 --- a/hw/mcu/nordic/nrf5340_net/src/hal_vflash.c +++ b/hw/mcu/nordic/nrf5340_net/src/hal_vflash.c @@ -27,7 +27,9 @@ #include #include #include +#if MYNEWT_PKG_apache_mynewt_core__hw_drivers_ipc_nrf5340 #include +#endif #define NRF5340_NET_VFLASH_SECTOR_SZ 2048 @@ -218,7 +220,12 @@ nrf5340_net_vflash_init(const struct hal_flash *dev) const void *img_addr; uint32_t image_size; +#if MYNEWT_PKG_apache_mynewt_core__hw_drivers_ipc_nrf5340 img_addr = ipc_nrf5340_net_image_get(&image_size); +#else + img_addr = 0; + image_size = 0; +#endif /* * Application side IPC will set ipc_share data diff --git a/hw/mcu/nordic/nrf54h20/include/mcu/cmsis_nvic.h b/hw/mcu/nordic/nrf54h20/include/mcu/cmsis_nvic.h new file mode 100644 index 0000000000..0c26de0406 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/include/mcu/cmsis_nvic.h @@ -0,0 +1,28 @@ +/* mbed Microcontroller Library - cmsis_nvic + * Copyright (c) 2009-2011 ARM Limited. All rights reserved. + * + * CMSIS-style functionality to support dynamic vectors + */ + +#ifndef _CMSIS_NVIC_H_ +#define _CMSIS_NVIC_H_ + +#include +#include + +#define NVIC_NUM_VECTORS (16 + 30) /* CORE + MCU Peripherals */ +#define NVIC_USER_IRQ_OFFSET 16 + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_Relocate(void); +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/mcu/nordic/nrf54h20/include/mcu/cortex_m33.h b/hw/mcu/nordic/nrf54h20/include/mcu/cortex_m33.h new file mode 100644 index 0000000000..2cfcaa24a5 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/include/mcu/cortex_m33.h @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _CORTEX_M33_H_ +#define _CORTEX_M33_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void +hal_debug_break(void) +{ + __BKPT(1); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _CORTEX_M33_H_ */ diff --git a/hw/mcu/nordic/nrf54h20/include/mcu/mcu.h b/hw/mcu/nordic/nrf54h20/include/mcu/mcu.h new file mode 100644 index 0000000000..5f654ec659 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/include/mcu/mcu.h @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _MCU_H_ +#define _MCU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Defines for naming GPIOs. NOTE: the nordic chip docs use numeric labels for + * ports. Port A corresponds to Port 0, B to 1, etc. The nrf54h20 has two ports + * but Port 1 only has 16 pins. + */ +#define MCU_GPIO_PORTA(pin) ((0 * 16) + (pin)) +#define MCU_GPIO_PORTB(pin) ((1 * 16) + (pin)) + +#define MCU_SYSVIEW_INTERRUPTS \ + "I#1=Reset,I#2=NonMaskableInt,I#3=HardFault,I#4=MemoryManagement," \ + "I#5=BusFault,I#6=UsageFault,I#7=SecureFault,I#11=SVCall," \ + "I#12=DebugMonitor,I#14=PendSV,I#15=SysTick,I#21=CLOCK_POWER," \ + "I#24=RADIO,I#25=RNG,I#26=GPIOTE,I#27=WDT,I#28=TIMER0,I#29=ECB," \ + "I#30=AAR_CCM,I#32=TEMP,I#33=RTC0,I#34=IPC," \ + "I#35=SPIM0_SPIS0_TWIM0_TWIS0_UARTE0,I#36=EGU0,I#38=RTC1,I" \ + "#40=TIMER1,I#41=TIMER2,I#42=SWI0,I#43=SWI1,I#44=SWI2,I#45=SWI3" + +#ifdef __cplusplus +} +#endif + +#endif /* _MCU_H_ */ diff --git a/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_clock.h b/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_clock.h new file mode 100644 index 0000000000..e3bb8934ed --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_clock.h @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_NRF5340_NET_CLOCK_ +#define H_NRF5340_NET_CLOCK_ + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * Request HFXO clock be turned on. Note that each request must have a + * corresponding release. + * + * @return int 0: hfxo was already on. 1: hfxo was turned on. + */ +int nrf54h20_clock_hfxo_request(void); + +/** + * Release the HFXO; caller no longer needs the HFXO to be turned on. Each call + * to release should have been preceeded by a corresponding call to request the + * HFXO + * + * + * @return int 0: HFXO not stopped by this call (others using it) 1: HFXO + * stopped. + */ +int nrf54h20_clock_hfxo_release(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF5340_NET_CLOCK_ */ diff --git a/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_hal.h b/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_hal.h new file mode 100644 index 0000000000..0c1ee4def4 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_hal.h @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _NRF5340_NET_HAL_H_ +#define _NRF5340_NET_HAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "nrf_hal.h" + +struct nrf54h20_uart_cfg { + int8_t suc_pin_tx; /* pins for IO */ + int8_t suc_pin_rx; + int8_t suc_pin_rts; + int8_t suc_pin_cts; +}; +const struct nrf54h20_uart_cfg *bsp_uart_config(void); + +struct nrf54h20_vflash { + struct hal_flash nv_flash; + const uint8_t *nv_image_address; + uint32_t nv_image_size; + const struct flash_area *nv_slot1; +}; +extern struct nrf54h20_vflash nrf54h20_vflash_dev; + +extern const struct hal_flash nrf54h20_flash_dev; +extern const struct hal_flash *ipc_flash(void); + +/* SPI configuration (used for both master and slave) */ +struct nrf54h20_hal_spi_cfg { + int8_t sck_pin; + int8_t mosi_pin; + int8_t miso_pin; + int8_t ss_pin; +}; + +/* + * GPIO pin mapping + * + * The logical GPIO pin numbers (0 to N) are mapped to ports in the following + * manner: + * pins 0 - 31: Port 0 + * pins 32 - 48: Port 1. + * + * The nrf54h20 has 48 pins and uses two ports. + * + * NOTE: in order to save code space, there is no checking done to see if the + * user specifies a pin that is not used by the processor. If an invalid pin + * number is used unexpected and/or erroneous behavior will result. + */ + +#define HAL_GPIO_INDEX(pin) ((pin) & 0x1F) +#define HAL_GPIO_PORT(pin) ((pin) > 31 ? NRF_P1_NS : NRF_P0_NS) +#define HAL_GPIO_MASK(pin) (1 << HAL_GPIO_INDEX(pin)) +#define HAL_GPIOTE_PIN_MASK (0x3FUL << GPIOTE_CONFIG_PSEL_Pos) + +#ifdef __cplusplus +} +#endif + +#endif /* _NRF5340_NET_HAL_H_ */ + diff --git a/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_periph.h b/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_periph.h new file mode 100644 index 0000000000..b9e7fcba1d --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/include/mcu/nrf54h20_periph.h @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _NRF5340_NET_PERIPH_H_ +#define _NRF5340_NET_PERIPH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void nrf54h20_periph_create(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _NRF5340_NET_PERIPH_H_ */ diff --git a/hw/mcu/nordic/nrf54h20/include/nrfx_config_nrf54h20_application.h b/hw/mcu/nordic/nrf54h20/include/nrfx_config_nrf54h20_application.h new file mode 100644 index 0000000000..e439eaa624 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/include/nrfx_config_nrf54h20_application.h @@ -0,0 +1,1970 @@ +/* + * Copyright (c) 2023 - 2024, Nordic Semiconductor ASA + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRFX_CONFIG_NRF54H20_APPLICATION_H__ +#define NRFX_CONFIG_NRF54H20_APPLICATION_H__ + +#ifndef NRFX_CONFIG_H__ +#error "This file should not be included directly. Include nrfx_config.h instead." +#endif + + +/** + * @brief NRFX_DEFAULT_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_DEFAULT_IRQ_PRIORITY +#define NRFX_DEFAULT_IRQ_PRIORITY 7 +#endif + +/** + * @brief NRFX_BELLBOARD_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD_ENABLED +#define NRFX_BELLBOARD_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_BELLBOARD0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD0_ENABLED +#define NRFX_BELLBOARD0_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD1_ENABLED +#define NRFX_BELLBOARD1_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD2_ENABLED +#define NRFX_BELLBOARD2_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD3_ENABLED +#define NRFX_BELLBOARD3_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_ENABLED +#define NRFX_COMP_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_CONFIG_LOG_ENABLED +#define NRFX_COMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_COMP_CONFIG_LOG_LEVEL +#define NRFX_COMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_ENABLED +#define NRFX_DPPI_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED +#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL +#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000f0 +#endif + +/** + * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e +#endif + +/** + * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 +#endif + +/** + * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 +#endif + +/** + * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 +#endif + +/** + * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000f +#endif + +/** + * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 +#endif + +/** + * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df +#endif + +/** + * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf +#endif + +/** + * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e +#endif + +/** + * @brief NRFX_EGU_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_EGU_ENABLED +#define NRFX_EGU_ENABLED 0 +#endif + +/** + * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_EGU130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_EGU130_ENABLED +#define NRFX_EGU130_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_ENABLED +#define NRFX_GPIOTE_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS + * + * Integer value. Minimum: 0. Maximum: 15. + */ +#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS +#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED +#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL +#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_GPIOTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE130_ENABLED +#define NRFX_GPIOTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_ENABLED +#define NRFX_GRTC_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_AUTOEN + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_AUTOEN +#define NRFX_GRTC_CONFIG_AUTOEN 1 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_AUTOSTART + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_AUTOSTART +#define NRFX_GRTC_CONFIG_AUTOSTART 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT +#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS + * + * Integer value. + */ +#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK + */ +#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000f0 +#endif + +/** + * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED +#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL +#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_LPCOMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_ENABLED +#define NRFX_LPCOMP_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED +#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL +#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_MVDMA_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_MVDMA_ENABLED +#define NRFX_MVDMA_ENABLED 0 +#endif + +/** + * @brief NRFX_MVDMA120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_MVDMA120_ENABLED +#define NRFX_MVDMA120_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_ENABLED +#define NRFX_NFCT_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. + * + * Integer value. Minimum: 0. Maximum: 5. + */ +#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID +#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED +#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL +#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PDM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_ENABLED +#define NRFX_PDM_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_CONFIG_LOG_ENABLED +#define NRFX_PDM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PDM_CONFIG_LOG_LEVEL +#define NRFX_PDM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_BOX_0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_2_ENABLED +#define NRFX_PRS_BOX_2_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_3_ENABLED +#define NRFX_PRS_BOX_3_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_4_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_4_ENABLED +#define NRFX_PRS_BOX_4_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_5_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_5_ENABLED +#define NRFX_PRS_BOX_5_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_6_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_6_ENABLED +#define NRFX_PRS_BOX_6_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_7_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_7_ENABLED +#define NRFX_PRS_BOX_7_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_8_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_8_ENABLED +#define NRFX_PRS_BOX_8_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_9_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_9_ENABLED +#define NRFX_PRS_BOX_9_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_ENABLED +#define NRFX_PWM_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_CONFIG_LOG_ENABLED +#define NRFX_PWM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PWM_CONFIG_LOG_LEVEL +#define NRFX_PWM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PWM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM120_ENABLED +#define NRFX_PWM120_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM130_ENABLED +#define NRFX_PWM130_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM131_ENABLED +#define NRFX_PWM131_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM132_ENABLED +#define NRFX_PWM132_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM133_ENABLED +#define NRFX_PWM133_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_ENABLED +#define NRFX_QDEC_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED +#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL +#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_QDEC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC130_ENABLED +#define NRFX_QDEC130_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC131_ENABLED +#define NRFX_QDEC131_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_ENABLED +#define NRFX_RTC_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_CONFIG_LOG_ENABLED +#define NRFX_RTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_RTC_CONFIG_LOG_LEVEL +#define NRFX_RTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_RTC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC130_ENABLED +#define NRFX_RTC130_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC131_ENABLED +#define NRFX_RTC131_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_ENABLED +#define NRFX_SAADC_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED +#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL +#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_ENABLED +#define NRFX_SPIM_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED +#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL +#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM120_ENABLED +#define NRFX_SPIM120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM121_ENABLED +#define NRFX_SPIM121_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM130_ENABLED +#define NRFX_SPIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM131_ENABLED +#define NRFX_SPIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM132_ENABLED +#define NRFX_SPIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM133_ENABLED +#define NRFX_SPIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM134_ENABLED +#define NRFX_SPIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM135_ENABLED +#define NRFX_SPIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM136_ENABLED +#define NRFX_SPIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM137_ENABLED +#define NRFX_SPIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_ENABLED +#define NRFX_SPIS_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED +#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL +#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIS120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS120_ENABLED +#define NRFX_SPIS120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS130_ENABLED +#define NRFX_SPIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS131_ENABLED +#define NRFX_SPIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS132_ENABLED +#define NRFX_SPIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS133_ENABLED +#define NRFX_SPIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS134_ENABLED +#define NRFX_SPIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS135_ENABLED +#define NRFX_SPIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS136_ENABLED +#define NRFX_SPIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS137_ENABLED +#define NRFX_SPIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_SYSTICK_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SYSTICK_ENABLED +#define NRFX_SYSTICK_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_ENABLED +#define NRFX_TEMP_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED +#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL +#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_ENABLED +#define NRFX_TIMER_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED +#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL +#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER120_ENABLED +#define NRFX_TIMER120_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER121_ENABLED +#define NRFX_TIMER121_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER130_ENABLED +#define NRFX_TIMER130_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER131_ENABLED +#define NRFX_TIMER131_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER132_ENABLED +#define NRFX_TIMER132_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER133_ENABLED +#define NRFX_TIMER133_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER134_ENABLED +#define NRFX_TIMER134_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER135_ENABLED +#define NRFX_TIMER135_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER136_ENABLED +#define NRFX_TIMER136_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER137_ENABLED +#define NRFX_TIMER137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_ENABLED +#define NRFX_TWIM_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED +#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL +#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM130_ENABLED +#define NRFX_TWIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM131_ENABLED +#define NRFX_TWIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM132_ENABLED +#define NRFX_TWIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM133_ENABLED +#define NRFX_TWIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM134_ENABLED +#define NRFX_TWIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM135_ENABLED +#define NRFX_TWIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM136_ENABLED +#define NRFX_TWIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM137_ENABLED +#define NRFX_TWIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ENABLED +#define NRFX_TWIS_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED +#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized only once. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +/** + * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_NO_SYNC_MODE +#define NRFX_TWIS_NO_SYNC_MODE 0 +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL +#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS130_ENABLED +#define NRFX_TWIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS131_ENABLED +#define NRFX_TWIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS132_ENABLED +#define NRFX_TWIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS133_ENABLED +#define NRFX_TWIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS134_ENABLED +#define NRFX_TWIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS135_ENABLED +#define NRFX_TWIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS136_ENABLED +#define NRFX_TWIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS137_ENABLED +#define NRFX_TWIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for configuring GPIO pins is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for configuring PSEL registers is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_TX_LINK +#define NRFX_UARTE_CONFIG_TX_LINK 1 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED +#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 +#endif + +/** + * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE + * + * Integer value. Minimum: 0. Maximum: 255. + */ +#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE +#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 +#endif + +/** + * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED +#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL +#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_UARTE120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE120_ENABLED +#define NRFX_UARTE120_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE130_ENABLED +#define NRFX_UARTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE131_ENABLED +#define NRFX_UARTE131_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE132_ENABLED +#define NRFX_UARTE132_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE133_ENABLED +#define NRFX_UARTE133_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE134_ENABLED +#define NRFX_UARTE134_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE135_ENABLED +#define NRFX_UARTE135_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE136_ENABLED +#define NRFX_UARTE136_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE137_ENABLED +#define NRFX_UARTE137_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_ENABLED +#define NRFX_WDT_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_LOG_ENABLED +#define NRFX_WDT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_WDT_CONFIG_LOG_LEVEL +#define NRFX_WDT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_WDT010_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT010_ENABLED +#define NRFX_WDT010_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT011_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT011_ENABLED +#define NRFX_WDT011_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT131_ENABLED +#define NRFX_WDT131_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT132_ENABLED +#define NRFX_WDT132_ENABLED 0 +#endif + +#endif // NRFX_CONFIG_NRF54H20_APPLICATION_H__ diff --git a/hw/mcu/nordic/nrf54h20/nrf54h20.ld b/hw/mcu/nordic/nrf54h20/nrf54h20.ld new file mode 100644 index 0000000000..c4d0a49e39 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/nrf54h20.ld @@ -0,0 +1,224 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .imghdr (NOLOAD): + { + . = . + _imghdr_size; + } > FLASH + + __text = .; + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + +INCLUDE "link_tables.ld.h" + *(.rodata*) + + *(.eh_frame*) + PROVIDE(mynewt_main = main); + . = ALIGN(4); + } > FLASH + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + /* Section for IPC RX */ + .ipc0_rx (NOLOAD): + { + . = ALIGN(4); + *(.ipc0_rx) + . = ALIGN(4); + } > sram_ipc0_rx + + /* Section for IPC TX */ + .ipc0_tx (NOLOAD): + { + . = ALIGN(4); + *(.ipc0_tx) + . = ALIGN(4); + } > sram_ipc0_tx + + /* This section will be zeroed by RTT package init */ + .rtt (NOLOAD): + { + . = ALIGN(4); + *(.rtt) + . = ALIGN(4); + } > RAM + + .data : + { + __data_start__ = .; + *(vtable) + *(.data*) + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM AT > FLASH + + /* Non-zeroed BSS. This section is similar to BSS, with the following two + * caveats: + * 1. It does not get zeroed at init-time. + * 2. You cannot use it as source memory for EasyDMA. + * + * This section exists because of a hardware defect; see errata 33 and 34 + * in nrf52 errata sheet. + */ + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + _ram_start = ORIGIN(RAM); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} + diff --git a/hw/mcu/nordic/nrf54h20/nrf54h20_ram_resident.ld b/hw/mcu/nordic/nrf54h20/nrf54h20_ram_resident.ld new file mode 100644 index 0000000000..9cc5b105b3 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/nrf54h20_ram_resident.ld @@ -0,0 +1,196 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text = .; + + __isr_vector_start = .; + __vector_tbl_reloc__ = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + +INCLUDE "link_tables.ld.h" + *(.rodata*) + + *(.eh_frame*) + PROVIDE(mynewt_main = main); + . = ALIGN(4); + } > RAM + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > RAM + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > RAM + __exidx_end = .; + + __etext = .; + + /* This section will be zeroed by RTT package init */ + .rtt (NOLOAD): + { + . = ALIGN(4); + *(.rtt) + . = ALIGN(4); + } > RAM + + .data : + { + __data_start__ = .; + *(vtable) + *(.data*) + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM + + /* Non-zeroed BSS. This section is similar to BSS, with the following two + * caveats: + * 1. It does not get zeroed at init-time. + * 2. You cannot use it as source memory for EasyDMA. + * + * This section exists because of a hardware defect; see errata 33 and 34 + * in nrf52 errata sheet. + */ + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + _ram_start = ORIGIN(RAM); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} + diff --git a/hw/mcu/nordic/nrf54h20/pkg.yml b/hw/mcu/nordic/nrf54h20/pkg.yml new file mode 100644 index 0000000000..cf7044d88a --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/pkg.yml @@ -0,0 +1,55 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/mcu/nordic/nrf54h20 +pkg.description: MCU definition for Nordic nRF54H20 ARM Cortex-M33 chip (app core). +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - nrf54 + - nrfx + +pkg.deps: + - "@apache-mynewt-core/hw/mcu/nordic" + - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" +# - "@apache-mynewt-core/hw/drivers/ipc" + - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20/startup" +# +#pkg.cflags.NFC_PINS_AS_GPIO: +# - '-DCONFIG_NFCT_PINS_AS_GPIOS=1' +# +#pkg.cflags.GPIO_AS_PIN_RESET: +# - '-DCONFIG_GPIO_AS_PINRESET=1' +# +#pkg.deps.UART_0: +# - "@apache-mynewt-core/hw/drivers/uart/uart_hal" +# +#pkg.deps.SPI_0_MASTER: +# - "@apache-mynewt-core/hw/bus" +# - "@apache-mynewt-core/hw/bus/drivers/spi_hal" +# +#pkg.deps.I2C_0': +# - "@apache-mynewt-core/hw/bus/drivers/i2c_nrf54h20" + +pkg.deps.TRNG: + - "@apache-mynewt-core/hw/drivers/trng/trng_sw" + +# +#pkg.deps.MCU_DEFAULT_STARTUP: +# - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20/startup" diff --git a/hw/mcu/nordic/nrf54h20/src/hal_flash.c b/hw/mcu/nordic/nrf54h20/src/hal_flash.c new file mode 100644 index 0000000000..9e2f672331 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_flash.c @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +// +//#include +//#include +//#include +//#include +//#include +// +//#define NRF5340_NET_FLASH_SECTOR_SZ 2048 +// +//#define NRF5340_NET_FLASH_READY() (NRF_NVMC->READY == NVMC_READY_READY_Ready) +// +//static int +//nrf54h20_flash_wait_ready(void) +//{ +// int i; +// +// for (i = 0; i < 100000; i++) { +// if (NRF_NVMC_NS->READY == NVMC_READY_READY_Ready) { +// return 0; +// } +// } +// return -1; +//} +// +//static int +//nrf54h20_flash_read(const struct hal_flash *dev, uint32_t address, void *dst, +// uint32_t num_bytes) +//{ +// memcpy(dst, (void *)address, num_bytes); +// return 0; +//} +// +///* +// * Flash write is done by writing 4 bytes at a time at a word boundary. +// */ +//static int +//nrf54h20_flash_write(const struct hal_flash *dev, uint32_t address, +// const void *src, uint32_t num_bytes) +//{ +// int sr; +// int rc = -1; +// uint32_t val; +// int cnt; +// uint32_t tmp; +// +// if (nrf54h20_flash_wait_ready()) { +// return -1; +// } +// __HAL_DISABLE_INTERRUPTS(sr); +// NRF_NVMC_NS->CONFIG = NVMC_CONFIG_WEN_Wen; /* Enable erase OP */ +// tmp = address & 0x3; +// if (tmp) { +// if (nrf54h20_flash_wait_ready()) { +// goto out; +// } +// /* +// * Starts at a non-word boundary. Read 4 bytes which were there +// * before, update with new data, and write back. +// */ +// val = *(uint32_t *)(address & ~0x3); +// cnt = 4 - tmp; +// if (cnt > num_bytes) { +// cnt = num_bytes; +// } +// memcpy((uint8_t *)&val + tmp, src, cnt); +// *(uint32_t *)(address & ~0x3) = val; +// address += cnt; +// num_bytes -= cnt; +// src += cnt; +// } +// +// while (num_bytes >= sizeof(uint32_t)) { +// /* +// * Write data 4 bytes at a time. +// */ +// if (nrf54h20_flash_wait_ready()) { +// goto out; +// } +// *(uint32_t *)address = *(uint32_t *)src; +// address += sizeof(uint32_t); +// src += sizeof(uint32_t); +// num_bytes -= sizeof(uint32_t); +// } +// if (num_bytes) { +// /* +// * Deal with the trailing bytes. +// */ +// val = *(uint32_t *)address; +// memcpy(&val, src, num_bytes); +// if (nrf54h20_flash_wait_ready()) { +// goto out; +// } +// *(uint32_t *)address = val; +// } +// +// rc = nrf54h20_flash_wait_ready(); +//out: +// NRF_NVMC_NS->CONFIG = NVMC_CONFIG_WEN_Ren; +// __HAL_ENABLE_INTERRUPTS(sr); +// return rc; +//} +// +//static int +//nrf54h20_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address) +//{ +// int sr; +// int rc; +// +// sector_address &= ~(NRF5340_NET_FLASH_SECTOR_SZ - 1); +// +// if (nrf54h20_flash_wait_ready()) { +// return -1; +// } +// __HAL_DISABLE_INTERRUPTS(sr); +// +// NRF_NVMC_NS->CONFIG = NVMC_CONFIG_WEN_Een; /* Enable erase OP */ +// *(uint32_t *)sector_address = 0xFFFFFFFF; +// +// rc = nrf54h20_flash_wait_ready(); +// +// NRF_NVMC_NS->CONFIG = NVMC_CONFIG_WEN_Ren; +// __HAL_ENABLE_INTERRUPTS(sr); +// +// return rc; +//} +// +//static int +//nrf54h20_flash_erase(const struct hal_flash *dev, uint32_t address, +// uint32_t num_bytes) +//{ +// uint32_t sector_address; +// +// if (address + num_bytes < dev->hf_base_addr || +// address > dev->hf_base_addr + dev->hf_size) { +// return -1; +// } +// +// sector_address = address & ~(NRF5340_NET_FLASH_SECTOR_SZ - 1); +// num_bytes += address - sector_address; +// num_bytes = (num_bytes + NRF5340_NET_FLASH_SECTOR_SZ - 1) & ~(NRF5340_NET_FLASH_SECTOR_SZ - 1); +// if (sector_address < dev->hf_base_addr) { +// num_bytes -= dev->hf_base_addr - sector_address; +// sector_address = dev->hf_base_addr; +// } +// +// while (num_bytes > 0 && sector_address < dev->hf_base_addr + dev->hf_size) { +// nrf54h20_flash_erase_sector(dev, sector_address); +// num_bytes -= NRF5340_NET_FLASH_SECTOR_SZ; +// sector_address += NRF5340_NET_FLASH_SECTOR_SZ; +// } +// +// return 0; +//} +// +//static int +//nrf54h20_flash_sector_info(const struct hal_flash *dev, int idx, +// uint32_t *address, uint32_t *sz) +//{ +// assert(idx < nrf54h20_flash_dev.hf_sector_cnt); +// *address = dev->hf_base_addr + idx * NRF5340_NET_FLASH_SECTOR_SZ; +// *sz = NRF5340_NET_FLASH_SECTOR_SZ; +// return 0; +//} +// +//static int +//nrf54h20_flash_init(const struct hal_flash *dev) +//{ +// return 0; +//} +// +//static const struct hal_flash_funcs nrf54h20_flash_funcs = { +// .hff_read = nrf54h20_flash_read, +// .hff_write = nrf54h20_flash_write, +// .hff_erase_sector = nrf54h20_flash_erase_sector, +// .hff_sector_info = nrf54h20_flash_sector_info, +// .hff_init = nrf54h20_flash_init, +// .hff_erase = nrf54h20_flash_erase, +//}; +// +//const struct hal_flash nrf54h20_flash_dev = { +// .hf_itf = &nrf54h20_flash_funcs, +// .hf_base_addr = 0x01000000, +// .hf_size = 256 * 1024, /* XXX read from factory info? */ +// .hf_sector_cnt = 128, /* XXX read from factory info? */ +// .hf_align = 1, +// .hf_erased_val = 0xff, +//}; diff --git a/hw/mcu/nordic/nrf54h20/src/hal_ipc.c b/hw/mcu/nordic/nrf54h20/src/hal_ipc.c new file mode 100644 index 0000000000..901505412c --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_ipc.c @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// #include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BIT +#define BIT(n) (1UL << (n)) +#endif + +#define IPC_MAX_CHANS BELLBOARD_EVENTS_TRIGGERED_MaxCount +#define BELLBOARD_IPC0_IRQ BELLBOARD_0_IRQn +#define BELLBOARD_NUM_IRQS 4U +#if MYNEWT_VAL(MCU_APP_CORE) +#define BELLBOARD_LOCAL NRF_APPLICATION_BELLBOARD_S +#define BELLBOARD_REMOTE NRF_RADIOCORE_BELLBOARD_S +#else +#define BELLBOARD_LOCAL NRF_RADIOCORE_BELLBOARD_S +#define BELLBOARD_REMOTE NRF_APPLICATION_BELLBOARD_S +#endif + +/* ipc0: 0: cpurad-cpusec, 6: cpurad-cpusys, 12: cpurad-cpuapp */ +#define BELLBOARD_IPC0_EVENTS_MAP (0x00001041) + +static const uint32_t evt_mappings[BELLBOARD_NUM_IRQS] = { + BELLBOARD_IPC0_EVENTS_MAP, 0, 0, 0 +}; + +static hal_ipc_cb cbs[IPC_MAX_CHANS]; + +int +hal_ipc_signal(uint8_t channel) +{ + assert(channel < IPC_MAX_CHANS); + + nrf_bellboard_task_trigger(BELLBOARD_REMOTE, nrf_bellboard_trigger_task_get(channel)); + + return 0; +} + +void +hal_ipc_register_callback(uint8_t channel, hal_ipc_cb cb) +{ + assert(channel < IPC_MAX_CHANS); + + cbs[channel] = cb; +} + +void +hal_ipc_enable_irq(uint8_t channel, bool enable) +{ + uint8_t i; + + assert(channel < IPC_MAX_CHANS); + + for (i = 0U; i < BELLBOARD_NUM_IRQS; i++) { + + if ((evt_mappings[i] & BIT(channel)) == 0U) { + continue; + } + + if (enable) { + nrf_bellboard_int_enable(BELLBOARD_LOCAL, i, BIT(channel)); + } else { + nrf_bellboard_int_disable(BELLBOARD_LOCAL, i, BIT(channel)); + } + } +} + +static void +ipc0_isr(void) +{ + uint32_t int_pend; + nrf_bellboard_event_t event; + uint8_t channel; + + int_pend = nrf_bellboard_int_pending_get(BELLBOARD_LOCAL, 0); + + for (channel = 0; channel < IPC_MAX_CHANS; channel++) { + event = nrf_bellboard_triggered_event_get(channel); + + if ((int_pend & BIT(channel)) != 0U) { + if (nrf_bellboard_event_check(BELLBOARD_LOCAL, event)) { + nrf_bellboard_event_clear(BELLBOARD_LOCAL, event); + } + + if (cbs[channel] != NULL) { + cbs[channel](channel); + } + } + } +} + +void +hal_ipc_init(void) +{ + uint32_t evt_all_mappings = evt_mappings[0] | evt_mappings[1] | + evt_mappings[2] | evt_mappings[3]; + uint8_t i = 0U; + + for (i = 0U; i < BELLBOARD_NUM_IRQS; ++i) { + nrf_bellboard_int_disable(BELLBOARD_LOCAL, i, evt_mappings[i]); + } + + for (i = 0U; i < IPC_MAX_CHANS; ++i) { + if ((evt_all_mappings & BIT(i)) != 0U) { + nrf_bellboard_event_clear(BELLBOARD_LOCAL, nrf_bellboard_triggered_event_get(i)); + } + } + + NVIC_SetPriority(BELLBOARD_IPC0_IRQ, 1); + NVIC_SetVector(BELLBOARD_IPC0_IRQ, (uint32_t)ipc0_isr); + NVIC_EnableIRQ(BELLBOARD_IPC0_IRQ); +} + +void +hal_ipc_start(void) +{ + +} diff --git a/hw/mcu/nordic/nrf54h20/src/hal_nvreg.c b/hw/mcu/nordic/nrf54h20/src/hal_nvreg.c new file mode 100644 index 0000000000..7db3ed4618 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_nvreg.c @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// #include +// #include +// #include + +// /* There are two GPREGRET registers on the NRF5340 */ +// #define HAL_NVREG_MAX (2) + +// /* GPREGRET registers only save the 8 lsbits */ +// #define HAL_NVREG_WIDTH_BYTES (1) + +// void +// hal_nvreg_write(unsigned int reg, uint32_t val) +// { +// if (reg < HAL_NVREG_MAX) { +// NRF_POWER_NS->GPREGRET[reg] = val; +// } +// } + +// uint32_t +// hal_nvreg_read(unsigned int reg) +// { +// uint32_t val = 0; + +// if (reg < HAL_NVREG_MAX) { +// val = NRF_POWER_NS->GPREGRET[reg]; +// } + +// return val; +// } + +// unsigned int +// hal_nvreg_get_num_regs(void) +// { +// return HAL_NVREG_MAX; +// } + +// unsigned int +// hal_nvreg_get_reg_width(void) +// { +// return HAL_NVREG_WIDTH_BYTES; +// } diff --git a/hw/mcu/nordic/nrf54h20/src/hal_os_tick.c b/hw/mcu/nordic/nrf54h20/src/hal_os_tick.c new file mode 100644 index 0000000000..0df69753aa --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_os_tick.c @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include + +/* The OS scheduler requires a low-frequency timer. */ +#if MYNEWT_VAL(OS_SCHEDULING) && !MYNEWT_VAL(MCU_LFCLK_SOURCE) + #error The OS scheduler requires a low-frequency timer; configure MCU_LFCLK_SOURCE +#endif + +#define RTC_FREQ 32768 /* in Hz */ + +struct hal_os_tick { + int ticks_per_ostick; + os_time_t max_idle_ticks; + uint32_t lastocmp; +}; + +struct hal_os_tick g_hal_os_tick; +struct hal_timer os_tick_timer; + +/* + * Implement (x - y) where the range of both 'x' and 'y' is limited to 24-bits. + * + * For example: + * + * sub24(0, 0xffffff) = 1 + * sub24(0xffffff, 0xfffffe) = 1 + * sub24(0xffffff, 0) = -1 + * sub24(0x7fffff, 0) = 8388607 + * sub24(0x800000, 0) = -8388608 + */ +static inline int +sub24(uint32_t x, uint32_t y) +{ + int result; + + assert(x <= 0xffffff); + assert(y <= 0xffffff); + + result = x - y; + if (result & 0x800000) { + return (result | 0xff800000); + } else { + return (result & 0x007fffff); + } +} + +static inline uint32_t +nrf54h20_os_tick_counter(void) +{ + return os_cputime_get32() & 0x00ffffff; +} + +static inline void +nrf54h20_os_tick_set_ocmp(uint32_t ocmp) +{ +// int delta; +// uint32_t counter; + + OS_ASSERT_CRITICAL(); + ocmp &= 0xffffff; + os_cputime_timer_start(&os_tick_timer, ocmp); +// while (1) { +// ocmp &= 0xffffff; +// counter = nrf54h20_os_tick_counter(); +// /* +// * From nRF5340 Product specification +// * +// * - If Counter is 'N' writing (N) or (N + 1) to CC register +// * may not trigger a compare event. +// * +// * - If Counter is 'N' writing (N + 2) to CC register is guaranteed +// * to trigger a compare event at 'N + 2'. +// */ +// delta = sub24(ocmp, counter); +// if (delta > 2) { +// break; +// } +// ocmp += g_hal_os_tick.ticks_per_ostick; +// } +} + +static void +nrf54h20_timer_handler(void *arg) +{ + int delta; + int ticks; + os_sr_t sr; + uint32_t counter; + + os_trace_isr_enter(); + OS_ENTER_CRITICAL(sr); + + /* Calculate elapsed ticks and advance OS time. */ + + counter = nrf54h20_os_tick_counter(); + delta = sub24(counter, g_hal_os_tick.lastocmp); + ticks = delta / g_hal_os_tick.ticks_per_ostick; + os_time_advance(ticks); + + /* Update the time associated with the most recent tick */ + g_hal_os_tick.lastocmp = (g_hal_os_tick.lastocmp + + (ticks * g_hal_os_tick.ticks_per_ostick)) & 0xffffff; + + /* Update the output compare to interrupt at the next tick */ + nrf54h20_os_tick_set_ocmp(g_hal_os_tick.lastocmp + g_hal_os_tick.ticks_per_ostick); + + OS_EXIT_CRITICAL(sr); + os_trace_isr_exit(); +} + +void +os_tick_idle(os_time_t ticks) +{ + uint32_t ocmp; + + OS_ASSERT_CRITICAL(); + + if (ticks > 0) { + /* + * Enter tickless regime during long idle durations. + */ + if (ticks > g_hal_os_tick.max_idle_ticks) { + ticks = g_hal_os_tick.max_idle_ticks; + } + ocmp = g_hal_os_tick.lastocmp + (ticks*g_hal_os_tick.ticks_per_ostick); + nrf54h20_os_tick_set_ocmp(ocmp); + } + + __DSB(); + __WFI(); + + if (ticks > 0) { + /* + * Update OS time before anything else when coming out of + * the tickless regime. + */ + nrf54h20_timer_handler(NULL); + } +} + +void +os_tick_init(uint32_t os_ticks_per_sec, int prio) +{ + uint32_t sr; + + assert(RTC_FREQ % os_ticks_per_sec == 0); + + g_hal_os_tick.lastocmp = 0; + g_hal_os_tick.ticks_per_ostick = RTC_FREQ / os_ticks_per_sec; + + /* + * The maximum number of OS ticks allowed to elapse during idle is + * limited to 1/4th the number of timer ticks before the 24-bit counter + * rolls over. + */ + g_hal_os_tick.max_idle_ticks = (1UL << 22) / g_hal_os_tick.ticks_per_ostick; + + os_cputime_timer_init(&os_tick_timer, nrf54h20_timer_handler, NULL); + os_cputime_timer_start(&os_tick_timer, g_hal_os_tick.ticks_per_ostick); +} diff --git a/hw/mcu/nordic/nrf54h20/src/hal_reset_cause.c b/hw/mcu/nordic/nrf54h20/src/hal_reset_cause.c new file mode 100644 index 0000000000..dbc3c28935 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_reset_cause.c @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include + +enum hal_reset_reason +hal_reset_cause(void) +{ + static enum hal_reset_reason reason; + uint32_t reg; + + // if (reason) { + // return reason; + // } + + // reg = NRF_RESET_NS->RESETREAS; + + // if (reg & (RESET_RESETREAS_DOG0_Msk | RESET_RESETREAS_DOG1_Msk | RESET_RESETREAS_LOCKUP_Msk)) { + // reason = HAL_RESET_WATCHDOG; + // } else if (reg & RESET_RESETREAS_SREQ_Msk) { + // reason = HAL_RESET_SOFT; + // } else if (reg & RESET_RESETREAS_RESETPIN_Msk) { + // reason = HAL_RESET_PIN; + // } else if (reg & RESET_RESETREAS_OFF_Msk) { + // reason = HAL_RESET_SYS_OFF_INT; + // } else { + // reason = HAL_RESET_POR; /* could also be brownout */ + // } + + // NRF_RESET_NS->RESETREAS = reg; + + return 0; +} diff --git a/hw/mcu/nordic/nrf54h20/src/hal_spi.c b/hw/mcu/nordic/nrf54h20/src/hal_spi.c new file mode 100644 index 0000000000..3c7a0b648c --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_spi.c @@ -0,0 +1,831 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +// #if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE) + +// #define SPIM_TXD_MAXCNT_MAX 0xffff + +// /* Used to disable all interrupts */ +// #define NRF_SPI_IRQ_DISABLE_ALL 0xffffffff + +// /* +// * Slave states +// * +// * IDLE: Slave not ready to be used. If master attempts to access +// * slave it will receive the default character +// * ACQ_SEM: Slave is attempting to acquire semaphore. +// * READY: Slave is ready for master to send it data +// * +// */ +// #define HAL_SPI_SLAVE_STATE_IDLE (0) +// #define HAL_SPI_SLAVE_STATE_ACQ_SEM (1) +// #define HAL_SPI_SLAVE_STATE_READY (2) + +// #if MYNEWT_VAL(SPI_0_MASTER) +// struct nrf54h20_hal_spi +// { +// uint8_t spi_xfr_flag; +// uint8_t dummy_rx; +// uint16_t nhs_buflen; +// uint16_t nhs_bytes_txd; +// struct hal_spi_settings spi_cfg; + +// /* Pointers to tx/rx buffers */ +// uint8_t *nhs_txbuf; +// uint8_t *nhs_rxbuf; + +// /* Callback and arguments */ +// hal_spi_txrx_cb txrx_cb_func; +// void *txrx_cb_arg; +// }; +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// struct nrf54h20_hal_spi +// { +// uint8_t slave_state; +// uint16_t nhs_buflen; +// uint16_t nhs_bytes_txd; +// struct hal_spi_settings spi_cfg; + +// /* Pointers to tx/rx buffers */ +// uint8_t *nhs_txbuf; +// uint8_t *nhs_rxbuf; + +// /* Callback and arguments */ +// hal_spi_txrx_cb txrx_cb_func; +// void *txrx_cb_arg; +// }; +// #endif + +// static struct nrf54h20_hal_spi nrf54h20_hal_spi0; + +// static void +// nrf54h20_spi0_irq_handler(void) +// { +// struct nrf54h20_hal_spi *spi = &nrf54h20_hal_spi0; +// uint16_t xfr_bytes; +// #if MYNEWT_VAL(SPI_0_MASTER) +// uint16_t len; +// #endif + +// os_trace_isr_enter(); + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (NRF_SPIM0_NS->EVENTS_END) { +// NRF_SPIM0_NS->EVENTS_END = 0; + +// /* Should not occur but if no transfer just leave */ +// if (spi->spi_xfr_flag != 0) { +// /* Are there more bytes to send? */ +// xfr_bytes = NRF_SPIM0_NS->TXD.AMOUNT; +// spi->nhs_bytes_txd += xfr_bytes; +// if (spi->nhs_bytes_txd < spi->nhs_buflen) { +// spi->nhs_txbuf += xfr_bytes; +// len = spi->nhs_buflen - spi->nhs_bytes_txd; +// len = min(SPIM_TXD_MAXCNT_MAX, len); +// NRF_SPIM0_NS->TXD.PTR = (uint32_t)spi->nhs_txbuf; +// NRF_SPIM0_NS->TXD.MAXCNT = len; + +// /* If no rxbuf, we need to set rxbuf and maxcnt to 1 */ +// if (spi->nhs_rxbuf) { +// spi->nhs_rxbuf += xfr_bytes; +// NRF_SPIM0_NS->RXD.PTR = (uint32_t)spi->nhs_rxbuf; +// NRF_SPIM0_NS->RXD.MAXCNT = len; +// } +// NRF_SPIM0_NS->TASKS_START = 1; +// } else { +// spi->spi_xfr_flag = 0; +// NRF_SPIM0_NS->INTENCLR = SPIM_INTENSET_END_Msk; +// if (spi->txrx_cb_func) { +// spi->txrx_cb_func(spi->txrx_cb_arg, spi->nhs_buflen); +// } +// } +// } +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// /* Semaphore acquired event */ +// if (NRF_SPIS0_NS->EVENTS_ACQUIRED) { +// NRF_SPIS0_NS->EVENTS_ACQUIRED = 0; + +// if (spi->slave_state == HAL_SPI_SLAVE_STATE_ACQ_SEM) { +// if (spi->nhs_txbuf == NULL) { +// NRF_SPIS0_NS->TXD.PTR = 0; +// NRF_SPIS0_NS->TXD.MAXCNT = 0; +// } else { +// NRF_SPIS0_NS->TXD.PTR = (uint32_t)spi->nhs_txbuf; +// NRF_SPIS0_NS->TXD.MAXCNT = spi->nhs_buflen; +// } + +// if (spi->nhs_rxbuf == NULL) { +// NRF_SPIS0_NS->RXD.PTR = 0; +// NRF_SPIS0_NS->RXD.MAXCNT = 0; +// } else { +// NRF_SPIS0_NS->RXD.PTR = (uint32_t)spi->nhs_rxbuf; +// NRF_SPIS0_NS->RXD.MAXCNT = spi->nhs_buflen; +// } +// NRF_SPIS0_NS->TASKS_RELEASE = 1; +// spi->slave_state = HAL_SPI_SLAVE_STATE_READY; +// } +// } + +// /* SPI transaction complete */ +// if (NRF_SPIS0_NS->EVENTS_END) { +// NRF_SPIS0_NS->EVENTS_END = 0; +// if (spi->slave_state == HAL_SPI_SLAVE_STATE_READY) { +// if (spi->txrx_cb_func) { +// /* Get transfer length */ +// if (spi->nhs_txbuf == NULL) { +// xfr_bytes = NRF_SPIS0_NS->RXD.AMOUNT; +// } else { +// xfr_bytes = NRF_SPIS0_NS->TXD.AMOUNT; +// } +// spi->txrx_cb_func(spi->txrx_cb_arg, xfr_bytes); +// } +// spi->slave_state = HAL_SPI_SLAVE_STATE_IDLE; +// } +// } +// #endif + +// os_trace_isr_exit(); +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// static void +// hal_spi_master_stop_transfer(void) +// { +// NRF_SPIM0_NS->TASKS_STOP = 1; +// while (!NRF_SPIM0_NS->EVENTS_STOPPED) { +// }; +// NRF_SPIM0_NS->EVENTS_STOPPED = 0; +// } + +// static int +// hal_spi_config_master(struct nrf54h20_hal_spi *spi, +// struct hal_spi_settings *settings) +// { +// int rc; +// uint32_t nrf_config; +// uint32_t frequency; +// NRF_GPIO_Type *port; +// uint32_t pin; + +// memcpy(&spi->spi_cfg, settings, sizeof(*settings)); + +// /* +// * Configure SCK. NOTE: this is done here in the config API as the data +// * mode is not set at init time so we do it here when we configure the SPI. +// */ +// pin = NRF_SPIM0_NS->PSEL.SCK & SPIM_PSEL_SCK_PIN_Msk; +// if (NRF_SPIM0_NS->PSEL.SCK & SPIM_PSEL_SCK_PORT_Msk) { +// port = NRF_P1_NS; +// } else { +// port = NRF_P0_NS; +// } + +// if (settings->data_mode <= HAL_SPI_MODE1) { +// port->OUTCLR = (1UL << pin); +// } else { +// port->OUTSET = (1UL << pin); +// } +// port->PIN_CNF[pin] = +// (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | +// (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); + +// /* Only 8-bit word sizes supported. */ +// rc = 0; +// switch (settings->word_size) { +// case HAL_SPI_WORD_SIZE_8BIT: +// break; +// default: +// rc = EINVAL; +// break; +// } + +// switch (settings->data_mode) { +// case HAL_SPI_MODE0: +// nrf_config = (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | +// (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE1: +// nrf_config = (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | +// (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE2: +// nrf_config = (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | +// (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE3: +// nrf_config = (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | +// (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); +// break; +// default: +// nrf_config = 0; +// rc = EINVAL; +// break; +// } + +// /* NOTE: msb first is 0 so no check done */ +// if (settings->data_order == HAL_SPI_LSB_FIRST) { +// nrf_config |= SPIM_CONFIG_ORDER_LsbFirst; +// } +// NRF_SPIM0_NS->CONFIG = nrf_config; + +// switch (settings->baudrate) { +// case 125: +// frequency = SPIM_FREQUENCY_FREQUENCY_K125; +// break; +// case 250: +// frequency = SPIM_FREQUENCY_FREQUENCY_K250; +// break; +// case 500: +// frequency = SPIM_FREQUENCY_FREQUENCY_K500; +// break; +// case 1000: +// frequency = SPIM_FREQUENCY_FREQUENCY_M1; +// break; +// case 2000: +// frequency = SPIM_FREQUENCY_FREQUENCY_M2; +// break; +// case 4000: +// frequency = SPIM_FREQUENCY_FREQUENCY_M4; +// break; +// case 8000: +// frequency = SPIM_FREQUENCY_FREQUENCY_M8; +// break; +// default: +// frequency = 0; +// rc = EINVAL; +// break; +// } +// NRF_SPIM0_NS->FREQUENCY = frequency; + +// return rc; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// static int +// hal_spi_config_slave(struct nrf54h20_hal_spi *spi, +// struct hal_spi_settings *settings) +// { +// int rc; +// uint32_t nrf_config; + +// rc = 0; +// switch (settings->data_mode) { +// case HAL_SPI_MODE0: +// nrf_config = (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) | +// (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE1: +// nrf_config = (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) | +// (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE2: +// nrf_config = (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) | +// (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE3: +// nrf_config = (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) | +// (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); +// break; +// default: +// nrf_config = 0; +// rc = EINVAL; +// break; +// } + +// if (settings->data_order == HAL_SPI_LSB_FIRST) { +// nrf_config |= SPIS_CONFIG_ORDER_LsbFirst; +// } +// NRF_SPIS0_NS->CONFIG = nrf_config; + +// /* Only 8-bit word sizes supported. */ +// switch (settings->word_size) { +// case HAL_SPI_WORD_SIZE_8BIT: +// break; +// default: +// rc = EINVAL; +// break; +// } + +// return rc; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_MASTER) +// static int +// hal_spi_init_master(struct nrf54h20_hal_spi *spi, +// struct nrf54h20_hal_spi_cfg *cfg) +// { +// NRF_GPIO_Type *port; +// uint32_t pin; + +// /* Configure MOSI */ +// port = HAL_GPIO_PORT(cfg->mosi_pin); +// pin = HAL_GPIO_INDEX(cfg->mosi_pin); +// port->OUTCLR = (1UL << pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); + +// /* Configure MISO */ +// port = HAL_GPIO_PORT(cfg->miso_pin); +// pin = HAL_GPIO_INDEX(cfg->miso_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// NRF_SPIM0_NS->PSEL.SCK = cfg->sck_pin; +// NRF_SPIM0_NS->PSEL.MOSI = cfg->mosi_pin; +// NRF_SPIM0_NS->PSEL.MISO = cfg->miso_pin; + +// NRF_SPIM0_NS->INTENCLR = NRF_SPI_IRQ_DISABLE_ALL; +// NVIC_SetVector(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (uint32_t)nrf54h20_spi0_irq_handler); +// NVIC_SetPriority(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (1 << __NVIC_PRIO_BITS) - 1); +// NVIC_ClearPendingIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); +// NVIC_EnableIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); + +// return 0; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// static int +// hal_spi_init_slave(struct nrf54h20_hal_spi *spi, +// struct nrf54h20_hal_spi_cfg *cfg) +// { +// NRF_GPIO_Type *port; +// uint32_t pin; + +// /* NOTE: making this pin an input is correct! See datasheet */ +// port = HAL_GPIO_PORT(cfg->miso_pin); +// pin = HAL_GPIO_INDEX(cfg->miso_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// port = HAL_GPIO_PORT(cfg->mosi_pin); +// pin = HAL_GPIO_INDEX(cfg->mosi_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// port = HAL_GPIO_PORT(cfg->ss_pin); +// pin = HAL_GPIO_INDEX(cfg->ss_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// port = HAL_GPIO_PORT(cfg->sck_pin); +// pin = HAL_GPIO_INDEX(cfg->sck_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// NRF_SPIS0_NS->PSEL.SCK = cfg->sck_pin; +// NRF_SPIS0_NS->PSEL.MOSI = cfg->mosi_pin; +// NRF_SPIS0_NS->PSEL.MISO = cfg->miso_pin; +// NRF_SPIS0_NS->PSEL.CSN = cfg->ss_pin; + +// /* Disable interrupt and clear any interrupt events */ +// NRF_SPIS0_NS->INTENCLR = SPIS_INTENSET_ACQUIRED_Msk | SPIS_INTENSET_END_Msk; +// NRF_SPIS0_NS->EVENTS_END = 0; +// NRF_SPIS0_NS->EVENTS_ACQUIRED = 0; + +// /* Enable END_ACQUIRE shortcut. */ +// NRF_SPIS0_NS->SHORTS = SPIS_SHORTS_END_ACQUIRE_Msk; + +// /* Set interrupt vector and enable IRQ */ +// NVIC_SetVector(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (uint32_t)nrf54h20_spi0_irq_handler); +// NVIC_SetPriority(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (1 << __NVIC_PRIO_BITS) - 1); +// NVIC_ClearPendingIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); +// NVIC_EnableIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); + +// return 0; +// } +// #endif + +// /** +// * Initialize the SPI, given by spi_num. +// * +// * @param spi_num The number of the SPI to initialize +// * @param cfg HW/MCU specific configuration, +// * passed to the underlying implementation, providing extra +// * configuration. +// * @param spi_type SPI type (master or slave) +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_init(int spi_num, void *cfg, uint8_t spi_type) +// { +// struct nrf54h20_hal_spi *spi = &nrf54h20_hal_spi0; + +// /* Check for valid arguments */ +// if (spi_num != 0 || cfg == NULL) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (spi_type != HAL_SPI_TYPE_MASTER) { +// return EINVAL; +// } + +// return hal_spi_init_master(spi, (struct nrf54h20_hal_spi_cfg *)cfg); +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// if (spi_type != HAL_SPI_TYPE_SLAVE) { +// return EINVAL; +// } + +// return hal_spi_init_slave(spi, (struct nrf54h20_hal_spi_cfg *)cfg); +// #endif +// } + +// int +// hal_spi_init_hw(uint8_t spi_num, uint8_t spi_type, +// const struct hal_spi_hw_settings *cfg) +// { +// struct nrf54h20_hal_spi_cfg hal_cfg; + +// hal_cfg.sck_pin = cfg->pin_sck; +// hal_cfg.mosi_pin = cfg->pin_mosi; +// hal_cfg.miso_pin = cfg->pin_miso; +// hal_cfg.ss_pin = cfg->pin_ss; + +// return hal_spi_init(spi_num, &hal_cfg, spi_type); +// } + +// /** +// * Configure the spi. Must be called after the spi is initialized (after +// * hal_spi_init is called) and when the spi is disabled (user must call +// * hal_spi_disable if the spi has been enabled through hal_spi_enable prior +// * to calling this function). Can also be used to reconfigure an initialized +// * SPI (assuming it is disabled as described previously). +// * +// * @param spi_num The number of the SPI to configure. +// * @param psettings The settings to configure this SPI with +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_config(int spi_num, struct hal_spi_settings *settings) +// { +// struct nrf54h20_hal_spi *spi = &nrf54h20_hal_spi0; + +// if (spi_num != 0) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (NRF_SPIM0_NS->ENABLE != 0) { +// return EINVAL; +// } + +// return hal_spi_config_master(spi, settings); +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// if (NRF_SPIS0_NS->ENABLE != 0) { +// return EINVAL; +// } + +// return hal_spi_config_slave(spi, settings); +// #endif +// } + +// /** +// * Enables the SPI. This does not start a transmit or receive operation; +// * it is used for power mgmt. Cannot be called when a SPI transfer is in +// * progress. +// * +// * @param spi_num +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_enable(int spi_num) +// { +// struct nrf54h20_hal_spi *spi = &nrf54h20_hal_spi0; + +// if (spi_num != 0 || spi->txrx_cb_func == NULL) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// NRF_SPIM0_NS->EVENTS_END = 0; +// NRF_SPIM0_NS->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos); +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// NRF_SPIS0_NS->EVENTS_END = 0; +// NRF_SPIS0_NS->EVENTS_ACQUIRED = 0; +// NRF_SPIS0_NS->INTENSET = SPIS_INTENSET_END_Msk | SPIS_INTENSET_ACQUIRED_Msk; +// NRF_SPIS0_NS->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos); +// #endif + +// return 0; +// } + +// /** +// * Disables the SPI. Used for power mgmt. It will halt any current SPI transfers +// * in progress. +// * +// * @param spi_num +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_disable(int spi_num) +// { +// struct nrf54h20_hal_spi *spi = &nrf54h20_hal_spi0; + +// if (spi_num != 0) { +// return -EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// NRF_SPIM0_NS->INTENCLR = NRF_SPI_IRQ_DISABLE_ALL; + +// if (spi->spi_xfr_flag) { +// hal_spi_master_stop_transfer(); +// spi->spi_xfr_flag = 0; +// } +// NRF_SPIM0_NS->ENABLE = 0; +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// NRF_SPIS0_NS->INTENCLR = NRF_SPI_IRQ_DISABLE_ALL; +// NRF_SPIS0_NS->EVENTS_END = 0; +// NRF_SPIS0_NS->EVENTS_ACQUIRED = 0; +// NRF_SPIS0_NS->ENABLE = 0; +// spi->slave_state = HAL_SPI_SLAVE_STATE_IDLE; +// #endif + +// spi->nhs_txbuf = NULL; +// spi->nhs_rxbuf = NULL; +// spi->nhs_buflen = 0; +// spi->nhs_bytes_txd = 0; + +// return 0; +// } + +// /** +// * Sets the txrx callback (executed at interrupt context) when the +// * buffer is transferred by the master or the slave using the non-blocking API. +// * Cannot be called when the spi is enabled. This callback will also be called +// * when chip select is de-asserted on the slave. +// * +// * NOTE: This callback is only used for the non-blocking interface and must +// * be called prior to using the non-blocking API. +// * +// * @param spi_num SPI interface on which to set callback +// * @param txrx Callback function +// * @param arg Argument to be passed to callback function +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_set_txrx_cb(int spi_num, hal_spi_txrx_cb txrx_cb, void *arg) +// { +// struct nrf54h20_hal_spi *spi = &nrf54h20_hal_spi0; + +// if (spi_num != 0) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (NRF_SPIM0_NS->ENABLE != 0) { +// return EINVAL; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// if (NRF_SPIS0_NS->ENABLE != 0) { +// return EINVAL; +// } +// #endif + +// spi->txrx_cb_func = txrx_cb; +// spi->txrx_cb_arg = arg; + +// return 0; +// } + +// /** +// * Non-blocking interface to send a buffer and store received values. Can be +// * used for both master and slave SPI types. The user must configure the +// * callback (using hal_spi_set_txrx_cb); the txrx callback is executed at +// * interrupt context when the buffer is sent. +// * +// * The transmit and receive buffers are either arrays of 8-bit (uint8_t) +// * values or 16-bit values depending on whether the spi is configured for 8 bit +// * data or more than 8 bits per value. The 'cnt' parameter is the number of +// * 8-bit or 16-bit values. Thus, if 'cnt' is 10, txbuf/rxbuf would point to an +// * array of size 10 (in bytes) if the SPI is using 8-bit data; otherwise +// * txbuf/rxbuf would point to an array of size 20 bytes (ten, uint16_t values). +// * +// * NOTE: these buffers are in the native endian-ness of the platform. +// * +// * MASTER: master sends all the values in the buffer and stores the +// * stores the values in the receive buffer if rxbuf is not NULL. +// * The txbuf parameter cannot be NULL +// * SLAVE: Slave "preloads" the data to be sent to the master (values +// * stored in txbuf) and places received data from master in rxbuf +// * (if not NULL). The txrx callback occurs when len values are +// * transferred or master de-asserts chip select. If txbuf is NULL, +// * the slave transfers its default byte. Both rxbuf and txbuf cannot +// * be NULL. +// * +// * @param spi_num SPI interface to use +// * @param txbuf Pointer to buffer where values to transmit are stored. +// * @param rxbuf Pointer to buffer to store values received from peer. +// * @param cnt Number of 8-bit or 16-bit values to be transferred. +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int len) +// { +// struct nrf54h20_hal_spi *spi = &nrf54h20_hal_spi0; + +// if (spi_num != 0 || (spi->txrx_cb_func == NULL) || (len == 0) || !nrfx_is_in_ram(txbuf)) { +// return EINVAL; +// } + +// if (rxbuf != NULL && !nrfx_is_in_ram(rxbuf)) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// /* Must have a txbuf for master! */ +// if (txbuf == NULL) { +// return EINVAL; +// } + +// /* Not allowed if transfer in progress */ +// if (spi->spi_xfr_flag) { +// return EBUSY; +// } + +// NRF_SPIM0_NS->INTENCLR = SPIM_INTENCLR_END_Msk; +// spi->spi_xfr_flag = 1; + +// /* Set internal data structure information */ +// spi->nhs_bytes_txd = 0; +// spi->nhs_buflen = len; +// spi->nhs_txbuf = txbuf; + +// len = min(SPIM_TXD_MAXCNT_MAX, len); + +// /* Set chip registers */ +// NRF_SPIM0_NS->TXD.PTR = (uint32_t)txbuf; +// NRF_SPIM0_NS->TXD.MAXCNT = len; + +// /* If no rxbuf, we need to set rxbuf and maxcnt to 1 */ +// spi->nhs_rxbuf = rxbuf; +// if (rxbuf == NULL) { +// NRF_SPIM0_NS->RXD.PTR = (uint32_t)&spi->dummy_rx; +// NRF_SPIM0_NS->RXD.MAXCNT = 1; +// } else { +// NRF_SPIM0_NS->RXD.PTR = (uint32_t)rxbuf; +// NRF_SPIM0_NS->RXD.MAXCNT = len; +// } + +// NRF_SPIM0_NS->EVENTS_END = 0; +// NRF_SPIM0_NS->EVENTS_STOPPED = 0; +// NRF_SPIM0_NS->TASKS_START = 1; +// NRF_SPIM0_NS->INTENSET = SPIM_INTENSET_END_Msk; +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// /* Must have txbuf or rxbuf */ +// if ((txbuf == NULL) && (rxbuf == NULL)) { +// return EINVAL; +// } + +// /* XXX: what to do here? */ +// if (len > 255) { +// return EINVAL; +// } + +// /* +// * Ready the slave for a transfer. Do not allow this to be called +// * if the slave has already been readied or is requesting the +// * semaphore +// */ +// if (spi->slave_state != HAL_SPI_SLAVE_STATE_IDLE) { +// return EBUSY; +// } + +// spi->nhs_rxbuf = rxbuf; +// spi->nhs_txbuf = txbuf; +// spi->nhs_buflen = len; +// spi->slave_state = HAL_SPI_SLAVE_STATE_ACQ_SEM; +// NRF_SPIS0_NS->TASKS_ACQUIRE = 1; +// #endif + +// return 0; +// } + +// /** +// * Sets the default value transferred by the slave. Not valid for master +// * +// * @param spi_num SPI interface to use +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_slave_set_def_tx_val(int spi_num, uint16_t val) +// { +// #if MYNEWT_VAL(SPI_0_SLAVE) +// if (spi_num != 0){ +// return EINVAL; +// } + +// NRF_SPIS0_NS->DEF = (uint8_t)val; +// NRF_SPIS0_NS->ORC = (uint8_t)val; + +// return 0; +// #else +// return EINVAL; +// #endif +// } + +// /** +// * This aborts the current transfer but keeps the spi enabled. +// * +// * @param spi_num SPI interface on which transfer should be aborted. +// * +// * @return int 0 on success, non-zero error code on failure. +// * +// * NOTE: does not return an error if no transfer was in progress. +// */ +// int +// hal_spi_abort(int spi_num) +// { +// if (spi_num != 0) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (nrf54h20_hal_spi0.spi_xfr_flag) { +// NRF_SPIM0_NS->INTENCLR = NRF_SPI_IRQ_DISABLE_ALL; +// hal_spi_master_stop_transfer(); +// nrf54h20_hal_spi0.spi_xfr_flag = 0; +// NRF_SPIM0_NS->INTENSET = SPIM_INTENSET_END_Msk; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// /* Only way I can see doing this is to disable, then re-enable */ +// rc = hal_spi_disable(spi_num); +// if (rc) { +// return rc; +// } +// rc = hal_spi_enable(spi_num); +// if (rc) { +// return rc; +// } +// #endif + +// return 0; +// } + +// #endif diff --git a/hw/mcu/nordic/nrf54h20/src/hal_system.c b/hw/mcu/nordic/nrf54h20/src/hal_system.c new file mode 100644 index 0000000000..cedabddbcd --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_system.c @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* stack limit provided by linker script */ +extern uint32_t __StackLimit[]; +extern int nrf54h20_clock_grtc_init(void); + +void +hal_system_init(void) +{ + uint32_t rc; + + NVIC_Relocate(); + +// assert(nrf54h20_clock_grtc_init() == 0); + + /* Setup Cortex-M33 stack limiter to detect stack overflow in interrupts and bootloader code */ + __set_MSPLIM((uint32_t)__StackLimit); +} + +void +hal_system_reset(void) +{ + #if MYNEWT_VAL(HAL_SYSTEM_RESET_CB) + hal_system_reset_cb(); + #endif + + while (1) { + HAL_DEBUG_BREAK(); + NVIC_SystemReset(); + } +} + +int +hal_debugger_connected(void) { + return CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk; +} + +/** + * hal system clock start + * + * Makes sure the LFCLK and/or HFCLK is started. + */ +void +hal_system_clock_start(void) +{ + /* 1. Start local RTC (radiocore only) + * 2. Get value of GRTC (available for both cores) + * 3. Get ticks difference between RTC and GRTC + * 4. Configure abstract timers over the Higher-Speed and High-Speed timers. + */ +} diff --git a/hw/mcu/nordic/nrf54h20/src/hal_system_start.c b/hw/mcu/nordic/nrf54h20/src/hal_system_start.c new file mode 100644 index 0000000000..a44606bcb6 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_system_start.c @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +// +///** +// * Boots the image described by the supplied image header. +// * +// * @param hdr The header for the image to boot. +// */ +//void __attribute__((naked)) +//hal_system_start(void *img_start) +//{ +// uint32_t *img_data = img_start; +// +// asm volatile (".syntax unified \n" +// /* 1st word is stack pointer */ +// " msr msp, %0 \n" +// /* 2nd word is a reset handler (image entry) */ +// " bx %1 \n" +// : /* no output */ +// : "r" (img_data[0]), "r" (img_data[1])); +//} +// +///** +// * Boots the image described by the supplied image header. +// * This routine is used in split-app scenario when loader decides +// * that it wants to run the app instead. +// * +// * @param hdr The header for the image to boot. +// */ +//void +//hal_system_restart(void *img_start) +//{ +// int i; +// +// /* +// * NOTE: on reset, PRIMASK should have global interrupts enabled so +// * the code disables interrupts, clears the interrupt enable bits, +// * clears any pending interrupts, then enables global interrupts +// * so processor looks like state it would be in if it reset. +// */ +// __disable_irq(); +// for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) { +// NVIC->ICER[i] = 0xffffffff; +// } +// +// for (i = 0; i < sizeof(NVIC->ICPR) / sizeof(NVIC->ICPR[0]); i++) { +// NVIC->ICPR[i] = 0xffffffff; +// } +// __enable_irq(); +// +// hal_system_start(img_start); +//} diff --git a/hw/mcu/nordic/nrf54h20/src/hal_timer.c b/hw/mcu/nordic/nrf54h20/src/hal_timer.c new file mode 100644 index 0000000000..0853252f20 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_timer.c @@ -0,0 +1,900 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* IRQ prototype */ +typedef void (*hal_timer_irq_handler_t)(void); + +/* User CC 2 for reading counter, CC 3 for timer isr */ +#define NRF_TIMER_CC_READ (2) +#define NRF_TIMER_CC_INT (3) + +/* Output compare 2 used for RTC timers */ +#define NRF_RTC_TIMER_CC_INT (2) + +/* Maximum number of hal timers used */ +#define nrf54h20_hal_timer_MAX (5) + +/* Maximum timer frequency */ +#define NRF54H20_MAX_TIMER_FREQ (32000000) + +struct nrf54h20_hal_timer { + uint8_t tmr_enabled; + uint16_t tmr_irq_num; + uint8_t tmr_rtc; + uint8_t tmr_pad; + uint32_t tmr_cntr; + uint32_t timer_isrs; + uint32_t tmr_freq; + void *tmr_reg; + TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_q; +}; + +#if MYNEWT_VAL(TIMER_0) +struct nrf54h20_hal_timer nrf54h20_hal_timer0; +#endif +#if MYNEWT_VAL(TIMER_1) +struct nrf54h20_hal_timer nrf54h20_hal_timer1; +#endif +#if MYNEWT_VAL(TIMER_2) +struct nrf54h20_hal_timer nrf54h20_hal_timer2; +#endif +#if MYNEWT_VAL(TIMER_3) +struct nrf54h20_hal_timer nrf54h20_hal_timer3; +#endif +#if MYNEWT_VAL(TIMER_4) +struct nrf54h20_hal_timer nrf54h20_hal_timer4; +#endif + +static const struct nrf54h20_hal_timer *nrf54h20_hal_timers[nrf54h20_hal_timer_MAX] = { +#if MYNEWT_VAL(TIMER_0) + &nrf54h20_hal_timer0, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_1) + &nrf54h20_hal_timer1, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_2) + &nrf54h20_hal_timer2, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_3) + &nrf54h20_hal_timer3, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_4) + &nrf54h20_hal_timer4, +#else + NULL, +#endif +}; + +/* Resolve timer number into timer structure */ +#define nrf54h20_hal_timer_RESOLVE(__n, __v) \ + if ((__n) >= nrf54h20_hal_timer_MAX) { \ + rc = EINVAL; \ + goto err; \ + } \ + (__v) = (struct nrf54h20_hal_timer *) nrf54h20_hal_timers[(__n)]; \ + if ((__v) == NULL) { \ + rc = EINVAL; \ + goto err; \ + } + +/* Interrupt mask for interrupt enable/clear */ +#define NRF_TIMER_INT_MASK(x) ((1 << (uint32_t)(x)) << TIMER_INTENCLR_COMPARE0_Pos) + +static uint32_t +nrf_read_timer_cntr(NRF_TIMER_Type *hwtimer) +{ + uint32_t tcntr; + + /* Force a capture of the timer into 'cntr' capture channel; read it */ + hwtimer->TASKS_CAPTURE[NRF_TIMER_CC_READ] = 1; + tcntr = hwtimer->CC[NRF_TIMER_CC_READ]; + + return tcntr; +} + +/** + * Set the OCMP used by the timer to the desired expiration tick + * + * NOTE: Must be called with interrupts disabled. + * + * @param bsptimer Pointer to timer. + * @param expiry Expiration tick + */ +static void +nrf_timer_set_ocmp(struct nrf54h20_hal_timer *bsptimer, uint32_t expiry) +{ + int32_t delta_t; + uint32_t temp; + uint32_t cntr; + NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; + + if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + temp = bsptimer->tmr_cntr; + cntr = rtctimer->COUNTER; + if (rtctimer->EVENTS_OVRFLW) { + temp += (1UL << 24); + cntr = rtctimer->COUNTER; + } + temp |= cntr; + delta_t = (int32_t)(expiry - temp); + + /* + * The nRF5340 documentation states that COMPARE event is guaranteed + * only if value written to CC register is at least 2 greater than the + * current counter value. We also need to account for possible extra + * tick during calculations so effectively any delta less than 3 needs + * to be handled differently. TICK event is used to have interrupt on + * each subsequent tick so we won't miss any and in case we detected + * mentioned extra tick during calculations, interrupt is triggered + * immediately. Delta 0 or less means we should always fire immediately. + */ + if (delta_t < 1) { + rtctimer->INTENCLR = RTC_INTENCLR_TICK_Msk; + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } else if (delta_t < 3) { + rtctimer->INTENSET = RTC_INTENSET_TICK_Msk; + if (rtctimer->COUNTER != cntr) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + } else { + rtctimer->INTENCLR = RTC_INTENCLR_TICK_Msk; + + if (delta_t < (1UL << 24)) { + rtctimer->CC[NRF_RTC_TIMER_CC_INT] = expiry & 0x00ffffff; + } else { + /* CC too far ahead. Just make sure we set compare far ahead */ + rtctimer->CC[NRF_RTC_TIMER_CC_INT] = cntr + (1UL << 23); + } + rtctimer->INTENSET = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + } + } else { + hwtimer = bsptimer->tmr_reg; + + /* Disable ocmp interrupt and set new value */ + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + + /* Set output compare register to timer expiration */ + hwtimer->CC[NRF_TIMER_CC_INT] = expiry; + + /* Clear interrupt flag */ + hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0; + + /* Enable the output compare interrupt */ + hwtimer->INTENSET = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + + /* Force interrupt to occur as we may have missed it */ + if ((int32_t)(nrf_read_timer_cntr(hwtimer) - expiry) >= 0) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + } +} + +/* Disable output compare used for timer */ +static void +nrf_timer_disable_ocmp(NRF_TIMER_Type *hwtimer) +{ + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); +} + +static void +nrf_rtc_disable_ocmp(NRF_RTC_Type *rtctimer) +{ + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + rtctimer->INTENCLR = RTC_INTENCLR_TICK_Msk; +} + +static uint32_t +hal_timer_read_bsptimer(struct nrf54h20_hal_timer *bsptimer) +{ + uint32_t low32; + uint32_t ctx; + uint32_t tcntr; + NRF_RTC_Type *rtctimer; + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + __HAL_DISABLE_INTERRUPTS(ctx); + tcntr = bsptimer->tmr_cntr; + low32 = rtctimer->COUNTER; + if (rtctimer->EVENTS_OVRFLW) { + tcntr += (1UL << 24); + bsptimer->tmr_cntr = tcntr; + low32 = rtctimer->COUNTER; + rtctimer->EVENTS_OVRFLW = 0; + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + tcntr |= low32; + __HAL_ENABLE_INTERRUPTS(ctx); + + return tcntr; +} + +#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \ + MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4)) + +static void +hal_timer_chk_queue(struct nrf54h20_hal_timer *bsptimer) +{ + uint32_t tcntr; + uint32_t ctx; + struct hal_timer *timer; + + /* disable interrupts */ + __HAL_DISABLE_INTERRUPTS(ctx); + while ((timer = TAILQ_FIRST(&bsptimer->hal_timer_q)) != NULL) { + if (bsptimer->tmr_rtc) { + tcntr = hal_timer_read_bsptimer(bsptimer); + } else { + tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + } + if ((int32_t)(tcntr - timer->expiry) >= 0) { + TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link); + timer->link.tqe_prev = NULL; + timer->cb_func(timer->cb_arg); + } else { + break; + } + } + + /* Any timers left on queue? If so, we need to set OCMP */ + timer = TAILQ_FIRST(&bsptimer->hal_timer_q); + if (timer) { + nrf_timer_set_ocmp(bsptimer, timer->expiry); + } else { + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } + } + __HAL_ENABLE_INTERRUPTS(ctx); +} +#endif + +/** + * Generic HAL timer irq handler. + * + * @param bsptimer Pointer to timer. + */ +#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2)) +static void +hal_timer_irq_handler(struct nrf54h20_hal_timer *bsptimer) +{ + uint32_t compare; + NRF_TIMER_Type *hwtimer; + + os_trace_isr_enter(); + + /* Check interrupt source. If set, clear them */ + hwtimer = bsptimer->tmr_reg; + compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT]; + if (compare) { + hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0; + } + + /* Count # of timer isrs */ + ++bsptimer->timer_isrs; + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + if (hwtimer->INTENCLR & NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)) { + hal_timer_chk_queue(bsptimer); + /* XXX: Recommended by nordic to make sure interrupts are cleared */ + compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT]; + } + + os_trace_isr_exit(); +} +#endif + +/** + * Generic HAL RTC timer irq handler. + * + * @param bsptimer Pointer to timer. + */ +#if MYNEWT_VAL(TIMER_3) +static void +hal_rtc_timer_irq_handler(struct nrf54h20_hal_timer *bsptimer) +{ + uint32_t overflow; + uint32_t compare; + uint32_t tick; + NRF_RTC_Type *rtctimer; + + os_trace_isr_enter(); + + /* Check interrupt source. If set, clear them */ + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; + if (compare) { + rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT] = 0; + } + + tick = rtctimer->EVENTS_TICK; + if (tick) { + rtctimer->EVENTS_TICK = 0; + } + + overflow = rtctimer->EVENTS_OVRFLW; + if (overflow) { + rtctimer->EVENTS_OVRFLW = 0; + bsptimer->tmr_cntr += (1UL << 24); + } + + /* Count # of timer isrs */ + ++bsptimer->timer_isrs; + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + hal_timer_chk_queue(bsptimer); + + /* Recommended by nordic to make sure interrupts are cleared */ + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; + + os_trace_isr_exit(); +} +#endif + +#if MYNEWT_VAL(TIMER_0) +void +nrf54h20_timer0_irq_handler(void) +{ + hal_timer_irq_handler(&nrf54h20_hal_timer0); +} +#endif + +#if MYNEWT_VAL(TIMER_1) +void +nrf54h20_timer1_irq_handler(void) +{ + hal_timer_irq_handler(&nrf54h20_hal_timer1); +} +#endif + +#if MYNEWT_VAL(TIMER_2) +void +nrf54h20_timer2_irq_handler(void) +{ + hal_timer_irq_handler(&nrf54h20_hal_timer2); +} +#endif + +#if MYNEWT_VAL(TIMER_3) +void +nrf54h20_timer3_irq_handler(void) +{ + hal_rtc_timer_irq_handler(&nrf54h20_hal_timer3); +} +#endif + +#if MYNEWT_VAL(TIMER_4) +void +nrf54h20_timer4_irq_handler(void) +{ + hal_timer_irq_handler(&nrf54h20_hal_timer4); +} +#endif + +/** + * Initialize platform specific timer items + * + * @param timer_num Timer number to initialize + * @param cfg Pointer to platform specific configuration + * + * @return int 0: success; error code otherwise + */ +int +hal_timer_init(int timer_num, void *cfg) +{ + int rc; + uint16_t irq_num; + struct nrf54h20_hal_timer *bsptimer; + void *hwtimer; + hal_timer_irq_handler_t irq_isr; + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + + /* If timer is enabled do not allow init */ + if (bsptimer->tmr_enabled) { + rc = EINVAL; + goto err; + } + + switch (timer_num) { +#if MYNEWT_VAL(TIMER_0) + case 0: + irq_num = TIMER120_IRQn; + hwtimer = NRF_TIMER120_S; + irq_isr = nrf54h20_timer0_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_1) + case 1: + irq_num = TIMER121_IRQn; + hwtimer = NRF_TIMER121_S; + irq_isr = nrf54h20_timer1_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_2) + case 2: + irq_num = TIMER130_IRQn; + hwtimer = NRF_TIMER130_S; + irq_isr = nrf54h20_timer2_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_3) + case 3: + irq_num = RTC131_IRQn; + hwtimer = NRF_RTC131_S; + irq_isr = nrf54h20_timer3_irq_handler; + bsptimer->tmr_rtc = 1; + break; +#endif +#if MYNEWT_VAL(TIMER_4) + case 4: + irq_num = TIMER131_IRQn; + hwtimer = NRF_TIMER131_S; + irq_isr = nrf54h20_timer4_irq_handler; +// bsptimer->tmr_rtc = 1; + break; +#endif + default: + hwtimer = NULL; + break; + } + + if (hwtimer == NULL) { + rc = EINVAL; + goto err; + } + + bsptimer->tmr_reg = hwtimer; + bsptimer->tmr_irq_num = irq_num; + + /* Disable IRQ, set priority and set vector in table */ + NVIC_DisableIRQ(irq_num); + NVIC_SetPriority(irq_num, (1 << __NVIC_PRIO_BITS) - 1); + NVIC_SetVector(irq_num, (uint32_t)irq_isr); + + return 0; + +err: + return rc; +} + +/** + * Configure a timer to run at the desired frequency. This starts the timer. + * + * @param timer_num + * @param freq_hz + * + * @return int + */ +int +hal_timer_config(int timer_num, uint32_t freq_hz) +{ + int rc; + uint8_t prescaler; + uint32_t ctx; + uint32_t div; + uint32_t min_delta; + uint32_t max_delta; + struct nrf54h20_hal_timer *bsptimer; + NRF_TIMER_Type *hwtimer; +#if MYNEWT_VAL(TIMER_3) + NRF_RTC_Type *rtctimer; +#endif + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + +#if MYNEWT_VAL(TIMER_3) + if (timer_num == 3) { + /* NOTE: we only allow the RTC frequency to be set at 32768 */ + if (bsptimer->tmr_enabled || (freq_hz != 32768) || + (bsptimer->tmr_reg == NULL)) { + rc = EINVAL; + goto err; + } + + bsptimer->tmr_freq = freq_hz; + bsptimer->tmr_enabled = 1; + + __HAL_DISABLE_INTERRUPTS(ctx); + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + + /* Stop the timer first */ + rtctimer->TASKS_STOP = 1; + rtctimer->TASKS_CLEAR = 1; + + /* Always no prescaler */ + rtctimer->PRESCALER = 0; + + /* Clear overflow events and set overflow interrupt */ + rtctimer->EVENTS_OVRFLW = 0; + rtctimer->INTENSET = RTC_INTENSET_OVRFLW_Msk; + + /* Start the timer */ + rtctimer->TASKS_START = 1; + + /* Set isr in vector table and enable interrupt */ + NVIC_EnableIRQ(bsptimer->tmr_irq_num); + + __HAL_ENABLE_INTERRUPTS(ctx); + return 0; + } +#endif + + /* Set timer to desired frequency */ + div = NRF54H20_MAX_TIMER_FREQ / freq_hz; + + /* + * Largest prescaler is 2^9 and must make sure frequency not too high. + * If hwtimer is NULL it means that the timer was not initialized prior + * to call. + */ + if (bsptimer->tmr_enabled || (div == 0) || (div > 512) || + (bsptimer->tmr_reg == NULL)) { + rc = EINVAL; + goto err; + } + + if (div == 1) { + prescaler = 0; + } else { + /* Find closest prescaler */ + for (prescaler = 1; prescaler < 10; ++prescaler) { + if (div <= (1 << prescaler)) { + min_delta = div - (1 << (prescaler - 1)); + max_delta = (1 << prescaler) - div; + if (min_delta < max_delta) { + prescaler -= 1; + } + break; + } + } + } + + /* Now set the actual frequency */ + bsptimer->tmr_freq = NRF54H20_MAX_TIMER_FREQ / (1 << prescaler); + bsptimer->tmr_enabled = 1; + + /* disable interrupts */ + __HAL_DISABLE_INTERRUPTS(ctx); + + /* Make sure HFXO is started */ +// if ((NRF_CLOCK_S->HFCLKSTAT & +// (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) != +// (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) { +// NRF_CLOCK_S->EVENTS_HFCLKSTARTED = 0; +// NRF_CLOCK_S->TASKS_HFCLKSTART = 1; +// while (1) { +// if ((NRF_CLOCK_S->EVENTS_HFCLKSTARTED) != 0) { +// break; +// } +// } +// } + hwtimer = bsptimer->tmr_reg; + + /* Stop the timer first */ + hwtimer->TASKS_STOP = 1; + hwtimer->TASKS_CLEAR = 1; + + /* Put the timer in timer mode using 32 bits. */ + hwtimer->MODE = TIMER_MODE_MODE_Timer; + hwtimer->BITMODE = TIMER_BITMODE_BITMODE_32Bit; + + /* Set the pre-scalar */ + hwtimer->PRESCALER = prescaler; + + /* Start the timer */ + hwtimer->TASKS_START = 1; + + NVIC_EnableIRQ(bsptimer->tmr_irq_num); + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; + +err: + return rc; +} + +/** + * De-initialize a HW timer. + * + * @param timer_num + * + * @return int + */ +int +hal_timer_deinit(int timer_num) +{ + int rc; + uint32_t ctx; + struct nrf54h20_hal_timer *bsptimer; + NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; + + rc = 0; + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + + __HAL_DISABLE_INTERRUPTS(ctx); + if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + rtctimer->TASKS_STOP = 1; + } else { + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + hwtimer->TASKS_SHUTDOWN = 1; + } + bsptimer->tmr_enabled = 0; + bsptimer->tmr_reg = NULL; + __HAL_ENABLE_INTERRUPTS(ctx); + +err: + return rc; +} + +/** + * Get the resolution of the timer. This is the timer period, in nanoseconds + * + * @param timer_num + * + * @return uint32_t The + */ +uint32_t +hal_timer_get_resolution(int timer_num) +{ + int rc; + uint32_t resolution; + struct nrf54h20_hal_timer *bsptimer; + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + + resolution = 1000000000 / bsptimer->tmr_freq; + return resolution; + +err: + rc = 0; + return rc; +} + +/** + * Returns the timer counter. NOTE: if the timer is a 16-bit timer, only + * the lower 16 bits are valid. If the timer is a 64-bit timer, only the + * low 32-bits are returned. + * + * @return uint32_t The timer counter register. + */ +uint32_t +hal_timer_read(int timer_num) +{ + int rc; + uint32_t tcntr; + struct nrf54h20_hal_timer *bsptimer; + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + if (bsptimer->tmr_rtc) { + tcntr = hal_timer_read_bsptimer(bsptimer); + } else { + tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + } + + return tcntr; + + /* Assert here since there is no invalid return code */ +err: + assert(0); + rc = 0; + return rc; +} + +/** + * Blocking delay for n ticks + * + * @param timer_num + * @param ticks + * + * @return int 0 on success; error code otherwise. + */ +int +hal_timer_delay(int timer_num, uint32_t ticks) +{ + uint32_t until; + + until = hal_timer_read(timer_num) + ticks; + while ((int32_t)(hal_timer_read(timer_num) - until) <= 0) { + /* Loop here till finished */ + } + + return 0; +} + +/** + * Initialize the HAL timer structure with the callback and the callback + * argument. Also initializes the HW specific timer pointer. + * + * @param cb_func + * + * @return int + */ +int +hal_timer_set_cb(int timer_num, struct hal_timer *timer, hal_timer_cb cb_func, + void *arg) +{ + int rc; + struct nrf54h20_hal_timer *bsptimer; + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + + timer->cb_func = cb_func; + timer->cb_arg = arg; + timer->link.tqe_prev = NULL; + timer->bsp_timer = bsptimer; + + rc = 0; + +err: + return rc; +} + +int +hal_timer_start(struct hal_timer *timer, uint32_t ticks) +{ + int rc; + uint32_t tick; + struct nrf54h20_hal_timer *bsptimer; + + /* Set the tick value at which the timer should expire */ + bsptimer = (struct nrf54h20_hal_timer *)timer->bsp_timer; + if (bsptimer->tmr_rtc) { + tick = hal_timer_read_bsptimer(bsptimer) + ticks; + } else { + tick = nrf_read_timer_cntr(bsptimer->tmr_reg) + ticks; + } + rc = hal_timer_start_at(timer, tick); + return rc; +} + +int +hal_timer_start_at(struct hal_timer *timer, uint32_t tick) +{ + uint32_t ctx; + struct hal_timer *entry; + struct nrf54h20_hal_timer *bsptimer; + + if ((timer == NULL) || (timer->link.tqe_prev != NULL) || + (timer->cb_func == NULL)) { + return EINVAL; + } + bsptimer = (struct nrf54h20_hal_timer *)timer->bsp_timer; + timer->expiry = tick; + + __HAL_DISABLE_INTERRUPTS(ctx); + + if (TAILQ_EMPTY(&bsptimer->hal_timer_q)) { + TAILQ_INSERT_HEAD(&bsptimer->hal_timer_q, timer, link); + } else { + TAILQ_FOREACH(entry, &bsptimer->hal_timer_q, link) { + if ((int32_t)(timer->expiry - entry->expiry) < 0) { + TAILQ_INSERT_BEFORE(entry, timer, link); + break; + } + } + if (!entry) { + TAILQ_INSERT_TAIL(&bsptimer->hal_timer_q, timer, link); + } + } + + /* If this is the head, we need to set new OCMP */ + if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) { + nrf_timer_set_ocmp(bsptimer, timer->expiry); + } + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} + +/** + * Stop a timer. + * + * @param timer + * + * @return int + */ +int +hal_timer_stop(struct hal_timer *timer) +{ + uint32_t ctx; + int reset_ocmp; + struct hal_timer *entry = NULL; + struct nrf54h20_hal_timer *bsptimer; + + if (timer == NULL) { + return EINVAL; + } + + bsptimer = (struct nrf54h20_hal_timer *)timer->bsp_timer; + + __HAL_DISABLE_INTERRUPTS(ctx); + + if (timer->link.tqe_prev != NULL) { + reset_ocmp = 0; + if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) { + /* If first on queue, we will need to reset OCMP */ + entry = TAILQ_NEXT(timer, link); + reset_ocmp = 1; + } + TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link); + timer->link.tqe_prev = NULL; + if (reset_ocmp) { + if (entry) { + nrf_timer_set_ocmp((struct nrf54h20_hal_timer *)entry->bsp_timer, + entry->expiry); + } else { + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } + } + } + } + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} diff --git a/hw/mcu/nordic/nrf54h20/src/hal_uart.c b/hw/mcu/nordic/nrf54h20/src/hal_uart.c new file mode 100644 index 0000000000..679f73ca7a --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_uart.c @@ -0,0 +1,349 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +// #if MYNEWT_VAL(UART_0) +// #endif + +// #define UARTE_INT_ENDTX UARTE_INTEN_ENDTX_Msk +// #define UARTE_INT_ENDRX UARTE_INTEN_ENDRX_Msk +// #define UARTE_CONFIG_PARITY UARTE_CONFIG_PARITY_Msk +// #define UARTE_CONFIG_PARITY_ODD UARTE_CONFIG_PARITYTYPE_Msk +// #define UARTE_CONFIG_HWFC UARTE_CONFIG_HWFC_Msk +// #define UARTE_ENABLE UARTE_ENABLE_ENABLE_Enabled +// #define UARTE_DISABLE UARTE_ENABLE_ENABLE_Disabled + +// struct hal_uart { +// uint8_t u_open : 1; +// uint8_t u_rx_stall : 1; +// volatile uint8_t u_tx_started : 1; + +// uint8_t u_rx_buf; +// uint8_t u_tx_buf[8]; + +// hal_uart_rx_char u_rx_func; +// hal_uart_tx_char u_tx_func; +// hal_uart_tx_done u_tx_done; +// void *u_func_arg; +// }; + +// static struct hal_uart uart0; + +// int +// hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done, +// hal_uart_rx_char rx_func, void *arg) +// { +// if (port != 0 || uart0.u_open) { +// return -1; +// } + +// uart0.u_rx_func = rx_func; +// uart0.u_tx_func = tx_func; +// uart0.u_tx_done = tx_done; +// uart0.u_func_arg = arg; + +// return 0; +// } + +// static int +// hal_uart_tx_fill_buf(struct hal_uart *u) +// { +// int data; +// int i; + +// for (i = 0; i < sizeof(u->u_tx_buf); i++) { +// data = u->u_tx_func(u->u_func_arg); +// if (data < 0) { +// break; +// } +// u->u_tx_buf[i] = data; +// } +// return i; +// } + +// void +// hal_uart_start_tx(int port) +// { +// int sr; +// int rc; + +// if (port != 0) { +// return; +// } + +// __HAL_DISABLE_INTERRUPTS(sr); +// if (uart0.u_tx_started == 0) { +// rc = hal_uart_tx_fill_buf(&uart0); +// if (rc > 0) { +// NRF_UARTE0_NS->INTENSET = UARTE_INT_ENDTX; +// NRF_UARTE0_NS->TXD.PTR = (uint32_t)&uart0.u_tx_buf; +// NRF_UARTE0_NS->TXD.MAXCNT = rc; +// NRF_UARTE0_NS->TASKS_STARTTX = 1; +// uart0.u_tx_started = 1; +// } +// } +// __HAL_ENABLE_INTERRUPTS(sr); +// } + +// void +// hal_uart_start_rx(int port) +// { +// int sr; +// int rc; + +// if (port != 0) { +// return; +// } + +// if (uart0.u_rx_stall) { +// __HAL_DISABLE_INTERRUPTS(sr); +// rc = uart0.u_rx_func(uart0.u_func_arg, uart0.u_rx_buf); +// if (rc == 0) { +// uart0.u_rx_stall = 0; +// NRF_UARTE0_NS->TASKS_STARTRX = 1; +// } + +// __HAL_ENABLE_INTERRUPTS(sr); +// } +// } + +// void +// hal_uart_blocking_tx(int port, uint8_t data) +// { +// if (port != 0 || !uart0.u_open) { +// return; +// } + +// /* If we have started, wait until the current uart dma buffer is done */ +// if (uart0.u_tx_started) { +// while (NRF_UARTE0_NS->EVENTS_ENDTX == 0) { +// /* Wait here until the dma is finished */ +// } +// } + +// NRF_UARTE0_NS->EVENTS_ENDTX = 0; +// NRF_UARTE0_NS->TXD.PTR = (uint32_t)&data; +// NRF_UARTE0_NS->TXD.MAXCNT = 1; +// NRF_UARTE0_NS->TASKS_STARTTX = 1; + +// while (NRF_UARTE0_NS->EVENTS_ENDTX == 0) { +// /* Wait till done */ +// } + +// /* Stop the uart */ +// NRF_UARTE0_NS->TASKS_STOPTX = 1; +// } + +// static void +// uart0_irq_handler(void) +// { +// int rc; + +// os_trace_isr_enter(); + +// if (NRF_UARTE0_NS->EVENTS_ENDTX) { +// NRF_UARTE0_NS->EVENTS_ENDTX = 0; +// rc = hal_uart_tx_fill_buf(&uart0); +// if (rc > 0) { +// NRF_UARTE0_NS->TXD.PTR = (uint32_t)uart0.u_tx_buf; +// NRF_UARTE0_NS->TXD.MAXCNT = rc; +// NRF_UARTE0_NS->TASKS_STARTTX = 1; +// } else { +// if (uart0.u_tx_done) { +// uart0.u_tx_done(uart0.u_func_arg); +// } +// NRF_UARTE0_NS->INTENCLR = UARTE_INT_ENDTX; +// NRF_UARTE0_NS->TASKS_STOPTX = 1; +// uart0.u_tx_started = 0; +// } +// } +// if (NRF_UARTE0_NS->EVENTS_ENDRX) { +// NRF_UARTE0_NS->EVENTS_ENDRX = 0; +// rc = uart0.u_rx_func(uart0.u_func_arg, uart0.u_rx_buf); +// if (rc < 0) { +// uart0.u_rx_stall = 1; +// } else { +// NRF_UARTE0_NS->TASKS_STARTRX = 1; +// } +// } +// os_trace_isr_exit(); +// } + +// static uint32_t +// hal_uart_baudrate(int baudrate) +// { +// switch (baudrate) { +// case 1200: +// return UARTE_BAUDRATE_BAUDRATE_Baud1200; +// case 2400: +// return UARTE_BAUDRATE_BAUDRATE_Baud2400; +// case 4800: +// return UARTE_BAUDRATE_BAUDRATE_Baud4800; +// case 9600: +// return UARTE_BAUDRATE_BAUDRATE_Baud9600; +// case 14400: +// return UARTE_BAUDRATE_BAUDRATE_Baud14400; +// case 19200: +// return UARTE_BAUDRATE_BAUDRATE_Baud19200; +// case 28800: +// return UARTE_BAUDRATE_BAUDRATE_Baud28800; +// case 38400: +// return UARTE_BAUDRATE_BAUDRATE_Baud38400; +// case 56000: +// return UARTE_BAUDRATE_BAUDRATE_Baud56000; +// case 57600: +// return UARTE_BAUDRATE_BAUDRATE_Baud57600; +// case 76800: +// return UARTE_BAUDRATE_BAUDRATE_Baud76800; +// case 115200: +// return UARTE_BAUDRATE_BAUDRATE_Baud115200; +// case 230400: +// return UARTE_BAUDRATE_BAUDRATE_Baud230400; +// case 250000: +// return UARTE_BAUDRATE_BAUDRATE_Baud250000; +// case 460800: +// return UARTE_BAUDRATE_BAUDRATE_Baud460800; +// case 921600: +// return UARTE_BAUDRATE_BAUDRATE_Baud921600; +// case 1000000: +// return UARTE_BAUDRATE_BAUDRATE_Baud1M; +// default: +// return 0; +// } +// } + +// int +// hal_uart_init(int port, void *arg) +// { +// struct nrf54h20_uart_cfg *cfg = arg; + +// if (port != 0) { +// return -1; +// } + +// NRF_UARTE0_NS->PSEL.TXD = cfg->suc_pin_tx; +// NRF_UARTE0_NS->PSEL.RXD = cfg->suc_pin_rx; +// NRF_UARTE0_NS->PSEL.RTS = cfg->suc_pin_rts; +// NRF_UARTE0_NS->PSEL.CTS = cfg->suc_pin_cts; + +// NVIC_SetVector(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (uint32_t)uart0_irq_handler); + +// return 0; +// } + +// int +// hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits, +// enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) +// { +// uint32_t cfg_reg = 0; +// uint32_t baud_reg; + +// if (port != 0 || uart0.u_open) { +// return -1; +// } + +// /* +// * pin config +// * UART config +// * nvic config +// * enable uart +// */ +// if (databits != 8) { +// return -1; +// } +// if (stopbits != 1) { +// return -1; +// } + +// switch (parity) { +// case HAL_UART_PARITY_NONE: +// break; +// case HAL_UART_PARITY_ODD: +// cfg_reg |= UARTE_CONFIG_PARITY | UARTE_CONFIG_PARITY_ODD; +// break; +// case HAL_UART_PARITY_EVEN: +// cfg_reg |= UARTE_CONFIG_PARITY; +// break; +// } + +// switch (flow_ctl) { +// case HAL_UART_FLOW_CTL_NONE: +// break; +// case HAL_UART_FLOW_CTL_RTS_CTS: +// cfg_reg |= UARTE_CONFIG_HWFC; +// if (NRF_UARTE0_NS->PSEL.RTS == 0xffffffff || +// NRF_UARTE0_NS->PSEL.CTS == 0xffffffff) { +// /* +// * Can't turn on HW flow control if pins to do that are not +// * defined. +// */ +// assert(0); +// return -1; +// } +// break; +// } +// baud_reg = hal_uart_baudrate(baudrate); +// if (baud_reg == 0) { +// return -1; +// } +// NRF_UARTE0_NS->ENABLE = 0; +// NRF_UARTE0_NS->INTENCLR = 0xffffffff; +// NRF_UARTE0_NS->BAUDRATE = baud_reg; +// NRF_UARTE0_NS->CONFIG = cfg_reg; + +// NVIC_EnableIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); + +// NRF_UARTE0_NS->ENABLE = UARTE_ENABLE; + +// NRF_UARTE0_NS->INTENSET = UARTE_INT_ENDRX; +// NRF_UARTE0_NS->RXD.PTR = (uint32_t)&uart0.u_rx_buf; +// NRF_UARTE0_NS->RXD.MAXCNT = sizeof(uart0.u_rx_buf); +// NRF_UARTE0_NS->TASKS_STARTRX = 1; + +// uart0.u_rx_stall = 0; +// uart0.u_tx_started = 0; +// uart0.u_open = 1; + +// return 0; +// } + +// int +// hal_uart_close(int port) +// { +// if (port != 0) { +// return -1; +// } + +// uart0.u_open = 0; +// while (uart0.u_tx_started) { +// /* Wait here until the dma is finished */ +// } +// NRF_UARTE0_NS->ENABLE = 0; +// NRF_UARTE0_NS->INTENCLR = 0xffffffff; + +// return 0; +// } diff --git a/hw/mcu/nordic/nrf54h20/src/hal_vflash.c b/hw/mcu/nordic/nrf54h20/src/hal_vflash.c new file mode 100644 index 0000000000..b218983e7a --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_vflash.c @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +// #if MCUBOOT_MYNEWT +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #if !MYNEWT_VAL(IPC_ICBMSG) +// #include +// #endif + +// #define NRF5340_NET_VFLASH_SECTOR_SZ 2048 + +// struct swap_data { +// uint32_t encryption_key0[4]; +// uint32_t encryption_key1[4]; +// uint32_t swap_size; +// struct image_trailer trailer; +// }; + +// static const struct swap_data swap_data_template = { +// .encryption_key0 = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, +// .encryption_key1 = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, +// .swap_size = 0xffffffff, +// .trailer = { +// .swap_type = BOOT_SWAP_TYPE_PERM, +// .pad1 = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, +// .copy_done = 0xff, +// .pad2 = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, +// .image_ok = 0x01, +// .pad3 = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, +// .magic = { 0x77, 0xc2, 0x95, 0xf3, 0x60, 0xd2, 0xef, 0x7f, +// 0x35, 0x52, 0x50, 0x0f, 0x2c, 0xb6, 0x79, 0x80 }, +// } +// }; + +// int +// nrf54h20_get_image_hash(uint8_t area_id, uint8_t hash[32]) +// { +// const struct flash_area *fa = NULL; +// struct image_header header; +// uint32_t addr; +// uint32_t limit; +// struct image_tlv_info info; +// struct image_tlv tlv; +// int rc = -1; + +// if (flash_area_open(area_id, &fa) != 0) { +// goto end; +// } + +// /* Does slot contain valid image */ +// if (flash_area_read(fa, 0, &header, sizeof(header)) != 0 || +// header.ih_magic != IMAGE_MAGIC) { +// goto end; +// } + +// addr = header.ih_hdr_size + header.ih_img_size; +// /* Does image has TLV? (needed for image hash verification) */ +// if (flash_area_read(fa, addr, &info, sizeof(info)) != 0 || +// info.it_magic != IMAGE_TLV_INFO_MAGIC) { +// goto end; +// } + +// addr += sizeof(info); +// limit = addr + info.it_tlv_tot; +// while (addr + sizeof(tlv) + 32 <= limit) { +// if (flash_area_read(fa, addr, &tlv, sizeof(tlv)) != 0) { +// goto end; +// } +// addr += sizeof(tlv); +// if (tlv.it_type == IMAGE_TLV_SHA256) { +// if (tlv.it_len != 32) { +// goto end; +// } +// rc = flash_area_read(fa, addr, hash, 32); +// break; +// } +// addr += tlv.it_len; +// } +// end: +// if (fa) { +// flash_area_close(fa); +// } +// return rc; +// } + +// bool +// nrf54h20_images_match(void) +// { +// uint8_t active_slot_hash[32]; +// uint8_t pending_slot_hash[32]; + +// if (nrf54h20_get_image_hash(FLASH_AREA_IMAGE_0, active_slot_hash) == 0 && +// nrf54h20_get_image_hash(FLASH_AREA_IMAGE_1, pending_slot_hash) == 0 && +// memcmp(pending_slot_hash, active_slot_hash, 32) == 0) { +// /* Same hash for current and pending slot, act as slot 2 was empty */ +// return true; +// } +// return false; +// } + +// static int +// nrf54h20_vflash_read(const struct hal_flash *dev, uint32_t address, void *dst, +// uint32_t num_bytes) +// { +// struct nrf54h20_vflash *vflash = (struct nrf54h20_vflash *)dev; +// uint32_t write_bytes = num_bytes; +// uint8_t *wp = dst; +// const struct flash_area *fa; +// struct swap_data swap_data; + +// if ((vflash->nv_image_size > 0) && (vflash->nv_slot1 == NULL)) { +// flash_area_open(FLASH_AREA_IMAGE_1, &vflash->nv_slot1); + +// /* +// * If application side provided image check if same image was already +// * provided before and if so mark virtual slot as empty +// */ +// if (nrf54h20_images_match()) { +// /* Same hash for current and pending slot, act as slot 2 was empty */ +// vflash->nv_image_size = 0; +// } +// } +// fa = vflash->nv_slot1; + +// /* Copy data from image */ +// if (address < vflash->nv_image_size) { +// if (address + write_bytes > vflash->nv_image_size) { +// write_bytes = vflash->nv_image_size - address; +// } +// memcpy(wp, vflash->nv_image_address + address, write_bytes); +// address += write_bytes; +// wp += write_bytes; +// num_bytes -= write_bytes; +// } +// /* Copy data from image trailer */ +// if (num_bytes > 0 && fa != NULL && address >= (fa->fa_off + fa->fa_size - sizeof(swap_data))) { +// swap_data = swap_data_template; +// uint32_t off = address - (fa->fa_off + fa->fa_size - sizeof(swap_data)); +// write_bytes = num_bytes; +// if (num_bytes > sizeof(swap_data) + off) { +// write_bytes = sizeof(swap_data) - off; +// } +// memcpy(wp, ((uint8_t *)&swap_data) + off, write_bytes); +// wp += write_bytes; +// address += write_bytes; +// num_bytes -= write_bytes; +// } +// /* Fill the rest with FF */ +// if (num_bytes > 0) { +// memset(wp, 0xff, num_bytes); +// } +// return 0; +// } + +// /* +// * Flash write is done by writing 4 bytes at a time at a word boundary. +// */ +// static int +// nrf54h20_vflash_write(const struct hal_flash *dev, uint32_t address, +// const void *src, uint32_t num_bytes) +// { +// (void)dev; +// (void)address; +// (void)src; +// (void)num_bytes; + +// return 0; +// } + +// static int +// nrf54h20_vflash_erase_sector(const struct hal_flash *dev, uint32_t sector_address) +// { +// (void)dev; +// (void)sector_address; + +// return 0; +// } + +// static int +// nrf54h20_vflash_sector_info(const struct hal_flash *dev, int idx, +// uint32_t *address, uint32_t *sz) +// { +// (void)dev; + +// assert(idx < nrf54h20_flash_dev.hf_sector_cnt); +// *address = idx * NRF5340_NET_VFLASH_SECTOR_SZ; +// *sz = NRF5340_NET_VFLASH_SECTOR_SZ; + +// return 0; +// } + +// static int +// nrf54h20_vflash_init(const struct hal_flash *dev) +// { +// struct nrf54h20_vflash *vflash = (struct nrf54h20_vflash *)dev; +// const void *img_addr; +// uint32_t image_size; + +// #if MYNEWT_VAL(IPC_ICBMSG) +// img_addr = 0; +// image_size = 0; +// #else +// img_addr = ipc_nrf54h20_image_get(&image_size); +// #endif + +// /* +// * Application side IPC will set ipc_share data +// * (or GPMEM registers) to address and size of +// * memory where net core image is present in application flash. +// * If those values are 0, application image does not have embedded image, +// * and there no need to provide any data. +// * Set nv_image_size to 0 and all reads will return empty values (0xff) +// */ +// if (img_addr) { +// vflash->nv_image_address = img_addr; +// vflash->nv_image_size = image_size; +// } + +// return 0; +// } + +// static const struct hal_flash_funcs nrf54h20_vflash_funcs = { +// .hff_read = nrf54h20_vflash_read, +// .hff_write = nrf54h20_vflash_write, +// .hff_erase_sector = nrf54h20_vflash_erase_sector, +// .hff_sector_info = nrf54h20_vflash_sector_info, +// .hff_init = nrf54h20_vflash_init +// }; + +// struct nrf54h20_vflash nrf54h20_vflash_dev = { +// .nv_flash = { +// .hf_itf = &nrf54h20_vflash_funcs, +// .hf_base_addr = 0x00000000, +// .hf_size = 256 * 1024, +// .hf_sector_cnt = 128, +// .hf_align = 1, +// .hf_erased_val = 0xff, +// } +// }; + +// #endif diff --git a/hw/mcu/nordic/nrf54h20/src/hal_watchdog.c b/hw/mcu/nordic/nrf54h20/src/hal_watchdog.c new file mode 100644 index 0000000000..83ced3a298 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/hal_watchdog.c @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include + +#if defined(NRF_RADIOCORE) +#define NRF_WDT NRF_RADIOCORE_WDT010_S +#define WDT_IRQn WDT010_IRQn +#else /* NRF_APPLICATION */ +#define NRF_WDT NRF_APPLICATION_WDT010_S +#define WDT_IRQn WDT010_IRQn +#endif + +static void +nrf54h20_hal_wdt_default_handler(void) +{ + assert(0); +} + +/**@brief WDT interrupt handler. */ +static void +nrf54h20_wdt_irq_handler(void) +{ + os_trace_isr_enter(); + if (NRF_WDT->INTENSET & WDT_INTENSET_TIMEOUT_Msk) { + NRF_WDT->EVENTS_TIMEOUT = 0; + nrf54h20_hal_wdt_default_handler(); + } + os_trace_isr_exit(); +} + +int +hal_watchdog_init(uint32_t expire_msecs) +{ + uint64_t expiration; + + NRF_WDT->CONFIG = WDT_CONFIG_SLEEP_Msk; + + /* Convert msec timeout to counts of a 32768 crystal */ + expiration = ((uint64_t)expire_msecs * 32768) / 1000; + NRF_WDT->CRV = (uint32_t)expiration; + + NRF_WDT->CRV = (expire_msecs * 32) + ((expire_msecs * 96) / 125); + + NVIC_SetVector(WDT_IRQn, (uint32_t)nrf54h20_wdt_irq_handler); + NVIC_SetPriority(WDT_IRQn, 0); + NVIC_ClearPendingIRQ(WDT_IRQn); + NVIC_EnableIRQ(WDT_IRQn); + NRF_WDT->RREN |= 0x1; + + return 0; +} + +void +hal_watchdog_enable(void) +{ +// NRF_WDT->INTENSET = WDT_INTENSET_TIMEOUT_Msk; +// NRF_WDT->TASKS_START = 1; +} + +void +hal_watchdog_tickle(void) +{ + NRF_WDT->RR[0] = WDT_RR_RR_Reload; +} + diff --git a/hw/mcu/nordic/nrf54h20/src/nrf54h20_clock.c b/hw/mcu/nordic/nrf54h20/src/nrf54h20_clock.c new file mode 100644 index 0000000000..a97194403c --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/nrf54h20_clock.c @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include +#include +#include "mcu/nrf54h20_hal.h" +#include +#include + +static uint8_t nrf54h20_clock_hfxo_refcnt; + +/** + * Request HFXO clock be turned on. Note that each request must have a + * corresponding release. + * + * @return int 0: hfxo was already on. 1: hfxo was turned on. + */ +int +nrf54h20_clock_hfxo_request(void) +{ + int started; + uint32_t ctx; + + // started = 0; + // __HAL_DISABLE_INTERRUPTS(ctx); + // assert(nrf54h20_clock_hfxo_refcnt < 0xff); + // if (nrf54h20_clock_hfxo_refcnt == 0) { + // NRF_CLOCK_NS->TASKS_HFCLKSTART = 1; + // started = 1; + // } + // ++nrf54h20_clock_hfxo_refcnt; + // __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} + +/** + * Release the HFXO. This means that the caller no longer needs the HFXO to be + * turned on. Each call to release should have been preceeded by a corresponding + * call to request the HFXO + * + * + * @return int 0: HFXO not stopped by this call (others using it) 1: HFXO + * stopped. + */ +int +nrf54h20_clock_hfxo_release(void) +{ + int stopped; + uint32_t ctx; + + // stopped = 0; + // __HAL_DISABLE_INTERRUPTS(ctx); + // assert(nrf54h20_clock_hfxo_refcnt != 0); + // --nrf54h20_clock_hfxo_refcnt; + // if (nrf54h20_clock_hfxo_refcnt == 0) { + // NRF_CLOCK_NS->TASKS_HFCLKSTOP = 1; + // stopped = 1; + // } + // __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} + +static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context) { +} + +static uint32_t int_mask; +static nrfx_grtc_channel_t system_clock_channel_data = { + .handler = sys_clock_timeout_handler, + .p_context = NULL, + .channel = (uint8_t)-1, +}; + +int +nrf54h20_clock_grtc_init(void) +{ + nrfx_err_t err_code; + + err_code = nrfx_grtc_init(0); + if (err_code != NRFX_SUCCESS) { + return -1; + } + +//#if defined(CONFIG_NRF_GRTC_START_SYSCOUNTER) +// err_code = nrfx_grtc_syscounter_start(true, &system_clock_channel_data.channel); +// if (err_code != NRFX_SUCCESS) { +// return err_code == NRFX_ERROR_NO_MEM ? -ENOMEM : -EPERM; +// } +//#else + err_code = nrfx_grtc_channel_alloc(&system_clock_channel_data.channel); + if (err_code != NRFX_SUCCESS) { + return -1; + } +//#endif /* CONFIG_NRF_GRTC_START_SYSCOUNTER */ + + int_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK; + + return 0; +} diff --git a/hw/mcu/nordic/nrf54h20/src/nrf54h20_hw_id.c b/hw/mcu/nordic/nrf54h20/src/nrf54h20_hw_id.c new file mode 100644 index 0000000000..1ff8a3a4b6 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/nrf54h20_hw_id.c @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include + +// int +// hal_bsp_hw_id_len(void) +// { +// return sizeof(NRF_FICR_NS->INFO.DEVICEID); +// } + +// /* +// * These values are generated at random. +// * DEVICEID +// */ +// int +// hal_bsp_hw_id(uint8_t *id, int max_len) +// { +// max_len = min(sizeof(NRF_FICR_NS->INFO.DEVICEID), max_len); + +// memcpy(id, (void *)&NRF_FICR_NS->INFO.DEVICEID, max_len); + +// return max_len; +// } diff --git a/hw/mcu/nordic/nrf54h20/src/nrf54h20_periph.c b/hw/mcu/nordic/nrf54h20/src/nrf54h20_periph.c new file mode 100644 index 0000000000..9a261d97bb --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/nrf54h20_periph.c @@ -0,0 +1,213 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "hal/hal_spi.h" + +#if MYNEWT_VAL(UART_0) +#include +#include +#endif + +#if MYNEWT_VAL(SPI_0_MASTER) +#include "bus/drivers/spi_hal.h" +#endif + +#if MYNEWT_VAL(I2C_0) +#include +#include +#endif + +#if MYNEWT_VAL(TRNG) +#include "trng/trng.h" +#include "trng_sw/trng_sw.h" +#endif + +#if MYNEWT_VAL(UART_0) +static struct uart_dev os_bsp_uart0; +static const struct nrf54h20_uart_cfg os_bsp_uart0_cfg = { + .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX), + .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX), + .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS), + .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS), +}; +#endif + +#if MYNEWT_VAL(SPI_0_MASTER) +static const struct bus_spi_dev_cfg spi0_cfg = { + .spi_num = 0, + .pin_sck = MYNEWT_VAL(SPI_0_MASTER_PIN_SCK), + .pin_mosi = MYNEWT_VAL(SPI_0_MASTER_PIN_MOSI), + .pin_miso = MYNEWT_VAL(SPI_0_MASTER_PIN_MISO), +}; +static struct bus_spi_hal_dev spi0_bus; +#endif +#if MYNEWT_VAL(SPI_0_SLAVE) +static const struct nrf54h20_hal_spi_cfg os_bsp_spi0s_cfg = { + .sck_pin = MYNEWT_VAL(SPI_0_SLAVE_PIN_SCK), + .mosi_pin = MYNEWT_VAL(SPI_0_SLAVE_PIN_MOSI), + .miso_pin = MYNEWT_VAL(SPI_0_SLAVE_PIN_MISO), + .ss_pin = MYNEWT_VAL(SPI_0_SLAVE_PIN_SS), +}; +#endif + +#if MYNEWT_VAL(I2C_0) +static const struct bus_i2c_dev_cfg i2c0_cfg = { + .i2c_num = 0, + .pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA), + .pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL), +}; +static struct bus_i2c_dev i2c0_bus; +#endif + +#if MYNEWT_VAL(TRNG) +//static struct trng_dev os_bsp_trng; +static struct trng_sw_dev os_bsp_trng; +static int32_t mypid; +static struct trng_sw_dev_cfg os_bsp_trng_cfg = { + .tsdc_entr = &mypid, + .tsdc_len = sizeof(mypid) +}; +#endif + +static void +nrf54h20_periph_create_timers(void) +{ + int rc; + + (void)rc; + +#if MYNEWT_VAL(TIMER_0) + rc = hal_timer_init(0, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_1) + rc = hal_timer_init(1, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_2) + rc = hal_timer_init(2, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_3) + rc = hal_timer_init(3, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_4) + rc = hal_timer_init(4, NULL); + assert(rc == 0); +#endif + +#if MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0 + rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ)); + assert(rc == 0); +#endif +} + +static void +nrf54h20_periph_create_uart(void) +{ +#if MYNEWT_VAL(UART_0) + int rc; + + rc = os_dev_create(&os_bsp_uart0.ud_dev, "uart0", + OS_DEV_INIT_PRIMARY, 0, uart_hal_init, + (void *)&os_bsp_uart0_cfg); + assert(rc == 0); +#endif +} + +static void +nrf54h20_periph_create_spi(void) +{ + int rc; + + (void)rc; + +#if MYNEWT_VAL(SPI_0_MASTER) + rc = bus_spi_hal_dev_create("spi0", + &spi0_bus, (struct bus_spi_dev_cfg *)&spi0_cfg); + assert(rc == 0); +#endif +#if MYNEWT_VAL(SPI_0_SLAVE) + rc = hal_spi_init(0, (void *)&os_bsp_spi0s_cfg, HAL_SPI_TYPE_SLAVE); + assert(rc == 0); +#endif +} + +static void +nrf54h20_periph_create_i2c(void) +{ +#if MYNEWT_VAL(I2C_0) + int rc; + + rc = bus_i2c_nrf54h20_dev_create("i2c0", &i2c0_bus, + (struct bus_i2c_dev_cfg *)&i2c0_cfg); + assert(rc == 0); +#endif +} + +#if MYNEWT_VAL(TRNG) +void +hal_bsp_init_trng(void) +{ + int i; + int rc; + + /* + * Add entropy (don't do it like this if you use this for real, use + * something proper). + */ + for (i = 0; i < 8; i++) { + rc = trng_sw_dev_add_entropy(&os_bsp_trng, &mypid, sizeof(mypid)); + assert(rc == 0); + } +} +#endif + +static void +nrf54h20_periph_create_trng(void) +{ + int rc; + + (void)rc; + +#if MYNEWT_VAL(TRNG) + mypid = 123; + rc = os_dev_create((struct os_dev *)&os_bsp_trng, "trng", + OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT, + trng_sw_dev_init, &os_bsp_trng_cfg); + assert(rc == 0); +#endif +} + +void +nrf54h20_periph_create(void) +{ + nrf54h20_periph_create_timers(); + // nrf54h20_periph_create_uart(); + // nrf54h20_periph_create_spi(); + // nrf54h20_periph_create_i2c(); + nrf54h20_periph_create_trng(); +} diff --git a/hw/mcu/nordic/nrf54h20/src/system_nrf54h20.c b/hw/mcu/nordic/nrf54h20/src/system_nrf54h20.c new file mode 100644 index 0000000000..6eb71bd30a --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/src/system_nrf54h20.c @@ -0,0 +1,122 @@ +/* + +Copyright (c) 2009-2024 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the License); you may +not use this file except in compliance with the License. +You may obtain a copy of the License at + + www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an AS IS BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +/* NOTE: Template files (including this one) are application specific and therefore expected to + be copied into the application project folder prior to its use! */ + +#include +#include +#include "nrf.h" +#include "system_nrf54h.h" +#include "system_config_sau.h" + +/*lint ++flb "Enter library region" */ + +#define __SYSTEM_CLOCK_MHZ (1000000UL) +#if defined(NRF_PPR) +#define __SYSTEM_CLOCK_DEFAULT (16ul * __SYSTEM_CLOCK_MHZ) +#elif defined(NRF_RADIOCORE) +#define __SYSTEM_CLOCK_DEFAULT (256ul * __SYSTEM_CLOCK_MHZ) +#else +#define __SYSTEM_CLOCK_DEFAULT (320ul * __SYSTEM_CLOCK_MHZ) +#endif + +#if defined ( __CC_ARM ) || defined ( __GNUC__ ) +uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_DEFAULT; +#elif defined ( __ICCARM__ ) +__root uint32_t SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; +#endif + +void SystemCoreClockUpdate(void) +{ +#if defined(NRF_PPR) + /* PPR clock is always 16MHz */ + SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; +#elif defined(NRF_FLPR) + /* FLPR does not have access to its HSFLL, assume default speed. */ + SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; +#else +#if !defined(NRF_SKIP_CORECLOCKDETECT) && !defined(NRF_TRUSTZONE_NONSECURE) + + /* CPU should have access to its local HSFLL, measure CPU frequency. */ + /* If HSFLL is in closed loop mode it's always measuring, and we can just pick the result.*/ + /* Otherwise, start a frequncy measurement.*/ + if ((NRF_HSFLL->CLOCKSTATUS & HSFLL_CLOCKSTATUS_MODE_Msk) != HSFLL_CLOCKSTATUS_MODE_ClosedLoop) + { + /* Start HSFLL frequency measurement */ + NRF_HSFLL->EVENTS_FREQMDONE = 0ul; + NRF_HSFLL->TASKS_FREQMEAS = 1ul; + for (volatile uint32_t i = 0ul; i < 200ul && NRF_HSFLL->EVENTS_FREQMDONE != 1ul; i++) + { + /* Wait until frequency measurement is done */ + } + + if (NRF_HSFLL->EVENTS_FREQMDONE != 1ul) + { + /* Clock measurement never completed, return default CPU clock speed */ + SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; + return; + } + } + + /* Frequency measurement result is a multiple of 16MHz */ + SystemCoreClock = NRF_HSFLL->FREQM.MEAS * 16ul * __SYSTEM_CLOCK_MHZ; +#else + SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; +#endif +#endif +} + +void SystemInit(void) +{ +#ifdef __CORTEX_M + #if !defined(NRF_TRUSTZONE_NONSECURE) && defined(__ARM_FEATURE_CMSE) + #if defined(__FPU_PRESENT) && __FPU_PRESENT + /* Allow Non-Secure code to run FPU instructions. + * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */ + SCB->NSACR |= (3UL << 10ul); + #endif + #ifndef NRF_SKIP_SAU_CONFIGURATION + configure_default_sau(); + #endif + #endif + + /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the + * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit + * operations are not used in your code. */ + #if (__FPU_USED == 1) + SCB->CPACR |= (3UL << 20ul) | (3UL << 22ul); + __DSB(); + __ISB(); + #endif +#endif + +#if defined(NFCT_PRESENT) + #if defined(NRF_CONFIG_NFCT_PINS_AS_GPIOS) + NRF_NFCT->PADCONFIG = NFCT_PADCONFIG_ENABLE_Disabled << NFCT_PADCONFIG_ENABLE_Pos; + #else + NRF_NFCT->PADCONFIG = NFCT_PADCONFIG_ENABLE_Enabled << NFCT_PADCONFIG_ENABLE_Pos; + #endif +#endif +} + +/*lint --flb "Leave library region" */ diff --git a/hw/mcu/nordic/nrf54h20/startup/pkg.yml b/hw/mcu/nordic/nrf54h20/startup/pkg.yml new file mode 100644 index 0000000000..75bc9f8327 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/startup/pkg.yml @@ -0,0 +1,25 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/mcu/nordic/nrf54h20/startup +pkg.description: MCU default startup code +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - nrf54h20 diff --git a/hw/mcu/nordic/nrf54h20/startup/src/arch/cortex_m33/gcc_startup_nrf54h20.s b/hw/mcu/nordic/nrf54h20/startup/src/arch/cortex_m33/gcc_startup_nrf54h20.s new file mode 100644 index 0000000000..67f920b126 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/startup/src/arch/cortex_m33/gcc_startup_nrf54h20.s @@ -0,0 +1,862 @@ +/* + +Copyright (c) 2009-2024 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the License); you may +not use this file except in compliance with the License. +You may obtain a copy of the License at + + www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an AS IS BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +#include "syscfg/syscfg.h" + + .syntax unified + .arch armv8-m.main + +#if MYNEWT_VAL(MAIN_STACK_SIZE) +#define __STACK_SIZE MYNEWT_VAL(MAIN_STACK_SIZE) +#endif +#ifndef __STARTUP_FILL_MAIN_STACK +#define __STARTUP_FILL_MAIN_STACK 1 +#endif +#define __HEAP_SIZE 0 +#define __STARTUP_CLEAR_BSS + +#ifdef __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif +#endif + + .section .stack +#if defined(__STARTUP_CONFIG) + .align __STARTUP_CONFIG_STACK_ALIGNEMENT + .equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE +#elif defined(__STACK_SIZE) + .align 3 + .equ Stack_Size, __STACK_SIZE +#else + .align 3 + .equ Stack_Size, 8192 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#if defined(__STARTUP_CONFIG) + .equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE +#elif defined(__HEAP_SIZE) + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 8192 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector, "ax" + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler + .long NMI_Handler + .long HardFault_Handler + .long MemoryManagement_Handler + .long BusFault_Handler + .long UsageFault_Handler + .long SecureFault_Handler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SVC_Handler + .long DebugMon_Handler + .long 0 /*Reserved */ + .long PendSV_Handler + .long SysTick_Handler + + /* External Interrupts */ + .long SPU000_IRQHandler + .long MPC_IRQHandler + .long CPUC_IRQHandler + .long MVDMA_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SPU010_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long WDT010_IRQHandler + .long WDT011_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SPU020_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long EGU020_IRQHandler + .long 0 /*Reserved */ + .long GPIOTE_0_IRQHandler + .long TIMER020_IRQHandler + .long TIMER021_IRQHandler + .long TIMER022_IRQHandler + .long RTC_IRQHandler + .long RADIO_0_IRQHandler + .long RADIO_1_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SPU030_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long VPR_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long AAR030_CCM030_IRQHandler + .long ECB030_IRQHandler + .long AAR031_CCM031_IRQHandler + .long ECB031_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long IPCT_0_IRQHandler + .long IPCT_1_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SWI0_IRQHandler + .long SWI1_IRQHandler + .long SWI2_IRQHandler + .long SWI3_IRQHandler + .long SWI4_IRQHandler + .long SWI5_IRQHandler + .long SWI6_IRQHandler + .long SWI7_IRQHandler + .long BELLBOARD_0_IRQHandler + .long BELLBOARD_1_IRQHandler + .long BELLBOARD_2_IRQHandler + .long BELLBOARD_3_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long GPIOTE130_0_IRQHandler + .long GPIOTE130_1_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long GRTC_0_IRQHandler + .long GRTC_1_IRQHandler + .long GRTC_2_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TBM_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long USBHS_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long EXMIF_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long IPCT120_0_IRQHandler + .long 0 /*Reserved */ + .long I3C120_IRQHandler + .long VPR121_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long CAN120_IRQHandler + .long MVDMA120_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long I3C121_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER120_IRQHandler + .long TIMER121_IRQHandler + .long PWM120_IRQHandler + .long SPIS120_IRQHandler + .long SPIM120_UARTE120_IRQHandler + .long SPIM121_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long VPR130_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long IPCT130_0_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long RTC130_IRQHandler + .long RTC131_IRQHandler + .long 0 /*Reserved */ + .long WDT131_IRQHandler + .long WDT132_IRQHandler + .long EGU130_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SAADC_IRQHandler + .long COMP_LPCOMP_IRQHandler + .long TEMP_IRQHandler + .long NFCT_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TDM130_IRQHandler + .long PDM_IRQHandler + .long QDEC130_IRQHandler + .long QDEC131_IRQHandler + .long 0 /*Reserved */ + .long TDM131_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER130_IRQHandler + .long TIMER131_IRQHandler + .long PWM130_IRQHandler + .long SERIAL0_IRQHandler + .long SERIAL1_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER132_IRQHandler + .long TIMER133_IRQHandler + .long PWM131_IRQHandler + .long SERIAL2_IRQHandler + .long SERIAL3_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER134_IRQHandler + .long TIMER135_IRQHandler + .long PWM132_IRQHandler + .long SERIAL4_IRQHandler + .long SERIAL5_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER136_IRQHandler + .long TIMER137_IRQHandler + .long PWM133_IRQHandler + .long SERIAL6_IRQHandler + .long SERIAL7_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + + .size __isr_vector, . - __isr_vector + +/* Reset Handler */ + + + .text + .thumb + .thumb_func + .align 1 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + + +/* Loop to copy data from read only memory to RAM. + * The ranges of copy from/to are specified by following symbols: + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to. + * __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ + * the user can add their own initialized data section before BSS section with the INTERT AFTER command. + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__bss_start__ + + subs r3, r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: + +/* This part of work usually is done in C library startup code. Otherwise, + * define __STARTUP_CLEAR_BSS to enable it in this startup. This section + * clears the RAM where BSS data is located. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * All addresses must be aligned to 4 bytes boundary. + */ +#ifdef __STARTUP_CLEAR_BSS + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, r2, #4 + str r0, [r1, r2] + bgt .L_loop3 + +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS */ + +#if __STARTUP_FILL_MAIN_STACK + ldr r2, =0xdeadbeef + ldr r0, =__StackLimit + mov r1, sp +0: cmp r1, r0 + str r2, [r1,#-4]! + bge 0b +1: +#endif + + LDR R0, =__HeapBase + LDR R1, =__HeapLimit + BL _sbrkInit + +/* Execute SystemInit function. */ + bl SystemInit + +/* Execute hal_system_init */ + bl hal_system_init + +/* Call _start function provided by libraries. + * If those libraries are not accessible, define __START as your entry point. + */ +#ifndef __START +#define __START _start +#endif + bl __START + + .pool + .size Reset_Handler,.-Reset_Handler + + .section ".text" + + +/* Dummy Exception Handlers (infinite loops which can be modified) */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + .size NMI_Handler, . - NMI_Handler + + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + b . + .size HardFault_Handler, . - HardFault_Handler + + + .weak MemoryManagement_Handler + .type MemoryManagement_Handler, %function +MemoryManagement_Handler: + b . + .size MemoryManagement_Handler, . - MemoryManagement_Handler + + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + .size BusFault_Handler, . - BusFault_Handler + + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + .size UsageFault_Handler, . - UsageFault_Handler + + + .weak SecureFault_Handler + .type SecureFault_Handler, %function +SecureFault_Handler: + b . + .size SecureFault_Handler, . - SecureFault_Handler + + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + b . + .size SVC_Handler, . - SVC_Handler + + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + .size DebugMon_Handler, . - DebugMon_Handler + + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + .size PendSV_Handler, . - PendSV_Handler + + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + .size SysTick_Handler, . - SysTick_Handler + + +/* IRQ Handlers */ + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ SPU000_IRQHandler + IRQ MPC_IRQHandler + IRQ CPUC_IRQHandler + IRQ MVDMA_IRQHandler + IRQ SPU010_IRQHandler + IRQ WDT010_IRQHandler + IRQ WDT011_IRQHandler + IRQ SPU020_IRQHandler + IRQ EGU020_IRQHandler + IRQ GPIOTE_0_IRQHandler + IRQ TIMER020_IRQHandler + IRQ TIMER021_IRQHandler + IRQ TIMER022_IRQHandler + IRQ RTC_IRQHandler + IRQ RADIO_0_IRQHandler + IRQ RADIO_1_IRQHandler + IRQ SPU030_IRQHandler + IRQ VPR_IRQHandler + IRQ AAR030_CCM030_IRQHandler + IRQ ECB030_IRQHandler + IRQ AAR031_CCM031_IRQHandler + IRQ ECB031_IRQHandler + IRQ IPCT_0_IRQHandler + IRQ IPCT_1_IRQHandler + IRQ SWI0_IRQHandler + IRQ SWI1_IRQHandler + IRQ SWI2_IRQHandler + IRQ SWI3_IRQHandler + IRQ SWI4_IRQHandler + IRQ SWI5_IRQHandler + IRQ SWI6_IRQHandler + IRQ SWI7_IRQHandler + IRQ BELLBOARD_0_IRQHandler + IRQ BELLBOARD_1_IRQHandler + IRQ BELLBOARD_2_IRQHandler + IRQ BELLBOARD_3_IRQHandler + IRQ GPIOTE130_0_IRQHandler + IRQ GPIOTE130_1_IRQHandler + IRQ GRTC_0_IRQHandler + IRQ GRTC_1_IRQHandler + IRQ GRTC_2_IRQHandler + IRQ TBM_IRQHandler + IRQ USBHS_IRQHandler + IRQ EXMIF_IRQHandler + IRQ IPCT120_0_IRQHandler + IRQ I3C120_IRQHandler + IRQ VPR121_IRQHandler + IRQ CAN120_IRQHandler + IRQ MVDMA120_IRQHandler + IRQ I3C121_IRQHandler + IRQ TIMER120_IRQHandler + IRQ TIMER121_IRQHandler + IRQ PWM120_IRQHandler + IRQ SPIS120_IRQHandler + IRQ SPIM120_UARTE120_IRQHandler + IRQ SPIM121_IRQHandler + IRQ VPR130_IRQHandler + IRQ IPCT130_0_IRQHandler + IRQ RTC130_IRQHandler + IRQ RTC131_IRQHandler + IRQ WDT131_IRQHandler + IRQ WDT132_IRQHandler + IRQ EGU130_IRQHandler + IRQ SAADC_IRQHandler + IRQ COMP_LPCOMP_IRQHandler + IRQ TEMP_IRQHandler + IRQ NFCT_IRQHandler + IRQ TDM130_IRQHandler + IRQ PDM_IRQHandler + IRQ QDEC130_IRQHandler + IRQ QDEC131_IRQHandler + IRQ TDM131_IRQHandler + IRQ TIMER130_IRQHandler + IRQ TIMER131_IRQHandler + IRQ PWM130_IRQHandler + IRQ SERIAL0_IRQHandler + IRQ SERIAL1_IRQHandler + IRQ TIMER132_IRQHandler + IRQ TIMER133_IRQHandler + IRQ PWM131_IRQHandler + IRQ SERIAL2_IRQHandler + IRQ SERIAL3_IRQHandler + IRQ TIMER134_IRQHandler + IRQ TIMER135_IRQHandler + IRQ PWM132_IRQHandler + IRQ SERIAL4_IRQHandler + IRQ SERIAL5_IRQHandler + IRQ TIMER136_IRQHandler + IRQ TIMER137_IRQHandler + IRQ PWM133_IRQHandler + IRQ SERIAL6_IRQHandler + IRQ SERIAL7_IRQHandler + + .end diff --git a/hw/mcu/nordic/nrf54h20/startup/syscfg.yml b/hw/mcu/nordic/nrf54h20/startup/syscfg.yml new file mode 100644 index 0000000000..d2923e3594 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/startup/syscfg.yml @@ -0,0 +1,29 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + MAIN_STACK_SIZE: + description: > + Stack size (in bytes) to use in startup code. + For bootloader it's main stack, for application this stack is used by interrupts + and exceptions. + value: 768 + +syscfg.vals.BOOT_LOADER: + # MCUboot code uses a lot of stack + MAIN_STACK_SIZE: 1024 diff --git a/hw/mcu/nordic/nrf54h20/syscfg.yml b/hw/mcu/nordic/nrf54h20/syscfg.yml new file mode 100644 index 0000000000..9a501c2555 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20/syscfg.yml @@ -0,0 +1,161 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + MCU_TARGET: + description: > + Specifies target MCU. + value: nRF54H20 + restrictions: + - $notnull + choices: + - nRF54H20 + MCU_NET_CORE: + description: > + Constant value always set to 0. It allows to have common + packages for network and application core that do have + some differences depending on which core they are build for. + value: 0 + MCU_FLASH_MIN_WRITE_SIZE: + description: > + Specifies the required alignment for internal flash writes. + Used internally by the newt tool. + value: 1 + + MCU_LFCLK_SOURCE: + description: > + Selected source for low frequency clock (LFCLK). + value: + restrictions: + - '!BLE_CONTROLLER || (MCU_LFCLK_SOURCE != "LFRC")' + choices: + - LFRC # 32.768 kHz RC oscillator + - LFXO # 32.768 kHz crystal oscillator + - LFSYNTH # 32.768 kHz synthesized from HFCLK + + MCU_GPIO_USE_PORT_EVENT: + description: > + When enabled, hal_gpio will use GPIOTE PORT event instead of PIN + events for interrupts. This mode may be less accurate (i.e. pulse + length needs to be longer in order to be detected) but it reduces + power consumption since it does not require HFCLK to be running. + Refer to nRF54H20 Product Specification document for more details. + value: 0 + + MCU_DEBUG_IGNORE_BKPT: + description: > + When enabled, asm(bkpt) will be ignored. If not set, it will hit + the breakpoint wherever it gets called, For example, reset and crash + value: 0 + + MCU_ICACHE_ENABLED: + description: > + Enable instruction code cache + value: 1 + + MCU_DEFAULT_STARTUP: + description: > + Include default startup code. + Set to 0 if BSP provides customized startup code. + value: 1 + +# MCU peripherals definitions + TRNG: + description: 'Enable nRF54H20 TRNG' + value: 1 + + UART_0: + description: 'Enable nRF54H20 net UART0' + value: 0 + restrictions: + - "!SPI_0_MASTER" + - "!SPI_0_SLAVE" + UART_0_PIN_TX: + description: 'TX pin for UART0' + value: '' + UART_0_PIN_RX: + description: 'RX pin for UART0' + value: '' + UART_0_PIN_RTS: + description: 'RTS pin for UART0' + value: -1 + UART_0_PIN_CTS: + description: 'CTS pin for UART0' + value: -1 + + TIMER_0: + description: 'Enable nRF54H20 Net Timer 0' + value: 1 + TIMER_1: + description: 'Enable nRF54H20 Net Timer 1' + value: 0 + TIMER_2: + description: 'Enable nRF54H20 Net Timer 2' + value: 0 + TIMER_3: + description: 'Enable nRF54H20 Net RTC 0' + value: 0 + TIMER_4: + description: 'Enable nRF54H20 Net RTC 1' + value: 0 + + GPIO_AS_PIN_RESET: + description: 'Enable pin reset' + value: 0 + + SPI_0_MASTER: + description: 'Enable nRF54H20 SPI Master 0' + value: 0 + restrictions: + - "!SPI_0_SLAVE" + - "!UART_0" + SPI_0_MASTER_PIN_SCK: + description: 'SCK pin for SPI_0_MASTER' + value: '' + SPI_0_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_0_MASTER' + value: '' + SPI_0_MASTER_PIN_MISO: + description: 'MISO pin for SPI_0_MASTER' + value: '' + + SPI_0_SLAVE: + description: 'Enable nRF54H20 SPI Slave 0' + value: 0 + restrictions: + - "!SPI_0_MASTER" + - "!UART_0" + - "!I2C_0" + SPI_0_SLAVE_PIN_SCK: + description: 'SCK pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_MOSI: + description: 'MOSI pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_MISO: + description: 'MISO pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_SS: + description: 'SS pin for SPI_0_SLAVE' + value: '' + +syscfg.vals: + OS_TICKS_PER_SEC: 128 + +syscfg.restrictions: + - "!UART_0 || (UART_0_PIN_TX && UART_0_PIN_RX)" diff --git a/hw/mcu/nordic/nrf54h20_rad/include/mcu/cmsis_nvic.h b/hw/mcu/nordic/nrf54h20_rad/include/mcu/cmsis_nvic.h new file mode 100644 index 0000000000..0c26de0406 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/include/mcu/cmsis_nvic.h @@ -0,0 +1,28 @@ +/* mbed Microcontroller Library - cmsis_nvic + * Copyright (c) 2009-2011 ARM Limited. All rights reserved. + * + * CMSIS-style functionality to support dynamic vectors + */ + +#ifndef _CMSIS_NVIC_H_ +#define _CMSIS_NVIC_H_ + +#include +#include + +#define NVIC_NUM_VECTORS (16 + 30) /* CORE + MCU Peripherals */ +#define NVIC_USER_IRQ_OFFSET 16 + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_Relocate(void); +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/mcu/nordic/nrf54h20_rad/include/mcu/cortex_m33.h b/hw/mcu/nordic/nrf54h20_rad/include/mcu/cortex_m33.h new file mode 100644 index 0000000000..2cfcaa24a5 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/include/mcu/cortex_m33.h @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _CORTEX_M33_H_ +#define _CORTEX_M33_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void +hal_debug_break(void) +{ + __BKPT(1); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _CORTEX_M33_H_ */ diff --git a/hw/mcu/nordic/nrf54h20_rad/include/mcu/mcu.h b/hw/mcu/nordic/nrf54h20_rad/include/mcu/mcu.h new file mode 100644 index 0000000000..5f654ec659 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/include/mcu/mcu.h @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _MCU_H_ +#define _MCU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Defines for naming GPIOs. NOTE: the nordic chip docs use numeric labels for + * ports. Port A corresponds to Port 0, B to 1, etc. The nrf54h20 has two ports + * but Port 1 only has 16 pins. + */ +#define MCU_GPIO_PORTA(pin) ((0 * 16) + (pin)) +#define MCU_GPIO_PORTB(pin) ((1 * 16) + (pin)) + +#define MCU_SYSVIEW_INTERRUPTS \ + "I#1=Reset,I#2=NonMaskableInt,I#3=HardFault,I#4=MemoryManagement," \ + "I#5=BusFault,I#6=UsageFault,I#7=SecureFault,I#11=SVCall," \ + "I#12=DebugMonitor,I#14=PendSV,I#15=SysTick,I#21=CLOCK_POWER," \ + "I#24=RADIO,I#25=RNG,I#26=GPIOTE,I#27=WDT,I#28=TIMER0,I#29=ECB," \ + "I#30=AAR_CCM,I#32=TEMP,I#33=RTC0,I#34=IPC," \ + "I#35=SPIM0_SPIS0_TWIM0_TWIS0_UARTE0,I#36=EGU0,I#38=RTC1,I" \ + "#40=TIMER1,I#41=TIMER2,I#42=SWI0,I#43=SWI1,I#44=SWI2,I#45=SWI3" + +#ifdef __cplusplus +} +#endif + +#endif /* _MCU_H_ */ diff --git a/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_clock.h b/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_clock.h new file mode 100644 index 0000000000..1e8edf091a --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_clock.h @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_NRF5340_NET_CLOCK_ +#define H_NRF5340_NET_CLOCK_ + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * Request HFXO clock be turned on. Note that each request must have a + * corresponding release. + * + * @return int 0: hfxo was already on. 1: hfxo was turned on. + */ +int nrf54h20_rad_clock_hfxo_request(void); + +/** + * Release the HFXO; caller no longer needs the HFXO to be turned on. Each call + * to release should have been preceeded by a corresponding call to request the + * HFXO + * + * + * @return int 0: HFXO not stopped by this call (others using it) 1: HFXO + * stopped. + */ +int nrf54h20_rad_clock_hfxo_release(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF5340_NET_CLOCK_ */ diff --git a/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_hal.h b/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_hal.h new file mode 100644 index 0000000000..29faaf56c0 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_hal.h @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _NRF5340_NET_HAL_H_ +#define _NRF5340_NET_HAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "nrf_hal.h" + +struct nrf54h20_rad_uart_cfg { + int8_t suc_pin_tx; /* pins for IO */ + int8_t suc_pin_rx; + int8_t suc_pin_rts; + int8_t suc_pin_cts; +}; +const struct nrf54h20_rad_uart_cfg *bsp_uart_config(void); + +struct nrf54h20_vflash { + struct hal_flash nv_flash; + const uint8_t *nv_image_address; + uint32_t nv_image_size; + const struct flash_area *nv_slot1; +}; +extern struct nrf54h20_vflash nrf54h20_rad_vflash_dev; + +extern const struct hal_flash nrf54h20_flash_dev; +extern const struct hal_flash *ipc_flash(void); + +/* SPI configuration (used for both master and slave) */ +struct nrf54h20_rad_hal_spi_cfg { + int8_t sck_pin; + int8_t mosi_pin; + int8_t miso_pin; + int8_t ss_pin; +}; + +/* + * GPIO pin mapping + * + * The logical GPIO pin numbers (0 to N) are mapped to ports in the following + * manner: + * pins 0 - 31: Port 0 + * pins 32 - 48: Port 1. + * + * The nrf54h20 has 48 pins and uses two ports. + * + * NOTE: in order to save code space, there is no checking done to see if the + * user specifies a pin that is not used by the processor. If an invalid pin + * number is used unexpected and/or erroneous behavior will result. + */ + +#define HAL_GPIO_INDEX(pin) ((pin) & 0x1F) +#define HAL_GPIO_PORT(pin) ((pin) > 31 ? NRF_P1_NS : NRF_P0_NS) +#define HAL_GPIO_MASK(pin) (1 << HAL_GPIO_INDEX(pin)) +#define HAL_GPIOTE_PIN_MASK (0x3FUL << GPIOTE_CONFIG_PSEL_Pos) + +#ifdef __cplusplus +} +#endif + +#endif /* _NRF5340_NET_HAL_H_ */ + diff --git a/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_periph.h b/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_periph.h new file mode 100644 index 0000000000..456bbfb136 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/include/mcu/nrf54h20_rad_periph.h @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _NRF5340_NET_PERIPH_H_ +#define _NRF5340_NET_PERIPH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void nrf54h20_rad_periph_create(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _NRF5340_NET_PERIPH_H_ */ diff --git a/hw/mcu/nordic/nrf54h20_rad/include/nrfx_config_nrf54h20_radiocore.h b/hw/mcu/nordic/nrf54h20_rad/include/nrfx_config_nrf54h20_radiocore.h new file mode 100644 index 0000000000..4a8fca7140 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/include/nrfx_config_nrf54h20_radiocore.h @@ -0,0 +1,2047 @@ +/* + * Copyright (c) 2023 - 2024, Nordic Semiconductor ASA + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRFX_CONFIG_NRF54H20_RADIOCORE_H__ +#define NRFX_CONFIG_NRF54H20_RADIOCORE_H__ + +#ifndef NRFX_CONFIG_H__ +#error "This file should not be included directly. Include nrfx_config.h instead." +#endif + +/* Use nrfx API >= 3.2.0 */ +#ifdef NRFX_CONFIG_API_VER_MINOR +#undef NRFX_CONFIG_API_VER_MINOR +#endif +#define NRFX_CONFIG_API_VER_MINOR 2 + +#ifndef NRFX_RTC0_ENABLED +#define NRFX_RTC0_ENABLED 1 +#endif + +/** + * @brief NRFX_DEFAULT_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_DEFAULT_IRQ_PRIORITY +#define NRFX_DEFAULT_IRQ_PRIORITY 7 +#endif + +/** + * @brief NRFX_BELLBOARD_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD_ENABLED +#define NRFX_BELLBOARD_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_BELLBOARD0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD0_ENABLED +#define NRFX_BELLBOARD0_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD1_ENABLED +#define NRFX_BELLBOARD1_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD2_ENABLED +#define NRFX_BELLBOARD2_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD3_ENABLED +#define NRFX_BELLBOARD3_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_ENABLED +#define NRFX_COMP_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_CONFIG_LOG_ENABLED +#define NRFX_COMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_COMP_CONFIG_LOG_LEVEL +#define NRFX_COMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_ENABLED +#define NRFX_DPPI_ENABLED 1 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED +#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL +#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK +//#define NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0b00001111 +#define NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0b11111111 +#endif + +/** + * @brief NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000f0 +#endif + +/** + * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +//#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0b11110000 +#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0b00000000 +#endif + +/** + * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0b00001100 +#endif + +/** + * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 +#endif + +/** + * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 +#endif + +/** + * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 +#endif + +/** + * @brief NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK +//#define NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0b1111110000 +#define NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0b00000000 +#endif + +/** + * @brief NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000f +#endif + +/** + * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +//#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0b00001111 +#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0b11111111 +#endif + +/** + * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0b00000011 +#endif + +/** + * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df +#endif + +/** + * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf +#endif + +/** + * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e +#endif + +/** + * @brief NRFX_EGU_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_EGU_ENABLED +#define NRFX_EGU_ENABLED 0 +#endif + +/** + * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_EGU020_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_EGU020_ENABLED +#define NRFX_EGU020_ENABLED 0 +#endif + +/** + * @brief NRFX_EGU130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_EGU130_ENABLED +#define NRFX_EGU130_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_ENABLED +#define NRFX_GPIOTE_ENABLED 1 +#endif + +/** + * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS + * + * Integer value. Minimum: 0. Maximum: 15. + */ +#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS +#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED +#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL +#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_GPIOTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE130_ENABLED +#define NRFX_GPIOTE130_ENABLED 1 +#endif + +/** + * @brief NRFX_GRTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_ENABLED +#define NRFX_GRTC_ENABLED 1 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_AUTOEN + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_AUTOEN +#define NRFX_GRTC_CONFIG_AUTOEN 1 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_AUTOSTART + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_AUTOSTART +#define NRFX_GRTC_CONFIG_AUTOSTART 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT +#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS + * + * Integer value. + */ +#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK + */ +#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x00000f00 +#endif + +/** + * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED +#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL +#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0xc0 +#endif + +/** + * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0xc0 +#endif + +/** + * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0xc0 +#endif + +/** + * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0xc0 +#endif + +/** + * @brief NRFX_LPCOMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_ENABLED +#define NRFX_LPCOMP_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED +#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL +#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_MVDMA_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_MVDMA_ENABLED +#define NRFX_MVDMA_ENABLED 0 +#endif + +/** + * @brief NRFX_MVDMA120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_MVDMA120_ENABLED +#define NRFX_MVDMA120_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_ENABLED +#define NRFX_NFCT_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. + * + * Integer value. Minimum: 0. Maximum: 5. + */ +#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID +#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED +#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL +#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PDM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_ENABLED +#define NRFX_PDM_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_CONFIG_LOG_ENABLED +#define NRFX_PDM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PDM_CONFIG_LOG_LEVEL +#define NRFX_PDM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_BOX_0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_2_ENABLED +#define NRFX_PRS_BOX_2_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_3_ENABLED +#define NRFX_PRS_BOX_3_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_4_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_4_ENABLED +#define NRFX_PRS_BOX_4_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_5_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_5_ENABLED +#define NRFX_PRS_BOX_5_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_6_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_6_ENABLED +#define NRFX_PRS_BOX_6_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_7_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_7_ENABLED +#define NRFX_PRS_BOX_7_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_8_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_8_ENABLED +#define NRFX_PRS_BOX_8_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_9_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_9_ENABLED +#define NRFX_PRS_BOX_9_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_ENABLED +#define NRFX_PWM_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_CONFIG_LOG_ENABLED +#define NRFX_PWM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PWM_CONFIG_LOG_LEVEL +#define NRFX_PWM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PWM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM120_ENABLED +#define NRFX_PWM120_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM130_ENABLED +#define NRFX_PWM130_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM131_ENABLED +#define NRFX_PWM131_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM132_ENABLED +#define NRFX_PWM132_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM133_ENABLED +#define NRFX_PWM133_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_ENABLED +#define NRFX_QDEC_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED +#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL +#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_QDEC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC130_ENABLED +#define NRFX_QDEC130_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC131_ENABLED +#define NRFX_QDEC131_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_ENABLED +#define NRFX_RTC_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_CONFIG_LOG_ENABLED +#define NRFX_RTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_RTC_CONFIG_LOG_LEVEL +#define NRFX_RTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_RTC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC130_ENABLED +#define NRFX_RTC130_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC131_ENABLED +#define NRFX_RTC131_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_ENABLED +#define NRFX_SAADC_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED +#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL +#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_ENABLED +#define NRFX_SPIM_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED +#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL +#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM120_ENABLED +#define NRFX_SPIM120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM121_ENABLED +#define NRFX_SPIM121_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM130_ENABLED +#define NRFX_SPIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM131_ENABLED +#define NRFX_SPIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM132_ENABLED +#define NRFX_SPIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM133_ENABLED +#define NRFX_SPIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM134_ENABLED +#define NRFX_SPIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM135_ENABLED +#define NRFX_SPIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM136_ENABLED +#define NRFX_SPIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM137_ENABLED +#define NRFX_SPIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_ENABLED +#define NRFX_SPIS_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED +#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL +#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIS120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS120_ENABLED +#define NRFX_SPIS120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS130_ENABLED +#define NRFX_SPIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS131_ENABLED +#define NRFX_SPIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS132_ENABLED +#define NRFX_SPIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS133_ENABLED +#define NRFX_SPIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS134_ENABLED +#define NRFX_SPIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS135_ENABLED +#define NRFX_SPIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS136_ENABLED +#define NRFX_SPIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS137_ENABLED +#define NRFX_SPIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_SYSTICK_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SYSTICK_ENABLED +#define NRFX_SYSTICK_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_ENABLED +#define NRFX_TEMP_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED +#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL +#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_ENABLED +#define NRFX_TIMER_ENABLED 1 +#endif + +/** + * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED +#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL +#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER020_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER020_ENABLED +#define NRFX_TIMER020_ENABLED 1 +#endif + +/** + * @brief NRFX_TIMER021_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER021_ENABLED +#define NRFX_TIMER021_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER022_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER022_ENABLED +#define NRFX_TIMER022_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER120_ENABLED +#define NRFX_TIMER120_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER121_ENABLED +#define NRFX_TIMER121_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER130_ENABLED +#define NRFX_TIMER130_ENABLED 1 +#endif + +/** + * @brief NRFX_TIMER131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER131_ENABLED +#define NRFX_TIMER131_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER132_ENABLED +#define NRFX_TIMER132_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER133_ENABLED +#define NRFX_TIMER133_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER134_ENABLED +#define NRFX_TIMER134_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER135_ENABLED +#define NRFX_TIMER135_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER136_ENABLED +#define NRFX_TIMER136_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER137_ENABLED +#define NRFX_TIMER137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_ENABLED +#define NRFX_TWIM_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED +#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL +#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM130_ENABLED +#define NRFX_TWIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM131_ENABLED +#define NRFX_TWIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM132_ENABLED +#define NRFX_TWIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM133_ENABLED +#define NRFX_TWIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM134_ENABLED +#define NRFX_TWIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM135_ENABLED +#define NRFX_TWIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM136_ENABLED +#define NRFX_TWIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM137_ENABLED +#define NRFX_TWIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ENABLED +#define NRFX_TWIS_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED +#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized only once. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +/** + * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_NO_SYNC_MODE +#define NRFX_TWIS_NO_SYNC_MODE 0 +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL +#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS130_ENABLED +#define NRFX_TWIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS131_ENABLED +#define NRFX_TWIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS132_ENABLED +#define NRFX_TWIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS133_ENABLED +#define NRFX_TWIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS134_ENABLED +#define NRFX_TWIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS135_ENABLED +#define NRFX_TWIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS136_ENABLED +#define NRFX_TWIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS137_ENABLED +#define NRFX_TWIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for configuring GPIO pins is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for configuring PSEL registers is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_TX_LINK +#define NRFX_UARTE_CONFIG_TX_LINK 1 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED +#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 +#endif + +/** + * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE + * + * Integer value. Minimum: 0. Maximum: 255. + */ +#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE +#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 +#endif + +/** + * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED +#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL +#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_UARTE120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE120_ENABLED +#define NRFX_UARTE120_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE130_ENABLED +#define NRFX_UARTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE131_ENABLED +#define NRFX_UARTE131_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE132_ENABLED +#define NRFX_UARTE132_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE133_ENABLED +#define NRFX_UARTE133_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE134_ENABLED +#define NRFX_UARTE134_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE135_ENABLED +#define NRFX_UARTE135_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE136_ENABLED +#define NRFX_UARTE136_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE137_ENABLED +#define NRFX_UARTE137_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_ENABLED +#define NRFX_WDT_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_LOG_ENABLED +#define NRFX_WDT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_WDT_CONFIG_LOG_LEVEL +#define NRFX_WDT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_WDT010_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT010_ENABLED +#define NRFX_WDT010_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT011_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT011_ENABLED +#define NRFX_WDT011_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT131_ENABLED +#define NRFX_WDT131_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT132_ENABLED +#define NRFX_WDT132_ENABLED 0 +#endif + +#endif // NRFX_CONFIG_NRF54H20_RADIOCORE_H__ diff --git a/hw/mcu/nordic/nrf54h20_rad/nrf54h20_rad.ld b/hw/mcu/nordic/nrf54h20_rad/nrf54h20_rad.ld new file mode 100644 index 0000000000..c4d0a49e39 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/nrf54h20_rad.ld @@ -0,0 +1,224 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .imghdr (NOLOAD): + { + . = . + _imghdr_size; + } > FLASH + + __text = .; + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + +INCLUDE "link_tables.ld.h" + *(.rodata*) + + *(.eh_frame*) + PROVIDE(mynewt_main = main); + . = ALIGN(4); + } > FLASH + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + /* Section for IPC RX */ + .ipc0_rx (NOLOAD): + { + . = ALIGN(4); + *(.ipc0_rx) + . = ALIGN(4); + } > sram_ipc0_rx + + /* Section for IPC TX */ + .ipc0_tx (NOLOAD): + { + . = ALIGN(4); + *(.ipc0_tx) + . = ALIGN(4); + } > sram_ipc0_tx + + /* This section will be zeroed by RTT package init */ + .rtt (NOLOAD): + { + . = ALIGN(4); + *(.rtt) + . = ALIGN(4); + } > RAM + + .data : + { + __data_start__ = .; + *(vtable) + *(.data*) + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM AT > FLASH + + /* Non-zeroed BSS. This section is similar to BSS, with the following two + * caveats: + * 1. It does not get zeroed at init-time. + * 2. You cannot use it as source memory for EasyDMA. + * + * This section exists because of a hardware defect; see errata 33 and 34 + * in nrf52 errata sheet. + */ + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + _ram_start = ORIGIN(RAM); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} + diff --git a/hw/mcu/nordic/nrf54h20_rad/nrf54h20_rad_ram_resident.ld b/hw/mcu/nordic/nrf54h20_rad/nrf54h20_rad_ram_resident.ld new file mode 100644 index 0000000000..9cc5b105b3 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/nrf54h20_rad_ram_resident.ld @@ -0,0 +1,196 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text = .; + + __isr_vector_start = .; + __vector_tbl_reloc__ = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + +INCLUDE "link_tables.ld.h" + *(.rodata*) + + *(.eh_frame*) + PROVIDE(mynewt_main = main); + . = ALIGN(4); + } > RAM + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > RAM + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > RAM + __exidx_end = .; + + __etext = .; + + /* This section will be zeroed by RTT package init */ + .rtt (NOLOAD): + { + . = ALIGN(4); + *(.rtt) + . = ALIGN(4); + } > RAM + + .data : + { + __data_start__ = .; + *(vtable) + *(.data*) + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM + + /* Non-zeroed BSS. This section is similar to BSS, with the following two + * caveats: + * 1. It does not get zeroed at init-time. + * 2. You cannot use it as source memory for EasyDMA. + * + * This section exists because of a hardware defect; see errata 33 and 34 + * in nrf52 errata sheet. + */ + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + _ram_start = ORIGIN(RAM); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} + diff --git a/hw/mcu/nordic/nrf54h20_rad/pkg.yml b/hw/mcu/nordic/nrf54h20_rad/pkg.yml new file mode 100644 index 0000000000..30579b9074 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/pkg.yml @@ -0,0 +1,57 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/mcu/nordic/nrf54h20_rad +pkg.description: MCU definition for Nordic nRF54H20 ARM Cortex-M33 chip (net core). +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - nrf54 + - nrfx + +pkg.deps: + - "@apache-mynewt-core/hw/mcu/nordic" + - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" + - "@apache-mynewt-core/hw/drivers/ipc" + - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20_rad/startup" +# +#pkg.cflags.NFC_PINS_AS_GPIO: +# - '-DCONFIG_NFCT_PINS_AS_GPIOS=1' +# +#pkg.cflags.GPIO_AS_PIN_RESET: +# - '-DCONFIG_GPIO_AS_PINRESET=1' +# +#pkg.deps.UART_0: +# - "@apache-mynewt-core/hw/drivers/uart/uart_hal" +# +#pkg.deps.SPI_0_MASTER: +# - "@apache-mynewt-core/hw/bus" +# - "@apache-mynewt-core/hw/bus/drivers/spi_hal" +# +#pkg.deps.I2C_0': +# - "@apache-mynewt-core/hw/bus/drivers/i2c_nrf54h20" +# +pkg.deps.TRNG: + - "@apache-mynewt-core/hw/drivers/trng/trng_sw" + +pkg.deps.BLE_CONTROLLER: + - "@apache-mynewt-nimble/nimble/drivers/nrf54h20" +# +#pkg.deps.MCU_DEFAULT_STARTUP: +# - "@apache-mynewt-core/hw/mcu/nordic/nrf54h20_rad/startup" diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_flash.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_flash.c new file mode 100644 index 0000000000..6a8eb34de5 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_flash.c @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +// +//#include +//#include +//#include +//#include +//#include +// +//#define NRF5340_NET_FLASH_SECTOR_SZ 2048 +// +//#define NRF5340_NET_FLASH_READY() (NRF_NVMC->READY == NVMC_READY_READY_Ready) +// +//static int +//nrf54h20_rad_flash_wait_ready(void) +//{ +// int i; +// +// for (i = 0; i < 100000; i++) { +// if (NRF_NVMC_NS->READY == NVMC_READY_READY_Ready) { +// return 0; +// } +// } +// return -1; +//} +// +//static int +//nrf54h20_rad_flash_read(const struct hal_flash *dev, uint32_t address, void *dst, +// uint32_t num_bytes) +//{ +// memcpy(dst, (void *)address, num_bytes); +// return 0; +//} +// +///* +// * Flash write is done by writing 4 bytes at a time at a word boundary. +// */ +//static int +//nrf54h20_rad_flash_write(const struct hal_flash *dev, uint32_t address, +// const void *src, uint32_t num_bytes) +//{ +// int sr; +// int rc = -1; +// uint32_t val; +// int cnt; +// uint32_t tmp; +// +// if (nrf54h20_rad_flash_wait_ready()) { +// return -1; +// } +// __HAL_DISABLE_INTERRUPTS(sr); +// NRF_NVMC_NS->CONFIG = NVMC_CONFIG_WEN_Wen; /* Enable erase OP */ +// tmp = address & 0x3; +// if (tmp) { +// if (nrf54h20_rad_flash_wait_ready()) { +// goto out; +// } +// /* +// * Starts at a non-word boundary. Read 4 bytes which were there +// * before, update with new data, and write back. +// */ +// val = *(uint32_t *)(address & ~0x3); +// cnt = 4 - tmp; +// if (cnt > num_bytes) { +// cnt = num_bytes; +// } +// memcpy((uint8_t *)&val + tmp, src, cnt); +// *(uint32_t *)(address & ~0x3) = val; +// address += cnt; +// num_bytes -= cnt; +// src += cnt; +// } +// +// while (num_bytes >= sizeof(uint32_t)) { +// /* +// * Write data 4 bytes at a time. +// */ +// if (nrf54h20_rad_flash_wait_ready()) { +// goto out; +// } +// *(uint32_t *)address = *(uint32_t *)src; +// address += sizeof(uint32_t); +// src += sizeof(uint32_t); +// num_bytes -= sizeof(uint32_t); +// } +// if (num_bytes) { +// /* +// * Deal with the trailing bytes. +// */ +// val = *(uint32_t *)address; +// memcpy(&val, src, num_bytes); +// if (nrf54h20_rad_flash_wait_ready()) { +// goto out; +// } +// *(uint32_t *)address = val; +// } +// +// rc = nrf54h20_rad_flash_wait_ready(); +//out: +// NRF_NVMC_NS->CONFIG = NVMC_CONFIG_WEN_Ren; +// __HAL_ENABLE_INTERRUPTS(sr); +// return rc; +//} +// +//static int +//nrf54h20_rad_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address) +//{ +// int sr; +// int rc; +// +// sector_address &= ~(NRF5340_NET_FLASH_SECTOR_SZ - 1); +// +// if (nrf54h20_rad_flash_wait_ready()) { +// return -1; +// } +// __HAL_DISABLE_INTERRUPTS(sr); +// +// NRF_NVMC_NS->CONFIG = NVMC_CONFIG_WEN_Een; /* Enable erase OP */ +// *(uint32_t *)sector_address = 0xFFFFFFFF; +// +// rc = nrf54h20_rad_flash_wait_ready(); +// +// NRF_NVMC_NS->CONFIG = NVMC_CONFIG_WEN_Ren; +// __HAL_ENABLE_INTERRUPTS(sr); +// +// return rc; +//} +// +//static int +//nrf54h20_rad_flash_erase(const struct hal_flash *dev, uint32_t address, +// uint32_t num_bytes) +//{ +// uint32_t sector_address; +// +// if (address + num_bytes < dev->hf_base_addr || +// address > dev->hf_base_addr + dev->hf_size) { +// return -1; +// } +// +// sector_address = address & ~(NRF5340_NET_FLASH_SECTOR_SZ - 1); +// num_bytes += address - sector_address; +// num_bytes = (num_bytes + NRF5340_NET_FLASH_SECTOR_SZ - 1) & ~(NRF5340_NET_FLASH_SECTOR_SZ - 1); +// if (sector_address < dev->hf_base_addr) { +// num_bytes -= dev->hf_base_addr - sector_address; +// sector_address = dev->hf_base_addr; +// } +// +// while (num_bytes > 0 && sector_address < dev->hf_base_addr + dev->hf_size) { +// nrf54h20_rad_flash_erase_sector(dev, sector_address); +// num_bytes -= NRF5340_NET_FLASH_SECTOR_SZ; +// sector_address += NRF5340_NET_FLASH_SECTOR_SZ; +// } +// +// return 0; +//} +// +//static int +//nrf54h20_rad_flash_sector_info(const struct hal_flash *dev, int idx, +// uint32_t *address, uint32_t *sz) +//{ +// assert(idx < nrf54h20_flash_dev.hf_sector_cnt); +// *address = dev->hf_base_addr + idx * NRF5340_NET_FLASH_SECTOR_SZ; +// *sz = NRF5340_NET_FLASH_SECTOR_SZ; +// return 0; +//} +// +//static int +//nrf54h20_rad_flash_init(const struct hal_flash *dev) +//{ +// return 0; +//} +// +//static const struct hal_flash_funcs nrf54h20_rad_flash_funcs = { +// .hff_read = nrf54h20_rad_flash_read, +// .hff_write = nrf54h20_rad_flash_write, +// .hff_erase_sector = nrf54h20_rad_flash_erase_sector, +// .hff_sector_info = nrf54h20_rad_flash_sector_info, +// .hff_init = nrf54h20_rad_flash_init, +// .hff_erase = nrf54h20_rad_flash_erase, +//}; +// +//const struct hal_flash nrf54h20_flash_dev = { +// .hf_itf = &nrf54h20_rad_flash_funcs, +// .hf_base_addr = 0x01000000, +// .hf_size = 256 * 1024, /* XXX read from factory info? */ +// .hf_sector_cnt = 128, /* XXX read from factory info? */ +// .hf_align = 1, +// .hf_erased_val = 0xff, +//}; diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_ipc.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_ipc.c new file mode 100644 index 0000000000..ab15a61e79 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_ipc.c @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// #include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BIT +#define BIT(n) (1UL << (n)) +#endif + +#define IPC_MAX_CHANS BELLBOARD_EVENTS_TRIGGERED_MaxCount +#define BELLBOARD_IPC0_IRQ BELLBOARD_0_IRQn +#define BELLBOARD_NUM_IRQS 4U +#if MYNEWT_VAL(MCU_APP_CORE) +#define BELLBOARD_LOCAL NRF_APPLICATION_BELLBOARD_S +#define BELLBOARD_REMOTE NRF_RADIOCORE_BELLBOARD_S +#else +#define BELLBOARD_LOCAL NRF_RADIOCORE_BELLBOARD_S +#define BELLBOARD_REMOTE NRF_APPLICATION_BELLBOARD_S +#endif + +/* ipc0: 0: cpurad-cpusec, 6: cpurad-cpusys, 12: cpurad-cpuapp */ +#define BELLBOARD_IPC0_EVENTS_MAP (0x00001041) + +static const uint32_t evt_mappings[BELLBOARD_NUM_IRQS] = { + BELLBOARD_IPC0_EVENTS_MAP, 0, 0, 0 +}; + +static hal_ipc_cb cbs[IPC_MAX_CHANS]; + +int +hal_ipc_signal(uint8_t channel) +{ + assert(channel < IPC_MAX_CHANS); + + nrf_bellboard_task_trigger(BELLBOARD_REMOTE, nrf_bellboard_trigger_task_get(channel)); + + return 0; +} + +void +hal_ipc_register_callback(uint8_t channel, hal_ipc_cb cb) +{ + assert(channel < IPC_MAX_CHANS); + + cbs[channel] = cb; +} + +void +hal_ipc_enable_irq(uint8_t channel, bool enable) +{ + uint8_t i; + + assert(channel < IPC_MAX_CHANS); + + for (i = 0U; i < BELLBOARD_NUM_IRQS; i++) { + + if ((evt_mappings[i] & BIT(channel)) == 0U) { + continue; + } + + if (enable) { + nrf_bellboard_int_enable(BELLBOARD_LOCAL, i, BIT(channel)); + } else { + nrf_bellboard_int_disable(BELLBOARD_LOCAL, i, BIT(channel)); + } + } +} + +static void +ipc0_isr(void) +{ + uint32_t int_pend; + nrf_bellboard_event_t event; + uint8_t channel; + + int_pend = nrf_bellboard_int_pending_get(BELLBOARD_LOCAL, 0); + + for (channel = 0; channel < IPC_MAX_CHANS; channel++) { + event = nrf_bellboard_triggered_event_get(channel); + + if ((int_pend & BIT(channel)) != 0U) { + if (nrf_bellboard_event_check(BELLBOARD_LOCAL, event)) { + nrf_bellboard_event_clear(BELLBOARD_LOCAL, event); + } + + if (cbs[channel] != NULL) { + cbs[channel](channel); + } + } + } +} + +void +hal_ipc_init(void) +{ + uint32_t evt_all_mappings = evt_mappings[0] | evt_mappings[1] | + evt_mappings[2] | evt_mappings[3]; + uint8_t i = 0U; + + for (i = 0U; i < BELLBOARD_NUM_IRQS; ++i) { + nrf_bellboard_int_disable(BELLBOARD_LOCAL, i, evt_mappings[i]); + } + + for (i = 0U; i < IPC_MAX_CHANS; ++i) { + if ((evt_all_mappings & BIT(i)) != 0U) { + nrf_bellboard_event_clear(BELLBOARD_LOCAL, nrf_bellboard_triggered_event_get(i)); + } + } + + NVIC_SetPriority(BELLBOARD_IPC0_IRQ, 1); + NVIC_SetVector(BELLBOARD_IPC0_IRQ, (uint32_t)ipc0_isr); + NVIC_EnableIRQ(BELLBOARD_IPC0_IRQ); +} + +void +hal_ipc_start(void) +{ + +} diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_nvreg.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_nvreg.c new file mode 100644 index 0000000000..7db3ed4618 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_nvreg.c @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// #include +// #include +// #include + +// /* There are two GPREGRET registers on the NRF5340 */ +// #define HAL_NVREG_MAX (2) + +// /* GPREGRET registers only save the 8 lsbits */ +// #define HAL_NVREG_WIDTH_BYTES (1) + +// void +// hal_nvreg_write(unsigned int reg, uint32_t val) +// { +// if (reg < HAL_NVREG_MAX) { +// NRF_POWER_NS->GPREGRET[reg] = val; +// } +// } + +// uint32_t +// hal_nvreg_read(unsigned int reg) +// { +// uint32_t val = 0; + +// if (reg < HAL_NVREG_MAX) { +// val = NRF_POWER_NS->GPREGRET[reg]; +// } + +// return val; +// } + +// unsigned int +// hal_nvreg_get_num_regs(void) +// { +// return HAL_NVREG_MAX; +// } + +// unsigned int +// hal_nvreg_get_reg_width(void) +// { +// return HAL_NVREG_WIDTH_BYTES; +// } diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_os_tick.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_os_tick.c new file mode 100644 index 0000000000..e6cea0bc1b --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_os_tick.c @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include + +/* The OS scheduler requires a low-frequency timer. */ +#if MYNEWT_VAL(OS_SCHEDULING) && !MYNEWT_VAL(MCU_LFCLK_SOURCE) + #error The OS scheduler requires a low-frequency timer; configure MCU_LFCLK_SOURCE +#endif + +#define RTC_FREQ 32768 /* in Hz */ + +struct hal_os_tick { + int ticks_per_ostick; + os_time_t max_idle_ticks; + uint32_t lastocmp; +}; + +struct hal_os_tick g_hal_os_tick; +struct hal_timer os_tick_timer; + +/* + * Implement (x - y) where the range of both 'x' and 'y' is limited to 24-bits. + * + * For example: + * + * sub24(0, 0xffffff) = 1 + * sub24(0xffffff, 0xfffffe) = 1 + * sub24(0xffffff, 0) = -1 + * sub24(0x7fffff, 0) = 8388607 + * sub24(0x800000, 0) = -8388608 + */ +static inline int +sub24(uint32_t x, uint32_t y) +{ + int result; + + assert(x <= 0xffffff); + assert(y <= 0xffffff); + + result = x - y; + if (result & 0x800000) { + return (result | 0xff800000); + } else { + return (result & 0x007fffff); + } +} + +static inline uint32_t +nrf54h20_rad_os_tick_counter(void) +{ + return os_cputime_get32() & 0x00ffffff; +} + +static inline void +nrf54h20_rad_os_tick_set_ocmp(uint32_t ocmp) +{ +// int delta; +// uint32_t counter; + + OS_ASSERT_CRITICAL(); + ocmp &= 0xffffff; + os_cputime_timer_start(&os_tick_timer, ocmp); +// while (1) { +// ocmp &= 0xffffff; +// counter = nrf54h20_rad_os_tick_counter(); +// /* +// * From nRF5340 Product specification +// * +// * - If Counter is 'N' writing (N) or (N + 1) to CC register +// * may not trigger a compare event. +// * +// * - If Counter is 'N' writing (N + 2) to CC register is guaranteed +// * to trigger a compare event at 'N + 2'. +// */ +// delta = sub24(ocmp, counter); +// if (delta > 2) { +// break; +// } +// ocmp += g_hal_os_tick.ticks_per_ostick; +// } +} + +static void +nrf54h20_rad_timer_handler(void *arg) +{ + int delta; + int ticks; + os_sr_t sr; + uint32_t counter; + + os_trace_isr_enter(); + OS_ENTER_CRITICAL(sr); + + /* Calculate elapsed ticks and advance OS time. */ + + counter = nrf54h20_rad_os_tick_counter(); + delta = sub24(counter, g_hal_os_tick.lastocmp); + ticks = delta / g_hal_os_tick.ticks_per_ostick; + os_time_advance(ticks); + + /* Update the time associated with the most recent tick */ + g_hal_os_tick.lastocmp = (g_hal_os_tick.lastocmp + + (ticks * g_hal_os_tick.ticks_per_ostick)) & 0xffffff; + + /* Update the output compare to interrupt at the next tick */ + nrf54h20_rad_os_tick_set_ocmp(g_hal_os_tick.lastocmp + g_hal_os_tick.ticks_per_ostick); + + OS_EXIT_CRITICAL(sr); + os_trace_isr_exit(); +} + +void +os_tick_idle(os_time_t ticks) +{ + uint32_t ocmp; + + OS_ASSERT_CRITICAL(); + + if (ticks > 0) { + /* + * Enter tickless regime during long idle durations. + */ + if (ticks > g_hal_os_tick.max_idle_ticks) { + ticks = g_hal_os_tick.max_idle_ticks; + } + ocmp = g_hal_os_tick.lastocmp + (ticks*g_hal_os_tick.ticks_per_ostick); + nrf54h20_rad_os_tick_set_ocmp(ocmp); + } + + __DSB(); + __WFI(); + + if (ticks > 0) { + /* + * Update OS time before anything else when coming out of + * the tickless regime. + */ + nrf54h20_rad_timer_handler(NULL); + } +} + +void +os_tick_init(uint32_t os_ticks_per_sec, int prio) +{ + uint32_t sr; + + assert(RTC_FREQ % os_ticks_per_sec == 0); + + g_hal_os_tick.lastocmp = 0; + g_hal_os_tick.ticks_per_ostick = RTC_FREQ / os_ticks_per_sec; + + /* + * The maximum number of OS ticks allowed to elapse during idle is + * limited to 1/4th the number of timer ticks before the 24-bit counter + * rolls over. + */ + g_hal_os_tick.max_idle_ticks = (1UL << 22) / g_hal_os_tick.ticks_per_ostick; + + os_cputime_timer_init(&os_tick_timer, nrf54h20_rad_timer_handler, NULL); + os_cputime_timer_start(&os_tick_timer, g_hal_os_tick.ticks_per_ostick); +} diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_reset_cause.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_reset_cause.c new file mode 100644 index 0000000000..dbc3c28935 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_reset_cause.c @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include + +enum hal_reset_reason +hal_reset_cause(void) +{ + static enum hal_reset_reason reason; + uint32_t reg; + + // if (reason) { + // return reason; + // } + + // reg = NRF_RESET_NS->RESETREAS; + + // if (reg & (RESET_RESETREAS_DOG0_Msk | RESET_RESETREAS_DOG1_Msk | RESET_RESETREAS_LOCKUP_Msk)) { + // reason = HAL_RESET_WATCHDOG; + // } else if (reg & RESET_RESETREAS_SREQ_Msk) { + // reason = HAL_RESET_SOFT; + // } else if (reg & RESET_RESETREAS_RESETPIN_Msk) { + // reason = HAL_RESET_PIN; + // } else if (reg & RESET_RESETREAS_OFF_Msk) { + // reason = HAL_RESET_SYS_OFF_INT; + // } else { + // reason = HAL_RESET_POR; /* could also be brownout */ + // } + + // NRF_RESET_NS->RESETREAS = reg; + + return 0; +} diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_spi.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_spi.c new file mode 100644 index 0000000000..3b7907650f --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_spi.c @@ -0,0 +1,831 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +// #if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE) + +// #define SPIM_TXD_MAXCNT_MAX 0xffff + +// /* Used to disable all interrupts */ +// #define NRF_SPI_IRQ_DISABLE_ALL 0xffffffff + +// /* +// * Slave states +// * +// * IDLE: Slave not ready to be used. If master attempts to access +// * slave it will receive the default character +// * ACQ_SEM: Slave is attempting to acquire semaphore. +// * READY: Slave is ready for master to send it data +// * +// */ +// #define HAL_SPI_SLAVE_STATE_IDLE (0) +// #define HAL_SPI_SLAVE_STATE_ACQ_SEM (1) +// #define HAL_SPI_SLAVE_STATE_READY (2) + +// #if MYNEWT_VAL(SPI_0_MASTER) +// struct nrf54h20_rad_hal_spi +// { +// uint8_t spi_xfr_flag; +// uint8_t dummy_rx; +// uint16_t nhs_buflen; +// uint16_t nhs_bytes_txd; +// struct hal_spi_settings spi_cfg; + +// /* Pointers to tx/rx buffers */ +// uint8_t *nhs_txbuf; +// uint8_t *nhs_rxbuf; + +// /* Callback and arguments */ +// hal_spi_txrx_cb txrx_cb_func; +// void *txrx_cb_arg; +// }; +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// struct nrf54h20_rad_hal_spi +// { +// uint8_t slave_state; +// uint16_t nhs_buflen; +// uint16_t nhs_bytes_txd; +// struct hal_spi_settings spi_cfg; + +// /* Pointers to tx/rx buffers */ +// uint8_t *nhs_txbuf; +// uint8_t *nhs_rxbuf; + +// /* Callback and arguments */ +// hal_spi_txrx_cb txrx_cb_func; +// void *txrx_cb_arg; +// }; +// #endif + +// static struct nrf54h20_rad_hal_spi nrf54h20_rad_hal_spi0; + +// static void +// nrf54h20_rad_spi0_irq_handler(void) +// { +// struct nrf54h20_rad_hal_spi *spi = &nrf54h20_rad_hal_spi0; +// uint16_t xfr_bytes; +// #if MYNEWT_VAL(SPI_0_MASTER) +// uint16_t len; +// #endif + +// os_trace_isr_enter(); + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (NRF_SPIM0_NS->EVENTS_END) { +// NRF_SPIM0_NS->EVENTS_END = 0; + +// /* Should not occur but if no transfer just leave */ +// if (spi->spi_xfr_flag != 0) { +// /* Are there more bytes to send? */ +// xfr_bytes = NRF_SPIM0_NS->TXD.AMOUNT; +// spi->nhs_bytes_txd += xfr_bytes; +// if (spi->nhs_bytes_txd < spi->nhs_buflen) { +// spi->nhs_txbuf += xfr_bytes; +// len = spi->nhs_buflen - spi->nhs_bytes_txd; +// len = min(SPIM_TXD_MAXCNT_MAX, len); +// NRF_SPIM0_NS->TXD.PTR = (uint32_t)spi->nhs_txbuf; +// NRF_SPIM0_NS->TXD.MAXCNT = len; + +// /* If no rxbuf, we need to set rxbuf and maxcnt to 1 */ +// if (spi->nhs_rxbuf) { +// spi->nhs_rxbuf += xfr_bytes; +// NRF_SPIM0_NS->RXD.PTR = (uint32_t)spi->nhs_rxbuf; +// NRF_SPIM0_NS->RXD.MAXCNT = len; +// } +// NRF_SPIM0_NS->TASKS_START = 1; +// } else { +// spi->spi_xfr_flag = 0; +// NRF_SPIM0_NS->INTENCLR = SPIM_INTENSET_END_Msk; +// if (spi->txrx_cb_func) { +// spi->txrx_cb_func(spi->txrx_cb_arg, spi->nhs_buflen); +// } +// } +// } +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// /* Semaphore acquired event */ +// if (NRF_SPIS0_NS->EVENTS_ACQUIRED) { +// NRF_SPIS0_NS->EVENTS_ACQUIRED = 0; + +// if (spi->slave_state == HAL_SPI_SLAVE_STATE_ACQ_SEM) { +// if (spi->nhs_txbuf == NULL) { +// NRF_SPIS0_NS->TXD.PTR = 0; +// NRF_SPIS0_NS->TXD.MAXCNT = 0; +// } else { +// NRF_SPIS0_NS->TXD.PTR = (uint32_t)spi->nhs_txbuf; +// NRF_SPIS0_NS->TXD.MAXCNT = spi->nhs_buflen; +// } + +// if (spi->nhs_rxbuf == NULL) { +// NRF_SPIS0_NS->RXD.PTR = 0; +// NRF_SPIS0_NS->RXD.MAXCNT = 0; +// } else { +// NRF_SPIS0_NS->RXD.PTR = (uint32_t)spi->nhs_rxbuf; +// NRF_SPIS0_NS->RXD.MAXCNT = spi->nhs_buflen; +// } +// NRF_SPIS0_NS->TASKS_RELEASE = 1; +// spi->slave_state = HAL_SPI_SLAVE_STATE_READY; +// } +// } + +// /* SPI transaction complete */ +// if (NRF_SPIS0_NS->EVENTS_END) { +// NRF_SPIS0_NS->EVENTS_END = 0; +// if (spi->slave_state == HAL_SPI_SLAVE_STATE_READY) { +// if (spi->txrx_cb_func) { +// /* Get transfer length */ +// if (spi->nhs_txbuf == NULL) { +// xfr_bytes = NRF_SPIS0_NS->RXD.AMOUNT; +// } else { +// xfr_bytes = NRF_SPIS0_NS->TXD.AMOUNT; +// } +// spi->txrx_cb_func(spi->txrx_cb_arg, xfr_bytes); +// } +// spi->slave_state = HAL_SPI_SLAVE_STATE_IDLE; +// } +// } +// #endif + +// os_trace_isr_exit(); +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// static void +// hal_spi_master_stop_transfer(void) +// { +// NRF_SPIM0_NS->TASKS_STOP = 1; +// while (!NRF_SPIM0_NS->EVENTS_STOPPED) { +// }; +// NRF_SPIM0_NS->EVENTS_STOPPED = 0; +// } + +// static int +// hal_spi_config_master(struct nrf54h20_rad_hal_spi *spi, +// struct hal_spi_settings *settings) +// { +// int rc; +// uint32_t nrf_config; +// uint32_t frequency; +// NRF_GPIO_Type *port; +// uint32_t pin; + +// memcpy(&spi->spi_cfg, settings, sizeof(*settings)); + +// /* +// * Configure SCK. NOTE: this is done here in the config API as the data +// * mode is not set at init time so we do it here when we configure the SPI. +// */ +// pin = NRF_SPIM0_NS->PSEL.SCK & SPIM_PSEL_SCK_PIN_Msk; +// if (NRF_SPIM0_NS->PSEL.SCK & SPIM_PSEL_SCK_PORT_Msk) { +// port = NRF_P1_NS; +// } else { +// port = NRF_P0_NS; +// } + +// if (settings->data_mode <= HAL_SPI_MODE1) { +// port->OUTCLR = (1UL << pin); +// } else { +// port->OUTSET = (1UL << pin); +// } +// port->PIN_CNF[pin] = +// (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | +// (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); + +// /* Only 8-bit word sizes supported. */ +// rc = 0; +// switch (settings->word_size) { +// case HAL_SPI_WORD_SIZE_8BIT: +// break; +// default: +// rc = EINVAL; +// break; +// } + +// switch (settings->data_mode) { +// case HAL_SPI_MODE0: +// nrf_config = (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | +// (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE1: +// nrf_config = (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | +// (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE2: +// nrf_config = (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | +// (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE3: +// nrf_config = (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | +// (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); +// break; +// default: +// nrf_config = 0; +// rc = EINVAL; +// break; +// } + +// /* NOTE: msb first is 0 so no check done */ +// if (settings->data_order == HAL_SPI_LSB_FIRST) { +// nrf_config |= SPIM_CONFIG_ORDER_LsbFirst; +// } +// NRF_SPIM0_NS->CONFIG = nrf_config; + +// switch (settings->baudrate) { +// case 125: +// frequency = SPIM_FREQUENCY_FREQUENCY_K125; +// break; +// case 250: +// frequency = SPIM_FREQUENCY_FREQUENCY_K250; +// break; +// case 500: +// frequency = SPIM_FREQUENCY_FREQUENCY_K500; +// break; +// case 1000: +// frequency = SPIM_FREQUENCY_FREQUENCY_M1; +// break; +// case 2000: +// frequency = SPIM_FREQUENCY_FREQUENCY_M2; +// break; +// case 4000: +// frequency = SPIM_FREQUENCY_FREQUENCY_M4; +// break; +// case 8000: +// frequency = SPIM_FREQUENCY_FREQUENCY_M8; +// break; +// default: +// frequency = 0; +// rc = EINVAL; +// break; +// } +// NRF_SPIM0_NS->FREQUENCY = frequency; + +// return rc; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// static int +// hal_spi_config_slave(struct nrf54h20_rad_hal_spi *spi, +// struct hal_spi_settings *settings) +// { +// int rc; +// uint32_t nrf_config; + +// rc = 0; +// switch (settings->data_mode) { +// case HAL_SPI_MODE0: +// nrf_config = (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) | +// (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE1: +// nrf_config = (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) | +// (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE2: +// nrf_config = (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) | +// (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos); +// break; +// case HAL_SPI_MODE3: +// nrf_config = (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) | +// (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); +// break; +// default: +// nrf_config = 0; +// rc = EINVAL; +// break; +// } + +// if (settings->data_order == HAL_SPI_LSB_FIRST) { +// nrf_config |= SPIS_CONFIG_ORDER_LsbFirst; +// } +// NRF_SPIS0_NS->CONFIG = nrf_config; + +// /* Only 8-bit word sizes supported. */ +// switch (settings->word_size) { +// case HAL_SPI_WORD_SIZE_8BIT: +// break; +// default: +// rc = EINVAL; +// break; +// } + +// return rc; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_MASTER) +// static int +// hal_spi_init_master(struct nrf54h20_rad_hal_spi *spi, +// struct nrf54h20_rad_hal_spi_cfg *cfg) +// { +// NRF_GPIO_Type *port; +// uint32_t pin; + +// /* Configure MOSI */ +// port = HAL_GPIO_PORT(cfg->mosi_pin); +// pin = HAL_GPIO_INDEX(cfg->mosi_pin); +// port->OUTCLR = (1UL << pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); + +// /* Configure MISO */ +// port = HAL_GPIO_PORT(cfg->miso_pin); +// pin = HAL_GPIO_INDEX(cfg->miso_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// NRF_SPIM0_NS->PSEL.SCK = cfg->sck_pin; +// NRF_SPIM0_NS->PSEL.MOSI = cfg->mosi_pin; +// NRF_SPIM0_NS->PSEL.MISO = cfg->miso_pin; + +// NRF_SPIM0_NS->INTENCLR = NRF_SPI_IRQ_DISABLE_ALL; +// NVIC_SetVector(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (uint32_t)nrf54h20_rad_spi0_irq_handler); +// NVIC_SetPriority(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (1 << __NVIC_PRIO_BITS) - 1); +// NVIC_ClearPendingIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); +// NVIC_EnableIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); + +// return 0; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// static int +// hal_spi_init_slave(struct nrf54h20_rad_hal_spi *spi, +// struct nrf54h20_rad_hal_spi_cfg *cfg) +// { +// NRF_GPIO_Type *port; +// uint32_t pin; + +// /* NOTE: making this pin an input is correct! See datasheet */ +// port = HAL_GPIO_PORT(cfg->miso_pin); +// pin = HAL_GPIO_INDEX(cfg->miso_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// port = HAL_GPIO_PORT(cfg->mosi_pin); +// pin = HAL_GPIO_INDEX(cfg->mosi_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// port = HAL_GPIO_PORT(cfg->ss_pin); +// pin = HAL_GPIO_INDEX(cfg->ss_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// port = HAL_GPIO_PORT(cfg->sck_pin); +// pin = HAL_GPIO_INDEX(cfg->sck_pin); +// port->PIN_CNF[pin] = +// ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | +// ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + +// NRF_SPIS0_NS->PSEL.SCK = cfg->sck_pin; +// NRF_SPIS0_NS->PSEL.MOSI = cfg->mosi_pin; +// NRF_SPIS0_NS->PSEL.MISO = cfg->miso_pin; +// NRF_SPIS0_NS->PSEL.CSN = cfg->ss_pin; + +// /* Disable interrupt and clear any interrupt events */ +// NRF_SPIS0_NS->INTENCLR = SPIS_INTENSET_ACQUIRED_Msk | SPIS_INTENSET_END_Msk; +// NRF_SPIS0_NS->EVENTS_END = 0; +// NRF_SPIS0_NS->EVENTS_ACQUIRED = 0; + +// /* Enable END_ACQUIRE shortcut. */ +// NRF_SPIS0_NS->SHORTS = SPIS_SHORTS_END_ACQUIRE_Msk; + +// /* Set interrupt vector and enable IRQ */ +// NVIC_SetVector(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (uint32_t)nrf54h20_rad_spi0_irq_handler); +// NVIC_SetPriority(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (1 << __NVIC_PRIO_BITS) - 1); +// NVIC_ClearPendingIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); +// NVIC_EnableIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); + +// return 0; +// } +// #endif + +// /** +// * Initialize the SPI, given by spi_num. +// * +// * @param spi_num The number of the SPI to initialize +// * @param cfg HW/MCU specific configuration, +// * passed to the underlying implementation, providing extra +// * configuration. +// * @param spi_type SPI type (master or slave) +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_init(int spi_num, void *cfg, uint8_t spi_type) +// { +// struct nrf54h20_rad_hal_spi *spi = &nrf54h20_rad_hal_spi0; + +// /* Check for valid arguments */ +// if (spi_num != 0 || cfg == NULL) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (spi_type != HAL_SPI_TYPE_MASTER) { +// return EINVAL; +// } + +// return hal_spi_init_master(spi, (struct nrf54h20_rad_hal_spi_cfg *)cfg); +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// if (spi_type != HAL_SPI_TYPE_SLAVE) { +// return EINVAL; +// } + +// return hal_spi_init_slave(spi, (struct nrf54h20_rad_hal_spi_cfg *)cfg); +// #endif +// } + +// int +// hal_spi_init_hw(uint8_t spi_num, uint8_t spi_type, +// const struct hal_spi_hw_settings *cfg) +// { +// struct nrf54h20_rad_hal_spi_cfg hal_cfg; + +// hal_cfg.sck_pin = cfg->pin_sck; +// hal_cfg.mosi_pin = cfg->pin_mosi; +// hal_cfg.miso_pin = cfg->pin_miso; +// hal_cfg.ss_pin = cfg->pin_ss; + +// return hal_spi_init(spi_num, &hal_cfg, spi_type); +// } + +// /** +// * Configure the spi. Must be called after the spi is initialized (after +// * hal_spi_init is called) and when the spi is disabled (user must call +// * hal_spi_disable if the spi has been enabled through hal_spi_enable prior +// * to calling this function). Can also be used to reconfigure an initialized +// * SPI (assuming it is disabled as described previously). +// * +// * @param spi_num The number of the SPI to configure. +// * @param psettings The settings to configure this SPI with +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_config(int spi_num, struct hal_spi_settings *settings) +// { +// struct nrf54h20_rad_hal_spi *spi = &nrf54h20_rad_hal_spi0; + +// if (spi_num != 0) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (NRF_SPIM0_NS->ENABLE != 0) { +// return EINVAL; +// } + +// return hal_spi_config_master(spi, settings); +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// if (NRF_SPIS0_NS->ENABLE != 0) { +// return EINVAL; +// } + +// return hal_spi_config_slave(spi, settings); +// #endif +// } + +// /** +// * Enables the SPI. This does not start a transmit or receive operation; +// * it is used for power mgmt. Cannot be called when a SPI transfer is in +// * progress. +// * +// * @param spi_num +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_enable(int spi_num) +// { +// struct nrf54h20_rad_hal_spi *spi = &nrf54h20_rad_hal_spi0; + +// if (spi_num != 0 || spi->txrx_cb_func == NULL) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// NRF_SPIM0_NS->EVENTS_END = 0; +// NRF_SPIM0_NS->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos); +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// NRF_SPIS0_NS->EVENTS_END = 0; +// NRF_SPIS0_NS->EVENTS_ACQUIRED = 0; +// NRF_SPIS0_NS->INTENSET = SPIS_INTENSET_END_Msk | SPIS_INTENSET_ACQUIRED_Msk; +// NRF_SPIS0_NS->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos); +// #endif + +// return 0; +// } + +// /** +// * Disables the SPI. Used for power mgmt. It will halt any current SPI transfers +// * in progress. +// * +// * @param spi_num +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_disable(int spi_num) +// { +// struct nrf54h20_rad_hal_spi *spi = &nrf54h20_rad_hal_spi0; + +// if (spi_num != 0) { +// return -EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// NRF_SPIM0_NS->INTENCLR = NRF_SPI_IRQ_DISABLE_ALL; + +// if (spi->spi_xfr_flag) { +// hal_spi_master_stop_transfer(); +// spi->spi_xfr_flag = 0; +// } +// NRF_SPIM0_NS->ENABLE = 0; +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// NRF_SPIS0_NS->INTENCLR = NRF_SPI_IRQ_DISABLE_ALL; +// NRF_SPIS0_NS->EVENTS_END = 0; +// NRF_SPIS0_NS->EVENTS_ACQUIRED = 0; +// NRF_SPIS0_NS->ENABLE = 0; +// spi->slave_state = HAL_SPI_SLAVE_STATE_IDLE; +// #endif + +// spi->nhs_txbuf = NULL; +// spi->nhs_rxbuf = NULL; +// spi->nhs_buflen = 0; +// spi->nhs_bytes_txd = 0; + +// return 0; +// } + +// /** +// * Sets the txrx callback (executed at interrupt context) when the +// * buffer is transferred by the master or the slave using the non-blocking API. +// * Cannot be called when the spi is enabled. This callback will also be called +// * when chip select is de-asserted on the slave. +// * +// * NOTE: This callback is only used for the non-blocking interface and must +// * be called prior to using the non-blocking API. +// * +// * @param spi_num SPI interface on which to set callback +// * @param txrx Callback function +// * @param arg Argument to be passed to callback function +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_set_txrx_cb(int spi_num, hal_spi_txrx_cb txrx_cb, void *arg) +// { +// struct nrf54h20_rad_hal_spi *spi = &nrf54h20_rad_hal_spi0; + +// if (spi_num != 0) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (NRF_SPIM0_NS->ENABLE != 0) { +// return EINVAL; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// if (NRF_SPIS0_NS->ENABLE != 0) { +// return EINVAL; +// } +// #endif + +// spi->txrx_cb_func = txrx_cb; +// spi->txrx_cb_arg = arg; + +// return 0; +// } + +// /** +// * Non-blocking interface to send a buffer and store received values. Can be +// * used for both master and slave SPI types. The user must configure the +// * callback (using hal_spi_set_txrx_cb); the txrx callback is executed at +// * interrupt context when the buffer is sent. +// * +// * The transmit and receive buffers are either arrays of 8-bit (uint8_t) +// * values or 16-bit values depending on whether the spi is configured for 8 bit +// * data or more than 8 bits per value. The 'cnt' parameter is the number of +// * 8-bit or 16-bit values. Thus, if 'cnt' is 10, txbuf/rxbuf would point to an +// * array of size 10 (in bytes) if the SPI is using 8-bit data; otherwise +// * txbuf/rxbuf would point to an array of size 20 bytes (ten, uint16_t values). +// * +// * NOTE: these buffers are in the native endian-ness of the platform. +// * +// * MASTER: master sends all the values in the buffer and stores the +// * stores the values in the receive buffer if rxbuf is not NULL. +// * The txbuf parameter cannot be NULL +// * SLAVE: Slave "preloads" the data to be sent to the master (values +// * stored in txbuf) and places received data from master in rxbuf +// * (if not NULL). The txrx callback occurs when len values are +// * transferred or master de-asserts chip select. If txbuf is NULL, +// * the slave transfers its default byte. Both rxbuf and txbuf cannot +// * be NULL. +// * +// * @param spi_num SPI interface to use +// * @param txbuf Pointer to buffer where values to transmit are stored. +// * @param rxbuf Pointer to buffer to store values received from peer. +// * @param cnt Number of 8-bit or 16-bit values to be transferred. +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int len) +// { +// struct nrf54h20_rad_hal_spi *spi = &nrf54h20_rad_hal_spi0; + +// if (spi_num != 0 || (spi->txrx_cb_func == NULL) || (len == 0) || !nrfx_is_in_ram(txbuf)) { +// return EINVAL; +// } + +// if (rxbuf != NULL && !nrfx_is_in_ram(rxbuf)) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// /* Must have a txbuf for master! */ +// if (txbuf == NULL) { +// return EINVAL; +// } + +// /* Not allowed if transfer in progress */ +// if (spi->spi_xfr_flag) { +// return EBUSY; +// } + +// NRF_SPIM0_NS->INTENCLR = SPIM_INTENCLR_END_Msk; +// spi->spi_xfr_flag = 1; + +// /* Set internal data structure information */ +// spi->nhs_bytes_txd = 0; +// spi->nhs_buflen = len; +// spi->nhs_txbuf = txbuf; + +// len = min(SPIM_TXD_MAXCNT_MAX, len); + +// /* Set chip registers */ +// NRF_SPIM0_NS->TXD.PTR = (uint32_t)txbuf; +// NRF_SPIM0_NS->TXD.MAXCNT = len; + +// /* If no rxbuf, we need to set rxbuf and maxcnt to 1 */ +// spi->nhs_rxbuf = rxbuf; +// if (rxbuf == NULL) { +// NRF_SPIM0_NS->RXD.PTR = (uint32_t)&spi->dummy_rx; +// NRF_SPIM0_NS->RXD.MAXCNT = 1; +// } else { +// NRF_SPIM0_NS->RXD.PTR = (uint32_t)rxbuf; +// NRF_SPIM0_NS->RXD.MAXCNT = len; +// } + +// NRF_SPIM0_NS->EVENTS_END = 0; +// NRF_SPIM0_NS->EVENTS_STOPPED = 0; +// NRF_SPIM0_NS->TASKS_START = 1; +// NRF_SPIM0_NS->INTENSET = SPIM_INTENSET_END_Msk; +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// /* Must have txbuf or rxbuf */ +// if ((txbuf == NULL) && (rxbuf == NULL)) { +// return EINVAL; +// } + +// /* XXX: what to do here? */ +// if (len > 255) { +// return EINVAL; +// } + +// /* +// * Ready the slave for a transfer. Do not allow this to be called +// * if the slave has already been readied or is requesting the +// * semaphore +// */ +// if (spi->slave_state != HAL_SPI_SLAVE_STATE_IDLE) { +// return EBUSY; +// } + +// spi->nhs_rxbuf = rxbuf; +// spi->nhs_txbuf = txbuf; +// spi->nhs_buflen = len; +// spi->slave_state = HAL_SPI_SLAVE_STATE_ACQ_SEM; +// NRF_SPIS0_NS->TASKS_ACQUIRE = 1; +// #endif + +// return 0; +// } + +// /** +// * Sets the default value transferred by the slave. Not valid for master +// * +// * @param spi_num SPI interface to use +// * +// * @return int 0 on success, non-zero error code on failure. +// */ +// int +// hal_spi_slave_set_def_tx_val(int spi_num, uint16_t val) +// { +// #if MYNEWT_VAL(SPI_0_SLAVE) +// if (spi_num != 0){ +// return EINVAL; +// } + +// NRF_SPIS0_NS->DEF = (uint8_t)val; +// NRF_SPIS0_NS->ORC = (uint8_t)val; + +// return 0; +// #else +// return EINVAL; +// #endif +// } + +// /** +// * This aborts the current transfer but keeps the spi enabled. +// * +// * @param spi_num SPI interface on which transfer should be aborted. +// * +// * @return int 0 on success, non-zero error code on failure. +// * +// * NOTE: does not return an error if no transfer was in progress. +// */ +// int +// hal_spi_abort(int spi_num) +// { +// if (spi_num != 0) { +// return EINVAL; +// } + +// #if MYNEWT_VAL(SPI_0_MASTER) +// if (nrf54h20_rad_hal_spi0.spi_xfr_flag) { +// NRF_SPIM0_NS->INTENCLR = NRF_SPI_IRQ_DISABLE_ALL; +// hal_spi_master_stop_transfer(); +// nrf54h20_rad_hal_spi0.spi_xfr_flag = 0; +// NRF_SPIM0_NS->INTENSET = SPIM_INTENSET_END_Msk; +// } +// #endif + +// #if MYNEWT_VAL(SPI_0_SLAVE) +// /* Only way I can see doing this is to disable, then re-enable */ +// rc = hal_spi_disable(spi_num); +// if (rc) { +// return rc; +// } +// rc = hal_spi_enable(spi_num); +// if (rc) { +// return rc; +// } +// #endif + +// return 0; +// } + +// #endif diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_system.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_system.c new file mode 100644 index 0000000000..7155e5a0b0 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_system.c @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* stack limit provided by linker script */ +extern uint32_t __StackLimit[]; +extern int nrf54h20_rad_clock_grtc_init(void); + +void +hal_system_init(void) +{ + uint32_t rc; + + NVIC_Relocate(); + +// assert(nrf54h20_rad_clock_grtc_init() == 0); + + /* Setup Cortex-M33 stack limiter to detect stack overflow in interrupts and bootloader code */ + __set_MSPLIM((uint32_t)__StackLimit); +} + +void +hal_system_reset(void) +{ + #if MYNEWT_VAL(HAL_SYSTEM_RESET_CB) + hal_system_reset_cb(); + #endif + + while (1) { + HAL_DEBUG_BREAK(); + NVIC_SystemReset(); + } +} + +int +hal_debugger_connected(void) { + return CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk; +} + +/** + * hal system clock start + * + * Makes sure the LFCLK and/or HFCLK is started. + */ +void +hal_system_clock_start(void) +{ + /* 1. Start local RTC (radiocore only) + * 2. Get value of GRTC (available for both cores) + * 3. Get ticks difference between RTC and GRTC + * 4. Configure abstract timers over the Higher-Speed and High-Speed timers. + */ +} diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_system_start.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_system_start.c new file mode 100644 index 0000000000..457bb4f182 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_system_start.c @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +// +///** +// * Boots the image described by the supplied image header. +// * +// * @param hdr The header for the image to boot. +// */ +//void __attribute__((naked)) +//hal_system_start(void *img_start) +//{ +// uint32_t *img_data = img_start; +// +// asm volatile (".syntax unified \n" +// /* 1st word is stack pointer */ +// " msr msp, %0 \n" +// /* 2nd word is a reset handler (image entry) */ +// " bx %1 \n" +// : /* no output */ +// : "r" (img_data[0]), "r" (img_data[1])); +//} +// +///** +// * Boots the image described by the supplied image header. +// * This routine is used in split-app scenario when loader decides +// * that it wants to run the app instead. +// * +// * @param hdr The header for the image to boot. +// */ +//void +//hal_system_restart(void *img_start) +//{ +// int i; +// +// /* +// * NOTE: on reset, PRIMASK should have global interrupts enabled so +// * the code disables interrupts, clears the interrupt enable bits, +// * clears any pending interrupts, then enables global interrupts +// * so processor looks like state it would be in if it reset. +// */ +// __disable_irq(); +// for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) { +// NVIC->ICER[i] = 0xffffffff; +// } +// +// for (i = 0; i < sizeof(NVIC->ICPR) / sizeof(NVIC->ICPR[0]); i++) { +// NVIC->ICPR[i] = 0xffffffff; +// } +// __enable_irq(); +// +// hal_system_start(img_start); +//} diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_timer.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_timer.c new file mode 100644 index 0000000000..50b5b1280b --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_timer.c @@ -0,0 +1,900 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* IRQ prototype */ +typedef void (*hal_timer_irq_handler_t)(void); + +/* User CC 2 for reading counter, CC 3 for timer isr */ +#define NRF_TIMER_CC_READ (2) +#define NRF_TIMER_CC_INT (3) + +/* Output compare 2 used for RTC timers */ +#define NRF_RTC_TIMER_CC_INT (2) + +/* Maximum number of hal timers used */ +#define nrf54h20_hal_timer_MAX (5) + +/* Maximum timer frequency */ +#define NRF54H20_MAX_TIMER_FREQ (32000000) + +struct nrf54h20_hal_timer { + uint8_t tmr_enabled; + uint16_t tmr_irq_num; + uint8_t tmr_rtc; + uint8_t tmr_pad; + uint32_t tmr_cntr; + uint32_t timer_isrs; + uint32_t tmr_freq; + void *tmr_reg; + TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_q; +}; + +#if MYNEWT_VAL(TIMER_0) +struct nrf54h20_hal_timer nrf54h20_hal_timer0; +#endif +#if MYNEWT_VAL(TIMER_1) +struct nrf54h20_hal_timer nrf54h20_hal_timer1; +#endif +#if MYNEWT_VAL(TIMER_2) +struct nrf54h20_hal_timer nrf54h20_hal_timer2; +#endif +#if MYNEWT_VAL(TIMER_3) +struct nrf54h20_hal_timer nrf54h20_hal_timer3; +#endif +#if MYNEWT_VAL(TIMER_4) +struct nrf54h20_hal_timer nrf54h20_hal_timer4; +#endif + +static const struct nrf54h20_hal_timer *nrf54h20_hal_timers[nrf54h20_hal_timer_MAX] = { +#if MYNEWT_VAL(TIMER_0) + &nrf54h20_hal_timer0, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_1) + &nrf54h20_hal_timer1, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_2) + &nrf54h20_hal_timer2, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_3) + &nrf54h20_hal_timer3, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_4) + &nrf54h20_hal_timer4, +#else + NULL, +#endif +}; + +/* Resolve timer number into timer structure */ +#define nrf54h20_hal_timer_RESOLVE(__n, __v) \ + if ((__n) >= nrf54h20_hal_timer_MAX) { \ + rc = EINVAL; \ + goto err; \ + } \ + (__v) = (struct nrf54h20_hal_timer *) nrf54h20_hal_timers[(__n)]; \ + if ((__v) == NULL) { \ + rc = EINVAL; \ + goto err; \ + } + +/* Interrupt mask for interrupt enable/clear */ +#define NRF_TIMER_INT_MASK(x) ((1 << (uint32_t)(x)) << TIMER_INTENCLR_COMPARE0_Pos) + +static uint32_t +nrf_read_timer_cntr(NRF_TIMER_Type *hwtimer) +{ + uint32_t tcntr; + + /* Force a capture of the timer into 'cntr' capture channel; read it */ + hwtimer->TASKS_CAPTURE[NRF_TIMER_CC_READ] = 1; + tcntr = hwtimer->CC[NRF_TIMER_CC_READ]; + + return tcntr; +} + +/** + * Set the OCMP used by the timer to the desired expiration tick + * + * NOTE: Must be called with interrupts disabled. + * + * @param bsptimer Pointer to timer. + * @param expiry Expiration tick + */ +static void +nrf_timer_set_ocmp(struct nrf54h20_hal_timer *bsptimer, uint32_t expiry) +{ + int32_t delta_t; + uint32_t temp; + uint32_t cntr; + NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; + + if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + temp = bsptimer->tmr_cntr; + cntr = rtctimer->COUNTER; + if (rtctimer->EVENTS_OVRFLW) { + temp += (1UL << 24); + cntr = rtctimer->COUNTER; + } + temp |= cntr; + delta_t = (int32_t)(expiry - temp); + + /* + * The nRF5340 documentation states that COMPARE event is guaranteed + * only if value written to CC register is at least 2 greater than the + * current counter value. We also need to account for possible extra + * tick during calculations so effectively any delta less than 3 needs + * to be handled differently. TICK event is used to have interrupt on + * each subsequent tick so we won't miss any and in case we detected + * mentioned extra tick during calculations, interrupt is triggered + * immediately. Delta 0 or less means we should always fire immediately. + */ + if (delta_t < 1) { + rtctimer->INTENCLR = RTC_INTENCLR_TICK_Msk; + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } else if (delta_t < 3) { + rtctimer->INTENSET = RTC_INTENSET_TICK_Msk; + if (rtctimer->COUNTER != cntr) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + } else { + rtctimer->INTENCLR = RTC_INTENCLR_TICK_Msk; + + if (delta_t < (1UL << 24)) { + rtctimer->CC[NRF_RTC_TIMER_CC_INT] = expiry & 0x00ffffff; + } else { + /* CC too far ahead. Just make sure we set compare far ahead */ + rtctimer->CC[NRF_RTC_TIMER_CC_INT] = cntr + (1UL << 23); + } + rtctimer->INTENSET = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + } + } else { + hwtimer = bsptimer->tmr_reg; + + /* Disable ocmp interrupt and set new value */ + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + + /* Set output compare register to timer expiration */ + hwtimer->CC[NRF_TIMER_CC_INT] = expiry; + + /* Clear interrupt flag */ + hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0; + + /* Enable the output compare interrupt */ + hwtimer->INTENSET = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + + /* Force interrupt to occur as we may have missed it */ + if ((int32_t)(nrf_read_timer_cntr(hwtimer) - expiry) >= 0) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + } +} + +/* Disable output compare used for timer */ +static void +nrf_timer_disable_ocmp(NRF_TIMER_Type *hwtimer) +{ + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); +} + +static void +nrf_rtc_disable_ocmp(NRF_RTC_Type *rtctimer) +{ + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + rtctimer->INTENCLR = RTC_INTENCLR_TICK_Msk; +} + +static uint32_t +hal_timer_read_bsptimer(struct nrf54h20_hal_timer *bsptimer) +{ + uint32_t low32; + uint32_t ctx; + uint32_t tcntr; + NRF_RTC_Type *rtctimer; + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + __HAL_DISABLE_INTERRUPTS(ctx); + tcntr = bsptimer->tmr_cntr; + low32 = rtctimer->COUNTER; + if (rtctimer->EVENTS_OVRFLW) { + tcntr += (1UL << 24); + bsptimer->tmr_cntr = tcntr; + low32 = rtctimer->COUNTER; + rtctimer->EVENTS_OVRFLW = 0; + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + tcntr |= low32; + __HAL_ENABLE_INTERRUPTS(ctx); + + return tcntr; +} + +#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \ + MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4)) + +static void +hal_timer_chk_queue(struct nrf54h20_hal_timer *bsptimer) +{ + uint32_t tcntr; + uint32_t ctx; + struct hal_timer *timer; + + /* disable interrupts */ + __HAL_DISABLE_INTERRUPTS(ctx); + while ((timer = TAILQ_FIRST(&bsptimer->hal_timer_q)) != NULL) { + if (bsptimer->tmr_rtc) { + tcntr = hal_timer_read_bsptimer(bsptimer); + } else { + tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + } + if ((int32_t)(tcntr - timer->expiry) >= 0) { + TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link); + timer->link.tqe_prev = NULL; + timer->cb_func(timer->cb_arg); + } else { + break; + } + } + + /* Any timers left on queue? If so, we need to set OCMP */ + timer = TAILQ_FIRST(&bsptimer->hal_timer_q); + if (timer) { + nrf_timer_set_ocmp(bsptimer, timer->expiry); + } else { + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } + } + __HAL_ENABLE_INTERRUPTS(ctx); +} +#endif + +/** + * Generic HAL timer irq handler. + * + * @param bsptimer Pointer to timer. + */ +#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2)) +static void +hal_timer_irq_handler(struct nrf54h20_hal_timer *bsptimer) +{ + uint32_t compare; + NRF_TIMER_Type *hwtimer; + + os_trace_isr_enter(); + + /* Check interrupt source. If set, clear them */ + hwtimer = bsptimer->tmr_reg; + compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT]; + if (compare) { + hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0; + } + + /* Count # of timer isrs */ + ++bsptimer->timer_isrs; + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + if (hwtimer->INTENCLR & NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)) { + hal_timer_chk_queue(bsptimer); + /* XXX: Recommended by nordic to make sure interrupts are cleared */ + compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT]; + } + + os_trace_isr_exit(); +} +#endif + +/** + * Generic HAL RTC timer irq handler. + * + * @param bsptimer Pointer to timer. + */ +#if MYNEWT_VAL(TIMER_3) +static void +hal_rtc_timer_irq_handler(struct nrf54h20_hal_timer *bsptimer) +{ + uint32_t overflow; + uint32_t compare; + uint32_t tick; + NRF_RTC_Type *rtctimer; + + os_trace_isr_enter(); + + /* Check interrupt source. If set, clear them */ + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; + if (compare) { + rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT] = 0; + } + + tick = rtctimer->EVENTS_TICK; + if (tick) { + rtctimer->EVENTS_TICK = 0; + } + + overflow = rtctimer->EVENTS_OVRFLW; + if (overflow) { + rtctimer->EVENTS_OVRFLW = 0; + bsptimer->tmr_cntr += (1UL << 24); + } + + /* Count # of timer isrs */ + ++bsptimer->timer_isrs; + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + hal_timer_chk_queue(bsptimer); + + /* Recommended by nordic to make sure interrupts are cleared */ + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; + + os_trace_isr_exit(); +} +#endif + +#if MYNEWT_VAL(TIMER_0) +void +nrf54h20_timer0_irq_handler(void) +{ + hal_timer_irq_handler(&nrf54h20_hal_timer0); +} +#endif + +#if MYNEWT_VAL(TIMER_1) +void +nrf54h20_timer1_irq_handler(void) +{ + hal_timer_irq_handler(&nrf54h20_hal_timer1); +} +#endif + +#if MYNEWT_VAL(TIMER_2) +void +nrf54h20_timer2_irq_handler(void) +{ + hal_timer_irq_handler(&nrf54h20_hal_timer2); +} +#endif + +#if MYNEWT_VAL(TIMER_3) +void +nrf54h20_timer3_irq_handler(void) +{ + hal_rtc_timer_irq_handler(&nrf54h20_hal_timer3); +} +#endif + +#if MYNEWT_VAL(TIMER_4) +void +nrf54h20_timer4_irq_handler(void) +{ + hal_timer_irq_handler(&nrf54h20_hal_timer4); +} +#endif + +/** + * Initialize platform specific timer items + * + * @param timer_num Timer number to initialize + * @param cfg Pointer to platform specific configuration + * + * @return int 0: success; error code otherwise + */ +int +hal_timer_init(int timer_num, void *cfg) +{ + int rc; + uint16_t irq_num; + struct nrf54h20_hal_timer *bsptimer; + void *hwtimer; + hal_timer_irq_handler_t irq_isr; + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + + /* If timer is enabled do not allow init */ + if (bsptimer->tmr_enabled) { + rc = EINVAL; + goto err; + } + + switch (timer_num) { +#if MYNEWT_VAL(TIMER_0) + case 0: + irq_num = TIMER020_IRQn; + hwtimer = NRF_RADIOCORE_TIMER020_S; + irq_isr = nrf54h20_timer0_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_1) + case 1: + irq_num = TIMER021_IRQn; + hwtimer = NRF_RADIOCORE_TIMER021_S; + irq_isr = nrf54h20_timer1_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_2) + case 2: + irq_num = TIMER022_IRQn; + hwtimer = NRF_RADIOCORE_TIMER022_S; + irq_isr = nrf54h20_timer2_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_3) + case 3: + irq_num = RTC_IRQn; + hwtimer = NRF_RADIOCORE_RTC_S; + irq_isr = nrf54h20_timer3_irq_handler; + bsptimer->tmr_rtc = 1; + break; +#endif +#if MYNEWT_VAL(TIMER_4) + case 4: + irq_num = TIMER120_IRQn; + hwtimer = NRF_TIMER120_S; + irq_isr = nrf54h20_timer4_irq_handler; +// bsptimer->tmr_rtc = 1; + break; +#endif + default: + hwtimer = NULL; + break; + } + + if (hwtimer == NULL) { + rc = EINVAL; + goto err; + } + + bsptimer->tmr_reg = hwtimer; + bsptimer->tmr_irq_num = irq_num; + + /* Disable IRQ, set priority and set vector in table */ + NVIC_DisableIRQ(irq_num); + NVIC_SetPriority(irq_num, (1 << __NVIC_PRIO_BITS) - 1); + NVIC_SetVector(irq_num, (uint32_t)irq_isr); + + return 0; + +err: + return rc; +} + +/** + * Configure a timer to run at the desired frequency. This starts the timer. + * + * @param timer_num + * @param freq_hz + * + * @return int + */ +int +hal_timer_config(int timer_num, uint32_t freq_hz) +{ + int rc; + uint8_t prescaler; + uint32_t ctx; + uint32_t div; + uint32_t min_delta; + uint32_t max_delta; + struct nrf54h20_hal_timer *bsptimer; + NRF_TIMER_Type *hwtimer; +#if MYNEWT_VAL(TIMER_3) + NRF_RTC_Type *rtctimer; +#endif + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + +#if MYNEWT_VAL(TIMER_3) + if (timer_num == 3) { + /* NOTE: we only allow the RTC frequency to be set at 32768 */ + if (bsptimer->tmr_enabled || (freq_hz != 32768) || + (bsptimer->tmr_reg == NULL)) { + rc = EINVAL; + goto err; + } + + bsptimer->tmr_freq = freq_hz; + bsptimer->tmr_enabled = 1; + + __HAL_DISABLE_INTERRUPTS(ctx); + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + + /* Stop the timer first */ + rtctimer->TASKS_STOP = 1; + rtctimer->TASKS_CLEAR = 1; + + /* Always no prescaler */ + rtctimer->PRESCALER = 0; + + /* Clear overflow events and set overflow interrupt */ + rtctimer->EVENTS_OVRFLW = 0; + rtctimer->INTENSET = RTC_INTENSET_OVRFLW_Msk; + + /* Start the timer */ + rtctimer->TASKS_START = 1; + + /* Set isr in vector table and enable interrupt */ + NVIC_EnableIRQ(bsptimer->tmr_irq_num); + + __HAL_ENABLE_INTERRUPTS(ctx); + return 0; + } +#endif + + /* Set timer to desired frequency */ + div = NRF54H20_MAX_TIMER_FREQ / freq_hz; + + /* + * Largest prescaler is 2^9 and must make sure frequency not too high. + * If hwtimer is NULL it means that the timer was not initialized prior + * to call. + */ + if (bsptimer->tmr_enabled || (div == 0) || (div > 512) || + (bsptimer->tmr_reg == NULL)) { + rc = EINVAL; + goto err; + } + + if (div == 1) { + prescaler = 0; + } else { + /* Find closest prescaler */ + for (prescaler = 1; prescaler < 10; ++prescaler) { + if (div <= (1 << prescaler)) { + min_delta = div - (1 << (prescaler - 1)); + max_delta = (1 << prescaler) - div; + if (min_delta < max_delta) { + prescaler -= 1; + } + break; + } + } + } + + /* Now set the actual frequency */ + bsptimer->tmr_freq = NRF54H20_MAX_TIMER_FREQ / (1 << prescaler); + bsptimer->tmr_enabled = 1; + + /* disable interrupts */ + __HAL_DISABLE_INTERRUPTS(ctx); + + /* Make sure HFXO is started */ +// if ((NRF_CLOCK_S->HFCLKSTAT & +// (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) != +// (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) { +// NRF_CLOCK_S->EVENTS_HFCLKSTARTED = 0; +// NRF_CLOCK_S->TASKS_HFCLKSTART = 1; +// while (1) { +// if ((NRF_CLOCK_S->EVENTS_HFCLKSTARTED) != 0) { +// break; +// } +// } +// } + hwtimer = bsptimer->tmr_reg; + + /* Stop the timer first */ + hwtimer->TASKS_STOP = 1; + hwtimer->TASKS_CLEAR = 1; + + /* Put the timer in timer mode using 32 bits. */ + hwtimer->MODE = TIMER_MODE_MODE_Timer; + hwtimer->BITMODE = TIMER_BITMODE_BITMODE_32Bit; + + /* Set the pre-scalar */ + hwtimer->PRESCALER = prescaler; + + /* Start the timer */ + hwtimer->TASKS_START = 1; + + NVIC_EnableIRQ(bsptimer->tmr_irq_num); + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; + +err: + return rc; +} + +/** + * De-initialize a HW timer. + * + * @param timer_num + * + * @return int + */ +int +hal_timer_deinit(int timer_num) +{ + int rc; + uint32_t ctx; + struct nrf54h20_hal_timer *bsptimer; + NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; + + rc = 0; + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + + __HAL_DISABLE_INTERRUPTS(ctx); + if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + rtctimer->TASKS_STOP = 1; + } else { + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + hwtimer->TASKS_SHUTDOWN = 1; + } + bsptimer->tmr_enabled = 0; + bsptimer->tmr_reg = NULL; + __HAL_ENABLE_INTERRUPTS(ctx); + +err: + return rc; +} + +/** + * Get the resolution of the timer. This is the timer period, in nanoseconds + * + * @param timer_num + * + * @return uint32_t The + */ +uint32_t +hal_timer_get_resolution(int timer_num) +{ + int rc; + uint32_t resolution; + struct nrf54h20_hal_timer *bsptimer; + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + + resolution = 1000000000 / bsptimer->tmr_freq; + return resolution; + +err: + rc = 0; + return rc; +} + +/** + * Returns the timer counter. NOTE: if the timer is a 16-bit timer, only + * the lower 16 bits are valid. If the timer is a 64-bit timer, only the + * low 32-bits are returned. + * + * @return uint32_t The timer counter register. + */ +uint32_t +hal_timer_read(int timer_num) +{ + int rc; + uint32_t tcntr; + struct nrf54h20_hal_timer *bsptimer; + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + if (bsptimer->tmr_rtc) { + tcntr = hal_timer_read_bsptimer(bsptimer); + } else { + tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + } + + return tcntr; + + /* Assert here since there is no invalid return code */ +err: + assert(0); + rc = 0; + return rc; +} + +/** + * Blocking delay for n ticks + * + * @param timer_num + * @param ticks + * + * @return int 0 on success; error code otherwise. + */ +int +hal_timer_delay(int timer_num, uint32_t ticks) +{ + uint32_t until; + + until = hal_timer_read(timer_num) + ticks; + while ((int32_t)(hal_timer_read(timer_num) - until) <= 0) { + /* Loop here till finished */ + } + + return 0; +} + +/** + * Initialize the HAL timer structure with the callback and the callback + * argument. Also initializes the HW specific timer pointer. + * + * @param cb_func + * + * @return int + */ +int +hal_timer_set_cb(int timer_num, struct hal_timer *timer, hal_timer_cb cb_func, + void *arg) +{ + int rc; + struct nrf54h20_hal_timer *bsptimer; + + nrf54h20_hal_timer_RESOLVE(timer_num, bsptimer); + + timer->cb_func = cb_func; + timer->cb_arg = arg; + timer->link.tqe_prev = NULL; + timer->bsp_timer = bsptimer; + + rc = 0; + +err: + return rc; +} + +int +hal_timer_start(struct hal_timer *timer, uint32_t ticks) +{ + int rc; + uint32_t tick; + struct nrf54h20_hal_timer *bsptimer; + + /* Set the tick value at which the timer should expire */ + bsptimer = (struct nrf54h20_hal_timer *)timer->bsp_timer; + if (bsptimer->tmr_rtc) { + tick = hal_timer_read_bsptimer(bsptimer) + ticks; + } else { + tick = nrf_read_timer_cntr(bsptimer->tmr_reg) + ticks; + } + rc = hal_timer_start_at(timer, tick); + return rc; +} + +int +hal_timer_start_at(struct hal_timer *timer, uint32_t tick) +{ + uint32_t ctx; + struct hal_timer *entry; + struct nrf54h20_hal_timer *bsptimer; + + if ((timer == NULL) || (timer->link.tqe_prev != NULL) || + (timer->cb_func == NULL)) { + return EINVAL; + } + bsptimer = (struct nrf54h20_hal_timer *)timer->bsp_timer; + timer->expiry = tick; + + __HAL_DISABLE_INTERRUPTS(ctx); + + if (TAILQ_EMPTY(&bsptimer->hal_timer_q)) { + TAILQ_INSERT_HEAD(&bsptimer->hal_timer_q, timer, link); + } else { + TAILQ_FOREACH(entry, &bsptimer->hal_timer_q, link) { + if ((int32_t)(timer->expiry - entry->expiry) < 0) { + TAILQ_INSERT_BEFORE(entry, timer, link); + break; + } + } + if (!entry) { + TAILQ_INSERT_TAIL(&bsptimer->hal_timer_q, timer, link); + } + } + + /* If this is the head, we need to set new OCMP */ + if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) { + nrf_timer_set_ocmp(bsptimer, timer->expiry); + } + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} + +/** + * Stop a timer. + * + * @param timer + * + * @return int + */ +int +hal_timer_stop(struct hal_timer *timer) +{ + uint32_t ctx; + int reset_ocmp; + struct hal_timer *entry = NULL; + struct nrf54h20_hal_timer *bsptimer; + + if (timer == NULL) { + return EINVAL; + } + + bsptimer = (struct nrf54h20_hal_timer *)timer->bsp_timer; + + __HAL_DISABLE_INTERRUPTS(ctx); + + if (timer->link.tqe_prev != NULL) { + reset_ocmp = 0; + if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) { + /* If first on queue, we will need to reset OCMP */ + entry = TAILQ_NEXT(timer, link); + reset_ocmp = 1; + } + TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link); + timer->link.tqe_prev = NULL; + if (reset_ocmp) { + if (entry) { + nrf_timer_set_ocmp((struct nrf54h20_hal_timer *)entry->bsp_timer, + entry->expiry); + } else { + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } + } + } + } + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_uart.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_uart.c new file mode 100644 index 0000000000..995325a19e --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_uart.c @@ -0,0 +1,349 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +// #if MYNEWT_VAL(UART_0) +// #endif + +// #define UARTE_INT_ENDTX UARTE_INTEN_ENDTX_Msk +// #define UARTE_INT_ENDRX UARTE_INTEN_ENDRX_Msk +// #define UARTE_CONFIG_PARITY UARTE_CONFIG_PARITY_Msk +// #define UARTE_CONFIG_PARITY_ODD UARTE_CONFIG_PARITYTYPE_Msk +// #define UARTE_CONFIG_HWFC UARTE_CONFIG_HWFC_Msk +// #define UARTE_ENABLE UARTE_ENABLE_ENABLE_Enabled +// #define UARTE_DISABLE UARTE_ENABLE_ENABLE_Disabled + +// struct hal_uart { +// uint8_t u_open : 1; +// uint8_t u_rx_stall : 1; +// volatile uint8_t u_tx_started : 1; + +// uint8_t u_rx_buf; +// uint8_t u_tx_buf[8]; + +// hal_uart_rx_char u_rx_func; +// hal_uart_tx_char u_tx_func; +// hal_uart_tx_done u_tx_done; +// void *u_func_arg; +// }; + +// static struct hal_uart uart0; + +// int +// hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done, +// hal_uart_rx_char rx_func, void *arg) +// { +// if (port != 0 || uart0.u_open) { +// return -1; +// } + +// uart0.u_rx_func = rx_func; +// uart0.u_tx_func = tx_func; +// uart0.u_tx_done = tx_done; +// uart0.u_func_arg = arg; + +// return 0; +// } + +// static int +// hal_uart_tx_fill_buf(struct hal_uart *u) +// { +// int data; +// int i; + +// for (i = 0; i < sizeof(u->u_tx_buf); i++) { +// data = u->u_tx_func(u->u_func_arg); +// if (data < 0) { +// break; +// } +// u->u_tx_buf[i] = data; +// } +// return i; +// } + +// void +// hal_uart_start_tx(int port) +// { +// int sr; +// int rc; + +// if (port != 0) { +// return; +// } + +// __HAL_DISABLE_INTERRUPTS(sr); +// if (uart0.u_tx_started == 0) { +// rc = hal_uart_tx_fill_buf(&uart0); +// if (rc > 0) { +// NRF_UARTE0_NS->INTENSET = UARTE_INT_ENDTX; +// NRF_UARTE0_NS->TXD.PTR = (uint32_t)&uart0.u_tx_buf; +// NRF_UARTE0_NS->TXD.MAXCNT = rc; +// NRF_UARTE0_NS->TASKS_STARTTX = 1; +// uart0.u_tx_started = 1; +// } +// } +// __HAL_ENABLE_INTERRUPTS(sr); +// } + +// void +// hal_uart_start_rx(int port) +// { +// int sr; +// int rc; + +// if (port != 0) { +// return; +// } + +// if (uart0.u_rx_stall) { +// __HAL_DISABLE_INTERRUPTS(sr); +// rc = uart0.u_rx_func(uart0.u_func_arg, uart0.u_rx_buf); +// if (rc == 0) { +// uart0.u_rx_stall = 0; +// NRF_UARTE0_NS->TASKS_STARTRX = 1; +// } + +// __HAL_ENABLE_INTERRUPTS(sr); +// } +// } + +// void +// hal_uart_blocking_tx(int port, uint8_t data) +// { +// if (port != 0 || !uart0.u_open) { +// return; +// } + +// /* If we have started, wait until the current uart dma buffer is done */ +// if (uart0.u_tx_started) { +// while (NRF_UARTE0_NS->EVENTS_ENDTX == 0) { +// /* Wait here until the dma is finished */ +// } +// } + +// NRF_UARTE0_NS->EVENTS_ENDTX = 0; +// NRF_UARTE0_NS->TXD.PTR = (uint32_t)&data; +// NRF_UARTE0_NS->TXD.MAXCNT = 1; +// NRF_UARTE0_NS->TASKS_STARTTX = 1; + +// while (NRF_UARTE0_NS->EVENTS_ENDTX == 0) { +// /* Wait till done */ +// } + +// /* Stop the uart */ +// NRF_UARTE0_NS->TASKS_STOPTX = 1; +// } + +// static void +// uart0_irq_handler(void) +// { +// int rc; + +// os_trace_isr_enter(); + +// if (NRF_UARTE0_NS->EVENTS_ENDTX) { +// NRF_UARTE0_NS->EVENTS_ENDTX = 0; +// rc = hal_uart_tx_fill_buf(&uart0); +// if (rc > 0) { +// NRF_UARTE0_NS->TXD.PTR = (uint32_t)uart0.u_tx_buf; +// NRF_UARTE0_NS->TXD.MAXCNT = rc; +// NRF_UARTE0_NS->TASKS_STARTTX = 1; +// } else { +// if (uart0.u_tx_done) { +// uart0.u_tx_done(uart0.u_func_arg); +// } +// NRF_UARTE0_NS->INTENCLR = UARTE_INT_ENDTX; +// NRF_UARTE0_NS->TASKS_STOPTX = 1; +// uart0.u_tx_started = 0; +// } +// } +// if (NRF_UARTE0_NS->EVENTS_ENDRX) { +// NRF_UARTE0_NS->EVENTS_ENDRX = 0; +// rc = uart0.u_rx_func(uart0.u_func_arg, uart0.u_rx_buf); +// if (rc < 0) { +// uart0.u_rx_stall = 1; +// } else { +// NRF_UARTE0_NS->TASKS_STARTRX = 1; +// } +// } +// os_trace_isr_exit(); +// } + +// static uint32_t +// hal_uart_baudrate(int baudrate) +// { +// switch (baudrate) { +// case 1200: +// return UARTE_BAUDRATE_BAUDRATE_Baud1200; +// case 2400: +// return UARTE_BAUDRATE_BAUDRATE_Baud2400; +// case 4800: +// return UARTE_BAUDRATE_BAUDRATE_Baud4800; +// case 9600: +// return UARTE_BAUDRATE_BAUDRATE_Baud9600; +// case 14400: +// return UARTE_BAUDRATE_BAUDRATE_Baud14400; +// case 19200: +// return UARTE_BAUDRATE_BAUDRATE_Baud19200; +// case 28800: +// return UARTE_BAUDRATE_BAUDRATE_Baud28800; +// case 38400: +// return UARTE_BAUDRATE_BAUDRATE_Baud38400; +// case 56000: +// return UARTE_BAUDRATE_BAUDRATE_Baud56000; +// case 57600: +// return UARTE_BAUDRATE_BAUDRATE_Baud57600; +// case 76800: +// return UARTE_BAUDRATE_BAUDRATE_Baud76800; +// case 115200: +// return UARTE_BAUDRATE_BAUDRATE_Baud115200; +// case 230400: +// return UARTE_BAUDRATE_BAUDRATE_Baud230400; +// case 250000: +// return UARTE_BAUDRATE_BAUDRATE_Baud250000; +// case 460800: +// return UARTE_BAUDRATE_BAUDRATE_Baud460800; +// case 921600: +// return UARTE_BAUDRATE_BAUDRATE_Baud921600; +// case 1000000: +// return UARTE_BAUDRATE_BAUDRATE_Baud1M; +// default: +// return 0; +// } +// } + +// int +// hal_uart_init(int port, void *arg) +// { +// struct nrf54h20_rad_uart_cfg *cfg = arg; + +// if (port != 0) { +// return -1; +// } + +// NRF_UARTE0_NS->PSEL.TXD = cfg->suc_pin_tx; +// NRF_UARTE0_NS->PSEL.RXD = cfg->suc_pin_rx; +// NRF_UARTE0_NS->PSEL.RTS = cfg->suc_pin_rts; +// NRF_UARTE0_NS->PSEL.CTS = cfg->suc_pin_cts; + +// NVIC_SetVector(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, +// (uint32_t)uart0_irq_handler); + +// return 0; +// } + +// int +// hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits, +// enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) +// { +// uint32_t cfg_reg = 0; +// uint32_t baud_reg; + +// if (port != 0 || uart0.u_open) { +// return -1; +// } + +// /* +// * pin config +// * UART config +// * nvic config +// * enable uart +// */ +// if (databits != 8) { +// return -1; +// } +// if (stopbits != 1) { +// return -1; +// } + +// switch (parity) { +// case HAL_UART_PARITY_NONE: +// break; +// case HAL_UART_PARITY_ODD: +// cfg_reg |= UARTE_CONFIG_PARITY | UARTE_CONFIG_PARITY_ODD; +// break; +// case HAL_UART_PARITY_EVEN: +// cfg_reg |= UARTE_CONFIG_PARITY; +// break; +// } + +// switch (flow_ctl) { +// case HAL_UART_FLOW_CTL_NONE: +// break; +// case HAL_UART_FLOW_CTL_RTS_CTS: +// cfg_reg |= UARTE_CONFIG_HWFC; +// if (NRF_UARTE0_NS->PSEL.RTS == 0xffffffff || +// NRF_UARTE0_NS->PSEL.CTS == 0xffffffff) { +// /* +// * Can't turn on HW flow control if pins to do that are not +// * defined. +// */ +// assert(0); +// return -1; +// } +// break; +// } +// baud_reg = hal_uart_baudrate(baudrate); +// if (baud_reg == 0) { +// return -1; +// } +// NRF_UARTE0_NS->ENABLE = 0; +// NRF_UARTE0_NS->INTENCLR = 0xffffffff; +// NRF_UARTE0_NS->BAUDRATE = baud_reg; +// NRF_UARTE0_NS->CONFIG = cfg_reg; + +// NVIC_EnableIRQ(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); + +// NRF_UARTE0_NS->ENABLE = UARTE_ENABLE; + +// NRF_UARTE0_NS->INTENSET = UARTE_INT_ENDRX; +// NRF_UARTE0_NS->RXD.PTR = (uint32_t)&uart0.u_rx_buf; +// NRF_UARTE0_NS->RXD.MAXCNT = sizeof(uart0.u_rx_buf); +// NRF_UARTE0_NS->TASKS_STARTRX = 1; + +// uart0.u_rx_stall = 0; +// uart0.u_tx_started = 0; +// uart0.u_open = 1; + +// return 0; +// } + +// int +// hal_uart_close(int port) +// { +// if (port != 0) { +// return -1; +// } + +// uart0.u_open = 0; +// while (uart0.u_tx_started) { +// /* Wait here until the dma is finished */ +// } +// NRF_UARTE0_NS->ENABLE = 0; +// NRF_UARTE0_NS->INTENCLR = 0xffffffff; + +// return 0; +// } diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_vflash.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_vflash.c new file mode 100644 index 0000000000..e2b6686b71 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_vflash.c @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +// #if MCUBOOT_MYNEWT +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #if !MYNEWT_VAL(IPC_ICBMSG) +// #include +// #endif + +// #define NRF5340_NET_VFLASH_SECTOR_SZ 2048 + +// struct swap_data { +// uint32_t encryption_key0[4]; +// uint32_t encryption_key1[4]; +// uint32_t swap_size; +// struct image_trailer trailer; +// }; + +// static const struct swap_data swap_data_template = { +// .encryption_key0 = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, +// .encryption_key1 = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, +// .swap_size = 0xffffffff, +// .trailer = { +// .swap_type = BOOT_SWAP_TYPE_PERM, +// .pad1 = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, +// .copy_done = 0xff, +// .pad2 = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, +// .image_ok = 0x01, +// .pad3 = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, +// .magic = { 0x77, 0xc2, 0x95, 0xf3, 0x60, 0xd2, 0xef, 0x7f, +// 0x35, 0x52, 0x50, 0x0f, 0x2c, 0xb6, 0x79, 0x80 }, +// } +// }; + +// int +// nrf54h20_rad_get_image_hash(uint8_t area_id, uint8_t hash[32]) +// { +// const struct flash_area *fa = NULL; +// struct image_header header; +// uint32_t addr; +// uint32_t limit; +// struct image_tlv_info info; +// struct image_tlv tlv; +// int rc = -1; + +// if (flash_area_open(area_id, &fa) != 0) { +// goto end; +// } + +// /* Does slot contain valid image */ +// if (flash_area_read(fa, 0, &header, sizeof(header)) != 0 || +// header.ih_magic != IMAGE_MAGIC) { +// goto end; +// } + +// addr = header.ih_hdr_size + header.ih_img_size; +// /* Does image has TLV? (needed for image hash verification) */ +// if (flash_area_read(fa, addr, &info, sizeof(info)) != 0 || +// info.it_magic != IMAGE_TLV_INFO_MAGIC) { +// goto end; +// } + +// addr += sizeof(info); +// limit = addr + info.it_tlv_tot; +// while (addr + sizeof(tlv) + 32 <= limit) { +// if (flash_area_read(fa, addr, &tlv, sizeof(tlv)) != 0) { +// goto end; +// } +// addr += sizeof(tlv); +// if (tlv.it_type == IMAGE_TLV_SHA256) { +// if (tlv.it_len != 32) { +// goto end; +// } +// rc = flash_area_read(fa, addr, hash, 32); +// break; +// } +// addr += tlv.it_len; +// } +// end: +// if (fa) { +// flash_area_close(fa); +// } +// return rc; +// } + +// bool +// nrf54h20_rad_images_match(void) +// { +// uint8_t active_slot_hash[32]; +// uint8_t pending_slot_hash[32]; + +// if (nrf54h20_rad_get_image_hash(FLASH_AREA_IMAGE_0, active_slot_hash) == 0 && +// nrf54h20_rad_get_image_hash(FLASH_AREA_IMAGE_1, pending_slot_hash) == 0 && +// memcmp(pending_slot_hash, active_slot_hash, 32) == 0) { +// /* Same hash for current and pending slot, act as slot 2 was empty */ +// return true; +// } +// return false; +// } + +// static int +// nrf54h20_rad_vflash_read(const struct hal_flash *dev, uint32_t address, void *dst, +// uint32_t num_bytes) +// { +// struct nrf54h20_vflash *vflash = (struct nrf54h20_vflash *)dev; +// uint32_t write_bytes = num_bytes; +// uint8_t *wp = dst; +// const struct flash_area *fa; +// struct swap_data swap_data; + +// if ((vflash->nv_image_size > 0) && (vflash->nv_slot1 == NULL)) { +// flash_area_open(FLASH_AREA_IMAGE_1, &vflash->nv_slot1); + +// /* +// * If application side provided image check if same image was already +// * provided before and if so mark virtual slot as empty +// */ +// if (nrf54h20_rad_images_match()) { +// /* Same hash for current and pending slot, act as slot 2 was empty */ +// vflash->nv_image_size = 0; +// } +// } +// fa = vflash->nv_slot1; + +// /* Copy data from image */ +// if (address < vflash->nv_image_size) { +// if (address + write_bytes > vflash->nv_image_size) { +// write_bytes = vflash->nv_image_size - address; +// } +// memcpy(wp, vflash->nv_image_address + address, write_bytes); +// address += write_bytes; +// wp += write_bytes; +// num_bytes -= write_bytes; +// } +// /* Copy data from image trailer */ +// if (num_bytes > 0 && fa != NULL && address >= (fa->fa_off + fa->fa_size - sizeof(swap_data))) { +// swap_data = swap_data_template; +// uint32_t off = address - (fa->fa_off + fa->fa_size - sizeof(swap_data)); +// write_bytes = num_bytes; +// if (num_bytes > sizeof(swap_data) + off) { +// write_bytes = sizeof(swap_data) - off; +// } +// memcpy(wp, ((uint8_t *)&swap_data) + off, write_bytes); +// wp += write_bytes; +// address += write_bytes; +// num_bytes -= write_bytes; +// } +// /* Fill the rest with FF */ +// if (num_bytes > 0) { +// memset(wp, 0xff, num_bytes); +// } +// return 0; +// } + +// /* +// * Flash write is done by writing 4 bytes at a time at a word boundary. +// */ +// static int +// nrf54h20_rad_vflash_write(const struct hal_flash *dev, uint32_t address, +// const void *src, uint32_t num_bytes) +// { +// (void)dev; +// (void)address; +// (void)src; +// (void)num_bytes; + +// return 0; +// } + +// static int +// nrf54h20_rad_vflash_erase_sector(const struct hal_flash *dev, uint32_t sector_address) +// { +// (void)dev; +// (void)sector_address; + +// return 0; +// } + +// static int +// nrf54h20_rad_vflash_sector_info(const struct hal_flash *dev, int idx, +// uint32_t *address, uint32_t *sz) +// { +// (void)dev; + +// assert(idx < nrf54h20_flash_dev.hf_sector_cnt); +// *address = idx * NRF5340_NET_VFLASH_SECTOR_SZ; +// *sz = NRF5340_NET_VFLASH_SECTOR_SZ; + +// return 0; +// } + +// static int +// nrf54h20_rad_vflash_init(const struct hal_flash *dev) +// { +// struct nrf54h20_vflash *vflash = (struct nrf54h20_vflash *)dev; +// const void *img_addr; +// uint32_t image_size; + +// #if MYNEWT_VAL(IPC_ICBMSG) +// img_addr = 0; +// image_size = 0; +// #else +// img_addr = ipc_nrf54h20_rad_image_get(&image_size); +// #endif + +// /* +// * Application side IPC will set ipc_share data +// * (or GPMEM registers) to address and size of +// * memory where net core image is present in application flash. +// * If those values are 0, application image does not have embedded image, +// * and there no need to provide any data. +// * Set nv_image_size to 0 and all reads will return empty values (0xff) +// */ +// if (img_addr) { +// vflash->nv_image_address = img_addr; +// vflash->nv_image_size = image_size; +// } + +// return 0; +// } + +// static const struct hal_flash_funcs nrf54h20_rad_vflash_funcs = { +// .hff_read = nrf54h20_rad_vflash_read, +// .hff_write = nrf54h20_rad_vflash_write, +// .hff_erase_sector = nrf54h20_rad_vflash_erase_sector, +// .hff_sector_info = nrf54h20_rad_vflash_sector_info, +// .hff_init = nrf54h20_rad_vflash_init +// }; + +// struct nrf54h20_vflash nrf54h20_rad_vflash_dev = { +// .nv_flash = { +// .hf_itf = &nrf54h20_rad_vflash_funcs, +// .hf_base_addr = 0x00000000, +// .hf_size = 256 * 1024, +// .hf_sector_cnt = 128, +// .hf_align = 1, +// .hf_erased_val = 0xff, +// } +// }; + +// #endif diff --git a/hw/mcu/nordic/nrf54h20_rad/src/hal_watchdog.c b/hw/mcu/nordic/nrf54h20_rad/src/hal_watchdog.c new file mode 100644 index 0000000000..41b463f711 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/hal_watchdog.c @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include + +#define NRF_WDT NRF_RADIOCORE_WDT010_S +#define WDT_IRQn WDT010_IRQn + +static void +nrf54h20_rad_hal_wdt_default_handler(void) +{ + assert(0); +} + +/**@brief WDT interrupt handler. */ +static void +nrf54h20_rad_wdt_irq_handler(void) +{ + os_trace_isr_enter(); + if (NRF_WDT->INTENSET & WDT_INTENSET_TIMEOUT_Msk) { + NRF_WDT->EVENTS_TIMEOUT = 0; + nrf54h20_rad_hal_wdt_default_handler(); + } + os_trace_isr_exit(); +} + +int +hal_watchdog_init(uint32_t expire_msecs) +{ + uint64_t expiration; + + NRF_WDT->CONFIG = WDT_CONFIG_SLEEP_Msk; + + /* Convert msec timeout to counts of a 32768 crystal */ + expiration = ((uint64_t)expire_msecs * 32768) / 1000; + NRF_WDT->CRV = (uint32_t)expiration; + + NRF_WDT->CRV = (expire_msecs * 32) + ((expire_msecs * 96) / 125); + + NVIC_SetVector(WDT_IRQn, (uint32_t)nrf54h20_rad_wdt_irq_handler); + NVIC_SetPriority(WDT_IRQn, 0); + NVIC_ClearPendingIRQ(WDT_IRQn); + NVIC_EnableIRQ(WDT_IRQn); + NRF_WDT->RREN |= 0x1; + + return 0; +} + +void +hal_watchdog_enable(void) +{ +// NRF_WDT->INTENSET = WDT_INTENSET_TIMEOUT_Msk; +// NRF_WDT->TASKS_START = 1; +} + +void +hal_watchdog_tickle(void) +{ + NRF_WDT->RR[0] = WDT_RR_RR_Reload; +} + diff --git a/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_clock.c b/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_clock.c new file mode 100644 index 0000000000..db8c3238e8 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_clock.c @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include +#include +#include "mcu/nrf54h20_rad_hal.h" +#include +#include + +static uint8_t nrf54h20_rad_clock_hfxo_refcnt; + +/** + * Request HFXO clock be turned on. Note that each request must have a + * corresponding release. + * + * @return int 0: hfxo was already on. 1: hfxo was turned on. + */ +int +nrf54h20_rad_clock_hfxo_request(void) +{ + int started; + uint32_t ctx; + + // started = 0; + // __HAL_DISABLE_INTERRUPTS(ctx); + // assert(nrf54h20_rad_clock_hfxo_refcnt < 0xff); + // if (nrf54h20_rad_clock_hfxo_refcnt == 0) { + // NRF_CLOCK_NS->TASKS_HFCLKSTART = 1; + // started = 1; + // } + // ++nrf54h20_rad_clock_hfxo_refcnt; + // __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} + +/** + * Release the HFXO. This means that the caller no longer needs the HFXO to be + * turned on. Each call to release should have been preceeded by a corresponding + * call to request the HFXO + * + * + * @return int 0: HFXO not stopped by this call (others using it) 1: HFXO + * stopped. + */ +int +nrf54h20_rad_clock_hfxo_release(void) +{ + int stopped; + uint32_t ctx; + + // stopped = 0; + // __HAL_DISABLE_INTERRUPTS(ctx); + // assert(nrf54h20_rad_clock_hfxo_refcnt != 0); + // --nrf54h20_rad_clock_hfxo_refcnt; + // if (nrf54h20_rad_clock_hfxo_refcnt == 0) { + // NRF_CLOCK_NS->TASKS_HFCLKSTOP = 1; + // stopped = 1; + // } + // __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} + +static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context) { +} + +static uint32_t int_mask; +static nrfx_grtc_channel_t system_clock_channel_data = { + .handler = sys_clock_timeout_handler, + .p_context = NULL, + .channel = (uint8_t)-1, +}; + +int +nrf54h20_rad_clock_grtc_init(void) +{ + nrfx_err_t err_code; + + err_code = nrfx_grtc_init(0); + if (err_code != NRFX_SUCCESS) { + return -1; + } + +//#if defined(CONFIG_NRF_GRTC_START_SYSCOUNTER) +// err_code = nrfx_grtc_syscounter_start(true, &system_clock_channel_data.channel); +// if (err_code != NRFX_SUCCESS) { +// return err_code == NRFX_ERROR_NO_MEM ? -ENOMEM : -EPERM; +// } +//#else + err_code = nrfx_grtc_channel_alloc(&system_clock_channel_data.channel); + if (err_code != NRFX_SUCCESS) { + return -1; + } +//#endif /* CONFIG_NRF_GRTC_START_SYSCOUNTER */ + + int_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK; + + return 0; +} diff --git a/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_hw_id.c b/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_hw_id.c new file mode 100644 index 0000000000..1ff8a3a4b6 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_hw_id.c @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include + +// int +// hal_bsp_hw_id_len(void) +// { +// return sizeof(NRF_FICR_NS->INFO.DEVICEID); +// } + +// /* +// * These values are generated at random. +// * DEVICEID +// */ +// int +// hal_bsp_hw_id(uint8_t *id, int max_len) +// { +// max_len = min(sizeof(NRF_FICR_NS->INFO.DEVICEID), max_len); + +// memcpy(id, (void *)&NRF_FICR_NS->INFO.DEVICEID, max_len); + +// return max_len; +// } diff --git a/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_periph.c b/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_periph.c new file mode 100644 index 0000000000..1f96f0f6c2 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/nrf54h20_rad_periph.c @@ -0,0 +1,211 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "hal/hal_spi.h" + +#if MYNEWT_VAL(UART_0) +#include +#include +#endif + +#if MYNEWT_VAL(SPI_0_MASTER) +#include "bus/drivers/spi_hal.h" +#endif + +#if MYNEWT_VAL(I2C_0) +#include +#include +#endif + +#if MYNEWT_VAL(TRNG) +#include "trng/trng.h" +#include "trng_sw/trng_sw.h" +#endif + +#if MYNEWT_VAL(UART_0) +static struct uart_dev os_bsp_uart0; +static const struct nrf54h20_rad_uart_cfg os_bsp_uart0_cfg = { + .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX), + .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX), + .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS), + .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS), +}; +#endif + +#if MYNEWT_VAL(SPI_0_MASTER) +static const struct bus_spi_dev_cfg spi0_cfg = { + .spi_num = 0, + .pin_sck = MYNEWT_VAL(SPI_0_MASTER_PIN_SCK), + .pin_mosi = MYNEWT_VAL(SPI_0_MASTER_PIN_MOSI), + .pin_miso = MYNEWT_VAL(SPI_0_MASTER_PIN_MISO), +}; +static struct bus_spi_hal_dev spi0_bus; +#endif +#if MYNEWT_VAL(SPI_0_SLAVE) +static const struct nrf54h20_rad_hal_spi_cfg os_bsp_spi0s_cfg = { + .sck_pin = MYNEWT_VAL(SPI_0_SLAVE_PIN_SCK), + .mosi_pin = MYNEWT_VAL(SPI_0_SLAVE_PIN_MOSI), + .miso_pin = MYNEWT_VAL(SPI_0_SLAVE_PIN_MISO), + .ss_pin = MYNEWT_VAL(SPI_0_SLAVE_PIN_SS), +}; +#endif + +#if MYNEWT_VAL(I2C_0) +static const struct bus_i2c_dev_cfg i2c0_cfg = { + .i2c_num = 0, + .pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA), + .pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL), +}; +static struct bus_i2c_dev i2c0_bus; +#endif + +#if MYNEWT_VAL(TRNG) +//static struct trng_dev os_bsp_trng; +static struct trng_sw_dev os_bsp_trng; +static int32_t mypid; +static struct trng_sw_dev_cfg os_bsp_trng_cfg = { + .tsdc_entr = &mypid, + .tsdc_len = sizeof(mypid) +}; +#endif + +static void +nrf54h20_rad_periph_create_timers(void) +{ + int rc; + + (void)rc; + +#if MYNEWT_VAL(TIMER_0) + rc = hal_timer_init(0, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_1) + rc = hal_timer_init(1, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_2) + rc = hal_timer_init(2, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_3) + rc = hal_timer_init(3, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_4) + rc = hal_timer_init(4, NULL); + assert(rc == 0); +#endif + +#if MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0 + rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ)); + assert(rc == 0); +#endif +} + +static void +nrf54h20_rad_periph_create_uart(void) +{ +#if MYNEWT_VAL(UART_0) + int rc; + + rc = os_dev_create(&os_bsp_uart0.ud_dev, "uart0", + OS_DEV_INIT_PRIMARY, 0, uart_hal_init, + (void *)&os_bsp_uart0_cfg); + assert(rc == 0); +#endif +} + +static void +nrf54h20_rad_periph_create_spi(void) +{ + int rc; + + (void)rc; + +#if MYNEWT_VAL(SPI_0_MASTER) + rc = bus_spi_hal_dev_create("spi0", + &spi0_bus, (struct bus_spi_dev_cfg *)&spi0_cfg); + assert(rc == 0); +#endif +#if MYNEWT_VAL(SPI_0_SLAVE) + rc = hal_spi_init(0, (void *)&os_bsp_spi0s_cfg, HAL_SPI_TYPE_SLAVE); + assert(rc == 0); +#endif +} + +static void +nrf54h20_rad_periph_create_i2c(void) +{ +#if MYNEWT_VAL(I2C_0) + int rc; + + rc = bus_i2c_nrf54h20_dev_create("i2c0", &i2c0_bus, + (struct bus_i2c_dev_cfg *)&i2c0_cfg); + assert(rc == 0); +#endif +} + +void +hal_bsp_init_trng(void) +{ + int i; + int rc; + + /* + * Add entropy (don't do it like this if you use this for real, use + * something proper). + */ + for (i = 0; i < 8; i++) { + rc = trng_sw_dev_add_entropy(&os_bsp_trng, &mypid, sizeof(mypid)); + assert(rc == 0); + } +} + +static void +nrf54h20_rad_periph_create_trng(void) +{ + int rc; + + (void)rc; + +#if MYNEWT_VAL(TRNG) + mypid = 123; + rc = os_dev_create((struct os_dev *)&os_bsp_trng, "trng", + OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT, + trng_sw_dev_init, &os_bsp_trng_cfg); + assert(rc == 0); +#endif +} + +void +nrf54h20_rad_periph_create(void) +{ + nrf54h20_rad_periph_create_timers(); + // nrf54h20_rad_periph_create_uart(); + // nrf54h20_rad_periph_create_spi(); + // nrf54h20_rad_periph_create_i2c(); + nrf54h20_rad_periph_create_trng(); +} diff --git a/hw/mcu/nordic/nrf54h20_rad/src/system_nrf54h20_rad.c b/hw/mcu/nordic/nrf54h20_rad/src/system_nrf54h20_rad.c new file mode 100644 index 0000000000..6eb71bd30a --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/src/system_nrf54h20_rad.c @@ -0,0 +1,122 @@ +/* + +Copyright (c) 2009-2024 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the License); you may +not use this file except in compliance with the License. +You may obtain a copy of the License at + + www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an AS IS BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +/* NOTE: Template files (including this one) are application specific and therefore expected to + be copied into the application project folder prior to its use! */ + +#include +#include +#include "nrf.h" +#include "system_nrf54h.h" +#include "system_config_sau.h" + +/*lint ++flb "Enter library region" */ + +#define __SYSTEM_CLOCK_MHZ (1000000UL) +#if defined(NRF_PPR) +#define __SYSTEM_CLOCK_DEFAULT (16ul * __SYSTEM_CLOCK_MHZ) +#elif defined(NRF_RADIOCORE) +#define __SYSTEM_CLOCK_DEFAULT (256ul * __SYSTEM_CLOCK_MHZ) +#else +#define __SYSTEM_CLOCK_DEFAULT (320ul * __SYSTEM_CLOCK_MHZ) +#endif + +#if defined ( __CC_ARM ) || defined ( __GNUC__ ) +uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_DEFAULT; +#elif defined ( __ICCARM__ ) +__root uint32_t SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; +#endif + +void SystemCoreClockUpdate(void) +{ +#if defined(NRF_PPR) + /* PPR clock is always 16MHz */ + SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; +#elif defined(NRF_FLPR) + /* FLPR does not have access to its HSFLL, assume default speed. */ + SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; +#else +#if !defined(NRF_SKIP_CORECLOCKDETECT) && !defined(NRF_TRUSTZONE_NONSECURE) + + /* CPU should have access to its local HSFLL, measure CPU frequency. */ + /* If HSFLL is in closed loop mode it's always measuring, and we can just pick the result.*/ + /* Otherwise, start a frequncy measurement.*/ + if ((NRF_HSFLL->CLOCKSTATUS & HSFLL_CLOCKSTATUS_MODE_Msk) != HSFLL_CLOCKSTATUS_MODE_ClosedLoop) + { + /* Start HSFLL frequency measurement */ + NRF_HSFLL->EVENTS_FREQMDONE = 0ul; + NRF_HSFLL->TASKS_FREQMEAS = 1ul; + for (volatile uint32_t i = 0ul; i < 200ul && NRF_HSFLL->EVENTS_FREQMDONE != 1ul; i++) + { + /* Wait until frequency measurement is done */ + } + + if (NRF_HSFLL->EVENTS_FREQMDONE != 1ul) + { + /* Clock measurement never completed, return default CPU clock speed */ + SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; + return; + } + } + + /* Frequency measurement result is a multiple of 16MHz */ + SystemCoreClock = NRF_HSFLL->FREQM.MEAS * 16ul * __SYSTEM_CLOCK_MHZ; +#else + SystemCoreClock = __SYSTEM_CLOCK_DEFAULT; +#endif +#endif +} + +void SystemInit(void) +{ +#ifdef __CORTEX_M + #if !defined(NRF_TRUSTZONE_NONSECURE) && defined(__ARM_FEATURE_CMSE) + #if defined(__FPU_PRESENT) && __FPU_PRESENT + /* Allow Non-Secure code to run FPU instructions. + * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */ + SCB->NSACR |= (3UL << 10ul); + #endif + #ifndef NRF_SKIP_SAU_CONFIGURATION + configure_default_sau(); + #endif + #endif + + /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the + * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit + * operations are not used in your code. */ + #if (__FPU_USED == 1) + SCB->CPACR |= (3UL << 20ul) | (3UL << 22ul); + __DSB(); + __ISB(); + #endif +#endif + +#if defined(NFCT_PRESENT) + #if defined(NRF_CONFIG_NFCT_PINS_AS_GPIOS) + NRF_NFCT->PADCONFIG = NFCT_PADCONFIG_ENABLE_Disabled << NFCT_PADCONFIG_ENABLE_Pos; + #else + NRF_NFCT->PADCONFIG = NFCT_PADCONFIG_ENABLE_Enabled << NFCT_PADCONFIG_ENABLE_Pos; + #endif +#endif +} + +/*lint --flb "Leave library region" */ diff --git a/hw/mcu/nordic/nrf54h20_rad/startup/pkg.yml b/hw/mcu/nordic/nrf54h20_rad/startup/pkg.yml new file mode 100644 index 0000000000..674690cb9f --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/startup/pkg.yml @@ -0,0 +1,25 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/mcu/nordic/nrf54h20_rad/startup +pkg.description: MCU default startup code +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - nrf54h20 diff --git a/hw/mcu/nordic/nrf54h20_rad/startup/src/arch/cortex_m33/gcc_startup_nrf54h20_rad.s b/hw/mcu/nordic/nrf54h20_rad/startup/src/arch/cortex_m33/gcc_startup_nrf54h20_rad.s new file mode 100644 index 0000000000..67f920b126 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/startup/src/arch/cortex_m33/gcc_startup_nrf54h20_rad.s @@ -0,0 +1,862 @@ +/* + +Copyright (c) 2009-2024 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the License); you may +not use this file except in compliance with the License. +You may obtain a copy of the License at + + www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an AS IS BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +#include "syscfg/syscfg.h" + + .syntax unified + .arch armv8-m.main + +#if MYNEWT_VAL(MAIN_STACK_SIZE) +#define __STACK_SIZE MYNEWT_VAL(MAIN_STACK_SIZE) +#endif +#ifndef __STARTUP_FILL_MAIN_STACK +#define __STARTUP_FILL_MAIN_STACK 1 +#endif +#define __HEAP_SIZE 0 +#define __STARTUP_CLEAR_BSS + +#ifdef __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif +#endif + + .section .stack +#if defined(__STARTUP_CONFIG) + .align __STARTUP_CONFIG_STACK_ALIGNEMENT + .equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE +#elif defined(__STACK_SIZE) + .align 3 + .equ Stack_Size, __STACK_SIZE +#else + .align 3 + .equ Stack_Size, 8192 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#if defined(__STARTUP_CONFIG) + .equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE +#elif defined(__HEAP_SIZE) + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 8192 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector, "ax" + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler + .long NMI_Handler + .long HardFault_Handler + .long MemoryManagement_Handler + .long BusFault_Handler + .long UsageFault_Handler + .long SecureFault_Handler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SVC_Handler + .long DebugMon_Handler + .long 0 /*Reserved */ + .long PendSV_Handler + .long SysTick_Handler + + /* External Interrupts */ + .long SPU000_IRQHandler + .long MPC_IRQHandler + .long CPUC_IRQHandler + .long MVDMA_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SPU010_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long WDT010_IRQHandler + .long WDT011_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SPU020_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long EGU020_IRQHandler + .long 0 /*Reserved */ + .long GPIOTE_0_IRQHandler + .long TIMER020_IRQHandler + .long TIMER021_IRQHandler + .long TIMER022_IRQHandler + .long RTC_IRQHandler + .long RADIO_0_IRQHandler + .long RADIO_1_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SPU030_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long VPR_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long AAR030_CCM030_IRQHandler + .long ECB030_IRQHandler + .long AAR031_CCM031_IRQHandler + .long ECB031_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long IPCT_0_IRQHandler + .long IPCT_1_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SWI0_IRQHandler + .long SWI1_IRQHandler + .long SWI2_IRQHandler + .long SWI3_IRQHandler + .long SWI4_IRQHandler + .long SWI5_IRQHandler + .long SWI6_IRQHandler + .long SWI7_IRQHandler + .long BELLBOARD_0_IRQHandler + .long BELLBOARD_1_IRQHandler + .long BELLBOARD_2_IRQHandler + .long BELLBOARD_3_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long GPIOTE130_0_IRQHandler + .long GPIOTE130_1_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long GRTC_0_IRQHandler + .long GRTC_1_IRQHandler + .long GRTC_2_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TBM_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long USBHS_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long EXMIF_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long IPCT120_0_IRQHandler + .long 0 /*Reserved */ + .long I3C120_IRQHandler + .long VPR121_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long CAN120_IRQHandler + .long MVDMA120_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long I3C121_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER120_IRQHandler + .long TIMER121_IRQHandler + .long PWM120_IRQHandler + .long SPIS120_IRQHandler + .long SPIM120_UARTE120_IRQHandler + .long SPIM121_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long VPR130_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long IPCT130_0_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long RTC130_IRQHandler + .long RTC131_IRQHandler + .long 0 /*Reserved */ + .long WDT131_IRQHandler + .long WDT132_IRQHandler + .long EGU130_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SAADC_IRQHandler + .long COMP_LPCOMP_IRQHandler + .long TEMP_IRQHandler + .long NFCT_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TDM130_IRQHandler + .long PDM_IRQHandler + .long QDEC130_IRQHandler + .long QDEC131_IRQHandler + .long 0 /*Reserved */ + .long TDM131_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER130_IRQHandler + .long TIMER131_IRQHandler + .long PWM130_IRQHandler + .long SERIAL0_IRQHandler + .long SERIAL1_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER132_IRQHandler + .long TIMER133_IRQHandler + .long PWM131_IRQHandler + .long SERIAL2_IRQHandler + .long SERIAL3_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER134_IRQHandler + .long TIMER135_IRQHandler + .long PWM132_IRQHandler + .long SERIAL4_IRQHandler + .long SERIAL5_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long TIMER136_IRQHandler + .long TIMER137_IRQHandler + .long PWM133_IRQHandler + .long SERIAL6_IRQHandler + .long SERIAL7_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + + .size __isr_vector, . - __isr_vector + +/* Reset Handler */ + + + .text + .thumb + .thumb_func + .align 1 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + + +/* Loop to copy data from read only memory to RAM. + * The ranges of copy from/to are specified by following symbols: + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to. + * __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ + * the user can add their own initialized data section before BSS section with the INTERT AFTER command. + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__bss_start__ + + subs r3, r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: + +/* This part of work usually is done in C library startup code. Otherwise, + * define __STARTUP_CLEAR_BSS to enable it in this startup. This section + * clears the RAM where BSS data is located. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * All addresses must be aligned to 4 bytes boundary. + */ +#ifdef __STARTUP_CLEAR_BSS + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, r2, #4 + str r0, [r1, r2] + bgt .L_loop3 + +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS */ + +#if __STARTUP_FILL_MAIN_STACK + ldr r2, =0xdeadbeef + ldr r0, =__StackLimit + mov r1, sp +0: cmp r1, r0 + str r2, [r1,#-4]! + bge 0b +1: +#endif + + LDR R0, =__HeapBase + LDR R1, =__HeapLimit + BL _sbrkInit + +/* Execute SystemInit function. */ + bl SystemInit + +/* Execute hal_system_init */ + bl hal_system_init + +/* Call _start function provided by libraries. + * If those libraries are not accessible, define __START as your entry point. + */ +#ifndef __START +#define __START _start +#endif + bl __START + + .pool + .size Reset_Handler,.-Reset_Handler + + .section ".text" + + +/* Dummy Exception Handlers (infinite loops which can be modified) */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + .size NMI_Handler, . - NMI_Handler + + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + b . + .size HardFault_Handler, . - HardFault_Handler + + + .weak MemoryManagement_Handler + .type MemoryManagement_Handler, %function +MemoryManagement_Handler: + b . + .size MemoryManagement_Handler, . - MemoryManagement_Handler + + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + .size BusFault_Handler, . - BusFault_Handler + + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + .size UsageFault_Handler, . - UsageFault_Handler + + + .weak SecureFault_Handler + .type SecureFault_Handler, %function +SecureFault_Handler: + b . + .size SecureFault_Handler, . - SecureFault_Handler + + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + b . + .size SVC_Handler, . - SVC_Handler + + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + .size DebugMon_Handler, . - DebugMon_Handler + + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + .size PendSV_Handler, . - PendSV_Handler + + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + .size SysTick_Handler, . - SysTick_Handler + + +/* IRQ Handlers */ + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ SPU000_IRQHandler + IRQ MPC_IRQHandler + IRQ CPUC_IRQHandler + IRQ MVDMA_IRQHandler + IRQ SPU010_IRQHandler + IRQ WDT010_IRQHandler + IRQ WDT011_IRQHandler + IRQ SPU020_IRQHandler + IRQ EGU020_IRQHandler + IRQ GPIOTE_0_IRQHandler + IRQ TIMER020_IRQHandler + IRQ TIMER021_IRQHandler + IRQ TIMER022_IRQHandler + IRQ RTC_IRQHandler + IRQ RADIO_0_IRQHandler + IRQ RADIO_1_IRQHandler + IRQ SPU030_IRQHandler + IRQ VPR_IRQHandler + IRQ AAR030_CCM030_IRQHandler + IRQ ECB030_IRQHandler + IRQ AAR031_CCM031_IRQHandler + IRQ ECB031_IRQHandler + IRQ IPCT_0_IRQHandler + IRQ IPCT_1_IRQHandler + IRQ SWI0_IRQHandler + IRQ SWI1_IRQHandler + IRQ SWI2_IRQHandler + IRQ SWI3_IRQHandler + IRQ SWI4_IRQHandler + IRQ SWI5_IRQHandler + IRQ SWI6_IRQHandler + IRQ SWI7_IRQHandler + IRQ BELLBOARD_0_IRQHandler + IRQ BELLBOARD_1_IRQHandler + IRQ BELLBOARD_2_IRQHandler + IRQ BELLBOARD_3_IRQHandler + IRQ GPIOTE130_0_IRQHandler + IRQ GPIOTE130_1_IRQHandler + IRQ GRTC_0_IRQHandler + IRQ GRTC_1_IRQHandler + IRQ GRTC_2_IRQHandler + IRQ TBM_IRQHandler + IRQ USBHS_IRQHandler + IRQ EXMIF_IRQHandler + IRQ IPCT120_0_IRQHandler + IRQ I3C120_IRQHandler + IRQ VPR121_IRQHandler + IRQ CAN120_IRQHandler + IRQ MVDMA120_IRQHandler + IRQ I3C121_IRQHandler + IRQ TIMER120_IRQHandler + IRQ TIMER121_IRQHandler + IRQ PWM120_IRQHandler + IRQ SPIS120_IRQHandler + IRQ SPIM120_UARTE120_IRQHandler + IRQ SPIM121_IRQHandler + IRQ VPR130_IRQHandler + IRQ IPCT130_0_IRQHandler + IRQ RTC130_IRQHandler + IRQ RTC131_IRQHandler + IRQ WDT131_IRQHandler + IRQ WDT132_IRQHandler + IRQ EGU130_IRQHandler + IRQ SAADC_IRQHandler + IRQ COMP_LPCOMP_IRQHandler + IRQ TEMP_IRQHandler + IRQ NFCT_IRQHandler + IRQ TDM130_IRQHandler + IRQ PDM_IRQHandler + IRQ QDEC130_IRQHandler + IRQ QDEC131_IRQHandler + IRQ TDM131_IRQHandler + IRQ TIMER130_IRQHandler + IRQ TIMER131_IRQHandler + IRQ PWM130_IRQHandler + IRQ SERIAL0_IRQHandler + IRQ SERIAL1_IRQHandler + IRQ TIMER132_IRQHandler + IRQ TIMER133_IRQHandler + IRQ PWM131_IRQHandler + IRQ SERIAL2_IRQHandler + IRQ SERIAL3_IRQHandler + IRQ TIMER134_IRQHandler + IRQ TIMER135_IRQHandler + IRQ PWM132_IRQHandler + IRQ SERIAL4_IRQHandler + IRQ SERIAL5_IRQHandler + IRQ TIMER136_IRQHandler + IRQ TIMER137_IRQHandler + IRQ PWM133_IRQHandler + IRQ SERIAL6_IRQHandler + IRQ SERIAL7_IRQHandler + + .end diff --git a/hw/mcu/nordic/nrf54h20_rad/startup/syscfg.yml b/hw/mcu/nordic/nrf54h20_rad/startup/syscfg.yml new file mode 100644 index 0000000000..d2923e3594 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/startup/syscfg.yml @@ -0,0 +1,29 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + MAIN_STACK_SIZE: + description: > + Stack size (in bytes) to use in startup code. + For bootloader it's main stack, for application this stack is used by interrupts + and exceptions. + value: 768 + +syscfg.vals.BOOT_LOADER: + # MCUboot code uses a lot of stack + MAIN_STACK_SIZE: 1024 diff --git a/hw/mcu/nordic/nrf54h20_rad/syscfg.yml b/hw/mcu/nordic/nrf54h20_rad/syscfg.yml new file mode 100644 index 0000000000..c6c4fd1363 --- /dev/null +++ b/hw/mcu/nordic/nrf54h20_rad/syscfg.yml @@ -0,0 +1,162 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.defs: + MCU_TARGET: + description: > + Specifies target MCU. + value: nRF54H20_RAD + restrictions: + - $notnull + choices: + - nRF54H20_RAD + MCU_NET_CORE: + description: > + Constant value always set to 1. It allows to have common + packages for network and application core that do have + some differences depending on which core they are build for. + value: 1 + restrictions: !MCU_APP_CORE + MCU_FLASH_MIN_WRITE_SIZE: + description: > + Specifies the required alignment for internal flash writes. + Used internally by the newt tool. + value: 1 + + MCU_LFCLK_SOURCE: + description: > + Selected source for low frequency clock (LFCLK). + value: + restrictions: + - '!BLE_CONTROLLER || (MCU_LFCLK_SOURCE != "LFRC")' + choices: + - LFRC # 32.768 kHz RC oscillator + - LFXO # 32.768 kHz crystal oscillator + - LFSYNTH # 32.768 kHz synthesized from HFCLK + + MCU_GPIO_USE_PORT_EVENT: + description: > + When enabled, hal_gpio will use GPIOTE PORT event instead of PIN + events for interrupts. This mode may be less accurate (i.e. pulse + length needs to be longer in order to be detected) but it reduces + power consumption since it does not require HFCLK to be running. + Refer to nRF54H20 Product Specification document for more details. + value: 0 + + MCU_DEBUG_IGNORE_BKPT: + description: > + When enabled, asm(bkpt) will be ignored. If not set, it will hit + the breakpoint wherever it gets called, For example, reset and crash + value: 0 + + MCU_ICACHE_ENABLED: + description: > + Enable instruction code cache + value: 1 + + MCU_DEFAULT_STARTUP: + description: > + Include default startup code. + Set to 0 if BSP provides customized startup code. + value: 1 + +# MCU peripherals definitions + TRNG: + description: 'Enable nRF54H20 TRNG' + value: 1 + + UART_0: + description: 'Enable nRF54H20 net UART0' + value: 0 + restrictions: + - "!SPI_0_MASTER" + - "!SPI_0_SLAVE" + UART_0_PIN_TX: + description: 'TX pin for UART0' + value: '' + UART_0_PIN_RX: + description: 'RX pin for UART0' + value: '' + UART_0_PIN_RTS: + description: 'RTS pin for UART0' + value: -1 + UART_0_PIN_CTS: + description: 'CTS pin for UART0' + value: -1 + + TIMER_0: + description: 'Enable nRF54H20 Net Timer 0' + value: 1 + TIMER_1: + description: 'Enable nRF54H20 Net Timer 1' + value: 0 + TIMER_2: + description: 'Enable nRF54H20 Net Timer 2' + value: 0 + TIMER_3: + description: 'Enable nRF54H20 Net RTC 0' + value: 0 + TIMER_4: + description: 'Enable nRF54H20 Net RTC 1' + value: 0 + + GPIO_AS_PIN_RESET: + description: 'Enable pin reset' + value: 0 + + SPI_0_MASTER: + description: 'Enable nRF54H20 SPI Master 0' + value: 0 + restrictions: + - "!SPI_0_SLAVE" + - "!UART_0" + SPI_0_MASTER_PIN_SCK: + description: 'SCK pin for SPI_0_MASTER' + value: '' + SPI_0_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_0_MASTER' + value: '' + SPI_0_MASTER_PIN_MISO: + description: 'MISO pin for SPI_0_MASTER' + value: '' + + SPI_0_SLAVE: + description: 'Enable nRF54H20 SPI Slave 0' + value: 0 + restrictions: + - "!SPI_0_MASTER" + - "!UART_0" + - "!I2C_0" + SPI_0_SLAVE_PIN_SCK: + description: 'SCK pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_MOSI: + description: 'MOSI pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_MISO: + description: 'MISO pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_SS: + description: 'SS pin for SPI_0_SLAVE' + value: '' + +syscfg.vals: + OS_TICKS_PER_SEC: 128 + +syscfg.restrictions: + - "!UART_0 || (UART_0_PIN_TX && UART_0_PIN_RX)" diff --git a/hw/mcu/nordic/nrf_common/src/hal_gpio.c b/hw/mcu/nordic/nrf_common/src/hal_gpio.c index dc4f6acf35..d63f20b727 100644 --- a/hw/mcu/nordic/nrf_common/src/hal_gpio.c +++ b/hw/mcu/nordic/nrf_common/src/hal_gpio.c @@ -39,6 +39,16 @@ #define GPIOTE_IRQn GPIOTE0_IRQn #endif +#if defined(NRF54H20_XXAA) +#if defined(NRF_RADIOCORE) +#define GPIOTE_IRQn GPIOTE_0_IRQn +#endif +#if defined(NRF_APPLICATION) +#define GPIOTE_IRQn GPIOTE130_0_IRQn +#define NRF_GPIOTE0 NRF_GPIOTE130 +#endif +#endif + /* Storage for GPIO callbacks. */ struct hal_gpio_irq { hal_gpio_irq_handler_t func; diff --git a/hw/mcu/nordic/pkg.yml b/hw/mcu/nordic/pkg.yml index a18bc0a2c8..8e61360524 100644 --- a/hw/mcu/nordic/pkg.yml +++ b/hw/mcu/nordic/pkg.yml @@ -42,11 +42,18 @@ pkg.include_dirs: - "@nordic-nrfx/hal" - "@nordic-nrfx/helpers" - "@nordic-nrfx/mdk" + - "@nordic-nrfx/soc/interconnect/apb" + - "@nordic-nrfx/soc/interconnect/dppic_ppib" + - "@nordic-nrfx/soc/interconnect/ipct" - "@nordic-nrfx/." - "include" pkg.src_dirs: - "@nordic-nrfx/drivers/src" + - "@nordic-nrfx/helpers" + - "@nordic-nrfx/soc/interconnect/apb" + - "@nordic-nrfx/soc/interconnect/dppic_ppib" + - "@nordic-nrfx/soc/interconnect/ipct" pkg.cflags: - -std=gnu99 @@ -58,7 +65,7 @@ pkg.deps: repository.nordic-nrfx: type: github - vers: v3.3.0-commit + vers: v3.7.0-commit branch: master user: NordicSemiconductor repo: nrfx