-
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 f910c03
Showing
10 changed files
with
858 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,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,180 @@ | ||
/* | ||
* 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 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, CLK_FIRST_CYCLE_MULTIPLICATOR * 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 % 4 == 0); | ||
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(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); | ||
} |
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,73 @@ | ||
/* | ||
* 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 Write on single line. | ||
* | ||
* Function to be used to write data on single data line (SPI). | ||
* | ||
* @param[in] data Data to be sent. | ||
* @param[in] data_len Length of data in words. | ||
* @param[in] counter_top Top value of VTIM. This will determine clock frequency | ||
* (SPI_CLOCK ~= CPU_CLOCK / (2 * TOP)). | ||
* @param[in] word_size Size of a word in bits. | ||
* @param[in] ce_enable_state Chip enable pin polarity in enabled state. | ||
* @param[in] hold_ce If true CE pin will be left enabled after transfer. | ||
*/ | ||
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); | ||
|
||
/** @brief Write on four lines. | ||
* | ||
* Function to be used to write data on quad data line (SPI). | ||
* | ||
* @param[in] data Data to be sent. | ||
* @param[in] data_len Length of data in words. | ||
* @param[in] counter_top Top value of VTIM. This will determine clock frequency | ||
* (SPI_CLOCK ~= CPU_CLOCK / (2 * TOP)). | ||
* @param[in] word_size Size of a word in bits. | ||
* @param[in] ce_enable_state Chip enable pin polarity in enabled state. | ||
* @param[in] hold_ce If true CE pin will be left enabled after transfer. | ||
*/ | ||
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); | ||
|
||
#endif /* _HRT_H__ */ |
Oops, something went wrong.