-
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 7a16741
Showing
11 changed files
with
893 additions
and
1 deletion.
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,3 @@ | ||
CONFIG_MBOX=n | ||
CONFIG_IPC_SERVICE=n | ||
CONFIG_IPC_SERVICE_BACKEND_ICMSG=n |
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,12 @@ | ||
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 |
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,181 @@ | ||
/* | ||
* 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 CLK_FIRST_CYCLE_MULTIPLICATOR (3) | ||
|
||
void write_single_by_word(volatile struct hrt_ll_xfer xfer_ll_params) | ||
{ | ||
|
||
NRFX_ASSERT(xfer_ll_params.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)); | ||
|
||
uint16_t out = nrf_vpr_csr_vio_out_get(); | ||
|
||
nrf_vpr_csr_vio_out_set(out | PIN_OUT_LOW_MASK(D0_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 (xfer_ll_params.word_size < MAX_WORD_SIZE) { | ||
for (uint8_t i = 0; i < xfer_ll_params.data_len; i++) { | ||
xfer_ll_params.data_to_send[i] = | ||
xfer_ll_params.data_to_send[i] | ||
<< (MAX_WORD_SIZE - xfer_ll_params.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, xfer_ll_params.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(xfer_ll_params.word_size); | ||
nrf_vpr_csr_vio_shift_cnt_out_buffered_set(xfer_ll_params.word_size - 1); | ||
|
||
/* Enable CS */ | ||
out = nrf_vpr_csr_vio_out_get(); | ||
out &= ~PIN_OUT_HIGH_MASK(CS_PIN); | ||
out |= xfer_ll_params.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, CLK_FIRST_CYCLE_MULTIPLICATOR * | ||
xfer_ll_params.counter_top); | ||
|
||
/* Send data */ | ||
for (uint8_t i = 0; i < xfer_ll_params.data_len; i++) { | ||
nrf_vpr_csr_vio_out_buffered_reversed_byte_set(xfer_ll_params.data_to_send[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 (!xfer_ll_params.ce_hold) { | ||
out = nrf_vpr_csr_vio_out_get(); | ||
out &= ~(PIN_OUT_HIGH_MASK(CS_PIN) | PIN_OUT_HIGH_MASK(SCLK_PIN)); | ||
out |= xfer_ll_params.ce_enable_state ? PIN_OUT_LOW_MASK(CS_PIN) | ||
: PIN_OUT_HIGH_MASK(CS_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 struct hrt_ll_xfer xfer_ll_params) | ||
{ | ||
NRFX_ASSERT(xfer_ll_params.word_size % 4 == 0); | ||
NRFX_ASSERT(xfer_ll_params.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(D1_PIN) | | ||
PIN_DIR_OUT_MASK(D2_PIN) | PIN_DIR_OUT_MASK(D3_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)); | ||
|
||
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 (xfer_ll_params.word_size < MAX_WORD_SIZE) { | ||
for (uint8_t i = 0; i < xfer_ll_params.data_len; i++) { | ||
xfer_ll_params.data_to_send[i] = | ||
xfer_ll_params.data_to_send[i] | ||
<< (MAX_WORD_SIZE - xfer_ll_params.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, xfer_ll_params.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(xfer_ll_params.word_size / 4); | ||
nrf_vpr_csr_vio_shift_cnt_out_buffered_set(xfer_ll_params.word_size / 4 - 1); | ||
|
||
/* Enable CS */ | ||
out = nrf_vpr_csr_vio_out_get(); | ||
out &= ~PIN_OUT_HIGH_MASK(CS_PIN); | ||
out |= xfer_ll_params.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 * xfer_ll_params.counter_top); | ||
|
||
/* Send data */ | ||
for (uint8_t i = 0; i < xfer_ll_params.data_len; i++) { | ||
nrf_vpr_csr_vio_out_buffered_reversed_byte_set(xfer_ll_params.data_to_send[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 (!xfer_ll_params.ce_hold) { | ||
out = nrf_vpr_csr_vio_out_get(); | ||
out &= ~(PIN_OUT_HIGH_MASK(CS_PIN) | PIN_OUT_HIGH_MASK(SCLK_PIN)); | ||
out |= xfer_ll_params.ce_enable_state ? PIN_OUT_LOW_MASK(CS_PIN) | ||
: PIN_OUT_HIGH_MASK(CS_PIN); | ||
nrf_vpr_csr_vio_out_set(out); | ||
} | ||
|
||
/* Stop counter */ | ||
nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_STOP); | ||
} |
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,83 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
#ifndef _HRT_H__ | ||
#define _HRT_H__ | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
#define SCLK_PIN 0 | ||
#define D0_PIN 1 | ||
#define D1_PIN 2 | ||
#define D2_PIN 3 | ||
#define D3_PIN 4 | ||
#define CS_PIN 5 | ||
|
||
/* Max word size. */ | ||
#define MAX_WORD_SIZE NRF_VPR_CSR_VIO_SHIFT_CNT_OUT_BUFFERED_MAX | ||
|
||
/* Macro for getting direction mask for specified pin and direction. */ | ||
#define PIN_DIR_MASK(PIN_NUM, DIR) \ | ||
(VPRCSR_NORDIC_DIR_PIN##PIN_NUM##_##DIR << VPRCSR_NORDIC_DIR_PIN##PIN_NUM##_Pos) | ||
|
||
/* Macro for getting output mask for specified pin. */ | ||
#define PIN_DIR_OUT_MASK(PIN_NUM) PIN_DIR_MASK(PIN_NUM, OUTPUT) | ||
|
||
/* Macro for getting input mask for specified pin. */ | ||
#define PIN_DIR_IN_MASK(PIN_NUM) PIN_DIR_MASK(PIN_NUM, INPUT) | ||
|
||
/* Macro for getting state mask for specified pin and state. */ | ||
#define PIN_OUT_MASK(PIN_NUM, STATE) \ | ||
(VPRCSR_NORDIC_OUT_PIN##PIN_NUM##_##STATE << VPRCSR_NORDIC_OUT_PIN##PIN_NUM##_Pos) | ||
|
||
/* Macro for getting high state mask for specified pin. */ | ||
#define PIN_OUT_HIGH_MASK(PIN_NUM) PIN_OUT_MASK(PIN_NUM, HIGH) | ||
|
||
/* Macro for getting low state mask for specified pin. */ | ||
#define PIN_OUT_LOW_MASK(PIN_NUM) PIN_OUT_MASK(PIN_NUM, LOW) | ||
|
||
/** @brief Low level transfer parameters. */ | ||
struct hrt_ll_xfer { | ||
|
||
/** @brief Top value of VTIM. This will determine clock frequency | ||
* (SPI_CLOCK ~= CPU_CLOCK / (2 * TOP)). | ||
*/ | ||
volatile uint8_t counter_top; | ||
|
||
/** @brief Word size of passed data, bits. */ | ||
volatile uint8_t word_size; | ||
|
||
/** @brief Data to send, under each index there is data of length word_size. */ | ||
volatile uint32_t *data_to_send; | ||
|
||
/** @brief Data length. */ | ||
volatile uint8_t data_len; | ||
|
||
/** @brief If true chip enable pin will be left active after transfer */ | ||
volatile uint8_t ce_hold; | ||
|
||
/** @brief Chip enable pin polarity in enabled state. */ | ||
volatile bool ce_enable_state; | ||
}; | ||
|
||
/** @brief Write on single line. | ||
* | ||
* Function to be used to write data on single data line (SPI). | ||
* | ||
* @param[in] xfer_ll_params Low level transfer parameters. | ||
*/ | ||
void write_single_by_word(volatile struct hrt_ll_xfer xfer_ll_params); | ||
|
||
/** @brief Write on four lines. | ||
* | ||
* Function to be used to write data on quad data line (SPI). | ||
* | ||
* @param[in] xfer_ll_params Low level transfer parameters. | ||
*/ | ||
void write_quad_by_word(volatile struct hrt_ll_xfer xfer_ll_params); | ||
|
||
#endif /* _HRT_H__ */ |
Oops, something went wrong.