-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
applications: sdp: mspi: Initial implementation
Added initial mspi implementation with hard real time task running on interrupts. Signed-off-by: Michal Frankiewicz <[email protected]> Signed-off-by: Magdalena Pastula <[email protected]>
- Loading branch information
1 parent
9598724
commit 89779ab
Showing
10 changed files
with
944 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(sdp_mspi) | ||
|
||
sdp_assembly_generate("${CMAKE_SOURCE_DIR}/src/hrt/hrt.c") | ||
sdp_assembly_check("${CMAKE_SOURCE_DIR}/src/hrt/hrt.c") | ||
sdp_assembly_prepare_install("${CMAKE_SOURCE_DIR}/src/hrt/hrt.c") | ||
|
||
target_sources(app PRIVATE src/main.c) | ||
target_sources(app PRIVATE src/hrt/hrt.s) | ||
|
||
add_dependencies(app asm_check) |
46 changes: 46 additions & 0 deletions
46
applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Single-threaded | ||
CONFIG_MULTITHREADING=n | ||
CONFIG_KERNEL_MEM_POOL=n | ||
CONFIG_LOG=n | ||
|
||
# Drivers and peripherals | ||
CONFIG_I2C=n | ||
CONFIG_WATCHDOG=n | ||
CONFIG_GPIO=n | ||
CONFIG_PINCTRL=n | ||
CONFIG_SPI=n | ||
CONFIG_SERIAL=n | ||
CONFIG_FLASH=n | ||
|
||
# Power management | ||
CONFIG_PM=n | ||
|
||
# Interrupts | ||
CONFIG_DYNAMIC_INTERRUPTS=n | ||
CONFIG_IRQ_OFFLOAD=n | ||
CONFIG_GEN_SW_ISR_TABLE=n | ||
|
||
# Memory protection | ||
CONFIG_THREAD_STACK_INFO=n | ||
CONFIG_THREAD_CUSTOM_DATA=n | ||
CONFIG_FPU=n | ||
|
||
# Boot | ||
CONFIG_BOOT_BANNER=n | ||
CONFIG_NCS_BOOT_BANNER=n | ||
|
||
# Console | ||
CONFIG_CONSOLE=n | ||
CONFIG_UART_CONSOLE=n | ||
CONFIG_STDOUT_CONSOLE=n | ||
CONFIG_PRINTK=n | ||
CONFIG_EARLY_CONSOLE=n | ||
|
||
# Build | ||
CONFIG_SIZE_OPTIMIZATIONS=y | ||
|
||
# No timer support in the kernel | ||
CONFIG_SYS_CLOCK_EXISTS=n | ||
|
||
CONFIG_OUTPUT_DISASSEMBLY=y | ||
CONFIG_COMMON_LIBC_MALLOC=n |
41 changes: 41 additions & 0 deletions
41
applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
&gpio0 { | ||
status = "disabled"; | ||
}; | ||
|
||
&gpio1 { | ||
status = "disabled"; | ||
}; | ||
|
||
&gpio2 { | ||
status = "disabled"; | ||
}; | ||
|
||
&gpiote20 { | ||
status = "disabled"; | ||
}; | ||
|
||
&gpiote30 { | ||
status = "disabled"; | ||
}; | ||
|
||
&grtc { | ||
status = "disabled"; | ||
}; | ||
|
||
&uart20 { | ||
status = "disabled"; | ||
}; | ||
|
||
&uart30 { | ||
status = "disabled"; | ||
}; | ||
|
||
&pwm20 { | ||
status = "disabled"; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
CONFIG_MBOX=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
sample: | ||
name: SDP mSPI application | ||
description: SDP mSPI application | ||
common: | ||
integration_platforms: | ||
- nrf54l15dk/nrf54l15/cpuflpr | ||
tests: | ||
applications.sdp.mspi.icmsg: | ||
build_only: true | ||
sysbuild: true | ||
platform_allow: nrf54l15dk/nrf54l15/cpuflpr | ||
tags: ci_build sysbuild mspi | ||
extra_configs: | ||
- CONFIG_IPC_SERVICE=y | ||
- CONFIG_IPC_SERVICE_BACKEND_ICMSG=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
#include "hrt.h" | ||
#include <hal/nrf_vpr_csr_vio.h> | ||
#include <hal/nrf_vpr_csr_vtim.h> | ||
|
||
#define TOP 4 | ||
|
||
void write_single_by_word(volatile uint32_t *data, | ||
uint8_t data_len, | ||
uint32_t counter_top, | ||
uint8_t word_size, | ||
bool ce_enable_state, | ||
bool hold_ce) | ||
{ | ||
NRFX_ASSERT(word_size > MAX_WORD_SIZE); | ||
|
||
/* Configuration step */ | ||
uint16_t dir = nrf_vpr_csr_vio_dir_get(); | ||
|
||
nrf_vpr_csr_vio_dir_set(dir | | ||
PIN_DIR_OUT_MASK(D0_PIN) | | ||
PIN_DIR_OUT_MASK(CS_PIN) | | ||
PIN_DIR_OUT_MASK(SCLK_PIN)); | ||
|
||
uint16_t out = nrf_vpr_csr_vio_out_get(); | ||
|
||
nrf_vpr_csr_vio_out_set(out | | ||
PIN_OUT_LOW_MASK(D0_PIN) | | ||
PIN_OUT_HIGH_MASK(CS_PIN) | | ||
PIN_OUT_LOW_MASK(SCLK_PIN)); | ||
|
||
nrf_vpr_csr_vio_mode_out_t out_mode = { | ||
.mode = NRF_VPR_CSR_VIO_SHIFT_OUTB_TOGGLE, | ||
.frame_width = 1, | ||
}; | ||
|
||
nrf_vpr_csr_vio_mode_out_set(&out_mode); | ||
nrf_vpr_csr_vio_mode_in_buffered_set(NRF_VPR_CSR_VIO_MODE_IN_CONTINUOUS); | ||
|
||
nrf_vpr_csr_vio_config_t config; | ||
|
||
nrf_vpr_csr_vio_config_get(&config); | ||
config.input_sel = false; | ||
nrf_vpr_csr_vio_config_set(&config); | ||
|
||
/* Fix position of data if word size < MAX_WORD_SIZE, | ||
* so that leading zeros would not be printed instead of data bits. | ||
*/ | ||
if (word_size < MAX_WORD_SIZE) { | ||
for (uint8_t i = 0; i < data_len; i++) { | ||
data[i] = data[i] << (MAX_WORD_SIZE - word_size); | ||
} | ||
} | ||
|
||
/* Counter settings */ | ||
nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_RELOAD); | ||
nrf_vpr_csr_vtim_simple_counter_top_set(0, counter_top); | ||
|
||
/* Set number of shifts before OUTB needs to be updated. | ||
* First shift needs to be increased by 1. | ||
*/ | ||
nrf_vpr_csr_vio_shift_cnt_out_set(word_size); | ||
nrf_vpr_csr_vio_shift_cnt_out_buffered_set(word_size - 1); | ||
|
||
/* Enable CS */ | ||
out = nrf_vpr_csr_vio_out_get(); | ||
out &= ~PIN_OUT_HIGH_MASK(CS_PIN); | ||
out |= ce_enable_state ? PIN_OUT_HIGH_MASK(CS_PIN) : PIN_OUT_LOW_MASK(CS_PIN); | ||
nrf_vpr_csr_vio_out_set(out); | ||
|
||
/* Start counter */ | ||
nrf_vpr_csr_vtim_simple_counter_set(0, 3 * counter_top); | ||
|
||
/* Send data */ | ||
for (uint8_t i = 0; i < data_len; i++) { | ||
nrf_vpr_csr_vio_out_buffered_reversed_byte_set(data[i]); | ||
} | ||
|
||
/* Clear all bits, wait until the last word is sent */ | ||
nrf_vpr_csr_vio_out_buffered_set(0); | ||
|
||
/* Final configuration */ | ||
out_mode.mode = NRF_VPR_CSR_VIO_SHIFT_NONE; | ||
nrf_vpr_csr_vio_mode_out_buffered_set(&out_mode); | ||
nrf_vpr_csr_vio_mode_in_buffered_set(NRF_VPR_CSR_VIO_MODE_IN_CONTINUOUS); | ||
|
||
/* Deselect slave */ | ||
if (!hold_ce) { | ||
out = nrf_vpr_csr_vio_out_get(); | ||
out &= ~(PIN_OUT_HIGH_MASK(CS_PIN) | PIN_OUT_HIGH_MASK(SCLK_PIN)); | ||
out |= ce_enable_state ? PIN_OUT_LOW_MASK(CS_PIN) : PIN_OUT_HIGH_MASK(CS_PIN); | ||
out |= PIN_OUT_LOW_MASK(SCLK_PIN); | ||
nrf_vpr_csr_vio_out_set(out); | ||
} | ||
|
||
/* Stop counter */ | ||
nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_STOP); | ||
} | ||
|
||
void write_quad_by_word(volatile uint32_t *data, | ||
uint8_t data_len, | ||
uint32_t counter_top, | ||
uint8_t word_size, | ||
bool ce_enable_state, | ||
bool hold_ce) | ||
{ | ||
NRFX_ASSERT(word_size > MAX_WORD_SIZE); | ||
NRFX_ASSERT(word_size % 4 == 0); | ||
|
||
/* Configuration step */ | ||
uint16_t dir = nrf_vpr_csr_vio_dir_get(); | ||
|
||
nrf_vpr_csr_vio_dir_set(dir | | ||
PIN_DIR_OUT_MASK(D0_PIN) | PIN_DIR_OUT_MASK(D1_PIN) | | ||
PIN_DIR_OUT_MASK(D2_PIN) | PIN_DIR_OUT_MASK(D3_PIN) | | ||
PIN_DIR_OUT_MASK(CS_PIN) | PIN_DIR_OUT_MASK(SCLK_PIN)); | ||
|
||
uint16_t out = nrf_vpr_csr_vio_out_get(); | ||
|
||
nrf_vpr_csr_vio_out_set(out | | ||
PIN_OUT_LOW_MASK(D0_PIN) | PIN_OUT_LOW_MASK(D1_PIN) | | ||
PIN_OUT_LOW_MASK(D2_PIN) | PIN_OUT_LOW_MASK(D3_PIN) | | ||
PIN_OUT_HIGH_MASK(CS_PIN) | PIN_OUT_LOW_MASK(SCLK_PIN)); | ||
|
||
nrf_vpr_csr_vio_mode_out_t out_mode = { | ||
.mode = NRF_VPR_CSR_VIO_SHIFT_OUTB_TOGGLE, | ||
.frame_width = 4, | ||
}; | ||
|
||
nrf_vpr_csr_vio_mode_out_set(&out_mode); | ||
nrf_vpr_csr_vio_mode_in_buffered_set(NRF_VPR_CSR_VIO_MODE_IN_CONTINUOUS); | ||
|
||
nrf_vpr_csr_vio_config_t config; | ||
|
||
nrf_vpr_csr_vio_config_get(&config); | ||
config.input_sel = false; | ||
nrf_vpr_csr_vio_config_set(&config); | ||
|
||
/* Fix position of data if word size < MAX_WORD_SIZE, | ||
* so that leading zeros would not be printed instead of data. | ||
*/ | ||
if (word_size < MAX_WORD_SIZE) { | ||
for (uint8_t i = 0; i < data_len; i++) { | ||
data[i] = data[i] << (MAX_WORD_SIZE - word_size); | ||
} | ||
} | ||
|
||
/* Counter settings */ | ||
nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_RELOAD); | ||
nrf_vpr_csr_vtim_simple_counter_top_set(0, counter_top); | ||
|
||
/* Set number of shifts before OUTB needs to be updated. | ||
* First shift needs to be increased by 1. | ||
*/ | ||
nrf_vpr_csr_vio_shift_cnt_out_set(word_size / 4); | ||
nrf_vpr_csr_vio_shift_cnt_out_buffered_set(word_size / 4 - 1); | ||
|
||
/* Enable CS */ | ||
out = nrf_vpr_csr_vio_out_get(); | ||
out &= ~PIN_OUT_HIGH_MASK(CS_PIN); | ||
out |= ce_enable_state ? PIN_OUT_HIGH_MASK(CS_PIN) : PIN_OUT_LOW_MASK(CS_PIN); | ||
nrf_vpr_csr_vio_out_set(out); | ||
|
||
/* Start counter */ | ||
nrf_vpr_csr_vtim_simple_counter_set(0, 3 * counter_top); | ||
|
||
/* Send data */ | ||
for (uint8_t i = 0; i < data_len; i++) { | ||
nrf_vpr_csr_vio_out_buffered_reversed_byte_set(data[i]); | ||
} | ||
|
||
/* Clear all bits, wait until the last word is sent */ | ||
nrf_vpr_csr_vio_out_buffered_set(0); | ||
|
||
/* Final configuration */ | ||
out_mode.mode = NRF_VPR_CSR_VIO_SHIFT_NONE; | ||
nrf_vpr_csr_vio_mode_out_buffered_set(&out_mode); | ||
nrf_vpr_csr_vio_mode_in_buffered_set(NRF_VPR_CSR_VIO_MODE_IN_CONTINUOUS); | ||
|
||
/* Deselect slave */ | ||
if (!hold_ce) { | ||
out = nrf_vpr_csr_vio_out_get(); | ||
out &= ~(PIN_OUT_HIGH_MASK(CS_PIN) | PIN_OUT_HIGH_MASK(SCLK_PIN)); | ||
out |= ce_enable_state ? PIN_OUT_LOW_MASK(CS_PIN) : PIN_OUT_HIGH_MASK(CS_PIN); | ||
out |= PIN_OUT_LOW_MASK(SCLK_PIN); | ||
nrf_vpr_csr_vio_out_set(out); | ||
} | ||
|
||
/* Stop counter */ | ||
nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_STOP); | ||
} |
Oops, something went wrong.