Skip to content

Commit 98eb5fc

Browse files
committed
applications: sdp: mspi: extend MSPI API with reset functions
Extend MSPI API with custom functions handling reset pins. Signed-off-by: Magdalena Pastula <magdalena.pastula@nordicsemi.no>
1 parent 0b0505a commit 98eb5fc

File tree

4 files changed

+213
-11
lines changed

4 files changed

+213
-11
lines changed

applications/sdp/mspi/src/main.c

+28
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ static volatile uint8_t ce_vios[DEVICES_MAX];
8484
static volatile uint8_t data_vios_count;
8585
static volatile uint8_t data_vios[DATA_PINS_MAX];
8686
static volatile uint8_t clk_vio;
87+
static volatile nrfe_mspi_reset_config_t reset_configs[DEVICES_MAX];
8788
static volatile nrfe_mspi_dev_config_t nrfe_mspi_devices[DEVICES_MAX];
8889
static volatile nrfe_mspi_xfer_config_t nrfe_mspi_xfer_config;
8990
static volatile nrfe_mspi_xfer_config_t *nrfe_mspi_xfer_config_ptr = &nrfe_mspi_xfer_config;
@@ -394,6 +395,21 @@ static void config_pins(nrfe_mspi_pinctrl_soc_pin_msg_t *pins_cfg)
394395
}
395396
}
396397

398+
static void reset_set(uint8_t device_index, int value)
399+
{
400+
if (reset_configs[device_index].inversed) {
401+
value = (value != 0) ? 0 : 1;
402+
}
403+
404+
if (value == 0) {
405+
nrf_vpr_csr_vio_out_clear_set(
406+
BIT(pin_to_vio_map[reset_configs[device_index].pin_number]));
407+
} else {
408+
nrf_vpr_csr_vio_out_or_set(
409+
BIT(pin_to_vio_map[reset_configs[device_index].pin_number]));
410+
}
411+
}
412+
397413
static void ep_bound(void *priv)
398414
{
399415
atomic_set_bit(&ipc_atomic_sem, NRFE_MSPI_EP_BOUNDED);
@@ -432,6 +448,18 @@ static void ep_recv(const void *data, size_t len, void *priv)
432448
config_pins(pins_cfg);
433449
break;
434450
}
451+
case NRFE_MSPI_CONFIG_RESET: {
452+
nrfe_mspi_reset_config_msg_t *reset_cfg = (nrfe_mspi_reset_config_msg_t *)data;
453+
454+
reset_configs[reset_cfg->device_index] = reset_cfg->reset_config;
455+
break;
456+
}
457+
case NRFE_MSPI_SET_RESET: {
458+
nrfe_mspi_reset_set_msg_t *reset_cfg = (nrfe_mspi_reset_set_msg_t *)data;
459+
460+
reset_set(reset_cfg->device_index, reset_cfg->value);
461+
break;
462+
}
435463
case NRFE_MSPI_CONFIG_DEV: {
436464
nrfe_mspi_dev_config_msg_t *dev_config = (nrfe_mspi_dev_config_msg_t *)data;
437465

drivers/mspi/mspi_nrfe.c

+85-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <zephyr/drivers/mspi.h>
1111
#include <zephyr/drivers/pinctrl.h>
1212
#include <zephyr/drivers/counter.h>
13+
#include <zephyr/drivers/gpio.h>
1314
#include <zephyr/ipc/ipc_service.h>
1415
#include <zephyr/pm/device.h>
1516
#if !defined(CONFIG_MULTITHREADING)
@@ -26,10 +27,12 @@ LOG_MODULE_REGISTER(mspi_nrfe, CONFIG_MSPI_LOG_LEVEL);
2627
#define MAX_RX_MSG_SIZE (DT_REG_SIZE(DT_NODELABEL(sram_rx)))
2728
#define IPC_TIMEOUT_MS 100
2829
#define EP_SEND_TIMEOUT_MS 10
30+
2931
#define EXTREME_DRIVE_FREQ_THRESHOLD 32000000
3032
#define CNT0_TOP_CALCULATE(freq) (NRFX_CEIL_DIV(SystemCoreClock, freq * 2) - 1)
3133
#define DATA_LINE_INDEX(pinctr_fun) (pinctr_fun - NRF_FUN_SDP_MSPI_DQ0)
3234
#define DATA_PIN_UNUSED UINT8_MAX
35+
#define DEVICES_MAX 5
3336

3437
#ifdef CONFIG_SOC_NRF54L15
3538

@@ -40,7 +43,6 @@ LOG_MODULE_REGISTER(mspi_nrfe, CONFIG_MSPI_LOG_LEVEL);
4043
#else
4144
#error "Unsupported SoC for SDP MSPI"
4245
#endif
43-
4446
#define SDP_MPSI_PINCTRL_DEV_CONFIG_INIT(node_id) \
4547
{ \
4648
.reg = PINCTRL_REG_NONE, \
@@ -97,6 +99,7 @@ static const struct mspi_nrfe_config dev_config = {
9799
};
98100

99101
static struct mspi_nrfe_data dev_data;
102+
static bool is_reset_sent[DEVICES_MAX];
100103

101104
static void ep_recv(const void *data, size_t len, void *priv);
102105

@@ -821,6 +824,77 @@ static int api_transceive(const struct device *dev, const struct mspi_dev_id *de
821824
return 0;
822825
}
823826

827+
static int api_reset_config(const struct device *dev, const struct mspi_dev_id *dev_id,
828+
const struct gpio_dt_spec *spec, uint8_t gpio_port_num,
829+
gpio_flags_t extra_flags)
830+
{
831+
const struct mspi_nrfe_config *drv_cfg = dev->config;
832+
const struct pinctrl_state *state = &drv_cfg->pcfg->states[PINCTRL_STATE_DEFAULT];
833+
gpio_flags_t flags = spec->dt_flags | extra_flags;
834+
uint8_t pin_number = spec->pin;
835+
nrfe_mspi_reset_config_msg_t mspi_reset_config;
836+
837+
/*
838+
* Check if reset pin is not the same as any pin declared for MSPI device.
839+
* If it is and it is valid, send the information to FLPR, otherwise treat it as a regular
840+
* GPIO pin.
841+
*/
842+
if (gpio_port_num == NRFE_MSPI_PORT_NUMBER) {
843+
for (uint8_t i = 0; i < state->pin_cnt; i++) {
844+
if (pin_number == NRF_PIN_NUMBER_TO_PIN(NRF_GET_PIN(state->pins[i]))) {
845+
switch (NRF_GET_FUN(state->pins[i])) {
846+
case NRF_FUN_SDP_MSPI_DQ0:
847+
case NRF_FUN_SDP_MSPI_DQ1:
848+
LOG_ERR("Reset pin cannot be the same as D0 or "
849+
"D1.");
850+
return -EINVAL;
851+
case NRF_FUN_SDP_MSPI_SCK:
852+
LOG_ERR("Reset pin cannot be the same as CLK.");
853+
return -EINVAL;
854+
case NRF_FUN_SDP_MSPI_CS0:
855+
case NRF_FUN_SDP_MSPI_CS1:
856+
case NRF_FUN_SDP_MSPI_CS2:
857+
case NRF_FUN_SDP_MSPI_CS3:
858+
LOG_ERR("Reset pin cannot be the same as any CS.");
859+
return -EINVAL;
860+
case NRF_FUN_SDP_MSPI_DQ2:
861+
case NRF_FUN_SDP_MSPI_DQ3:
862+
is_reset_sent[dev_id->dev_idx] = true;
863+
mspi_reset_config.device_index = dev_id->dev_idx;
864+
mspi_reset_config.reset_config.pin_number = pin_number;
865+
mspi_reset_config.reset_config.inversed =
866+
((flags & GPIO_ACTIVE_LOW) != 0);
867+
/* Send reset configuration to FLPR */
868+
return send_data(NRFE_MSPI_CONFIG_RESET,
869+
(const void *)&mspi_reset_config,
870+
sizeof(nrfe_mspi_reset_config_msg_t));
871+
default:
872+
break;
873+
}
874+
}
875+
}
876+
}
877+
878+
return gpio_pin_configure_dt(spec, flags);
879+
}
880+
881+
static int api_reset_set(const struct device *dev, const struct gpio_dt_spec *spec,
882+
const struct mspi_dev_id *dev_id, int value)
883+
{
884+
nrfe_mspi_reset_set_msg_t mspi_reset_set;
885+
886+
if (is_reset_sent[dev_id->dev_idx]) {
887+
mspi_reset_set.device_index = dev_id->dev_idx;
888+
mspi_reset_set.value = value;
889+
return send_data(NRFE_MSPI_SET_RESET, (const void *)&mspi_reset_set,
890+
sizeof(nrfe_mspi_reset_set_msg_t));
891+
} else {
892+
return gpio_pin_set_dt(spec, value);
893+
}
894+
895+
return 0;
896+
}
897+
824898
#if CONFIG_PM_DEVICE
825899
/**
826900
* @brief Callback function to handle power management actions.
@@ -968,11 +1042,16 @@ static int nrfe_mspi_init(const struct device *dev)
9681042
return ret;
9691043
}
9701044

971-
static const struct mspi_driver_api drv_api = {
972-
.config = api_config,
973-
.dev_config = api_dev_config,
974-
.get_channel_status = api_get_channel_status,
975-
.transceive = api_transceive,
1045+
static const struct nrf_mspi_driver_api drv_api = {
1046+
.std_api =
1047+
{
1048+
.config = api_config,
1049+
.dev_config = api_dev_config,
1050+
.get_channel_status = api_get_channel_status,
1051+
.transceive = api_transceive,
1052+
},
1053+
.reset_pin_config = api_reset_config,
1054+
.reset_pin_set = api_reset_set,
9761055
};
9771056

9781057
PM_DEVICE_DT_INST_DEFINE(0, dev_pm_action_cb);

include/drivers/mspi/nrf_mspi.h

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_DRIVERS_MSPI_NRF_MSPI_H_
8+
#define ZEPHYR_INCLUDE_DRIVERS_MSPI_NRF_MSPI_H_
9+
10+
#include <zephyr/device.h>
11+
#include <zephyr/drivers/mspi.h>
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
typedef int (*mspi_api_reset_pin_config)(const struct device *dev, const struct mspi_dev_id *dev_id,
18+
const struct gpio_dt_spec *spec, uint8_t gpio_port_num,
19+
gpio_flags_t extra_flags);
20+
typedef int (*mspi_api_reset_pin_set)(const struct device *dev, const struct gpio_dt_spec *spec,
21+
const struct mspi_dev_id *dev_id, int value);
22+
23+
__subsystem struct nrf_mspi_driver_api {
24+
struct mspi_driver_api std_api;
25+
26+
mspi_api_reset_pin_config reset_pin_config;
27+
mspi_api_reset_pin_set reset_pin_set;
28+
};
29+
30+
/**
31+
* @brief Configure reset pin. It is mandatory when reset pin overlaps with any data pin.
32+
*
33+
* @param dev pointer to the mspi device structure.
34+
* @param psel pin number
35+
*
36+
* @retval non-negative the observed state of the on-off service associated
37+
* with the clock machine at the time the request was
38+
* processed (see onoff_release()), if successful.
39+
* @retval -EIO if service has recorded an error.
40+
* @retval -ENOTSUP if the service is not in a state that permits release.
41+
*/
42+
static inline int nrf_mspi_reset_pin_config(const struct device *dev,
43+
const struct mspi_dev_id *dev_id,
44+
const struct gpio_dt_spec *spec, uint8_t gpio_port_num,
45+
gpio_flags_t extra_flags)
46+
{
47+
const struct nrf_mspi_driver_api *api = (const struct nrf_mspi_driver_api *)dev->api;
48+
49+
return api->reset_pin_config(dev, dev_id, spec, gpio_port_num, extra_flags);
50+
}
51+
52+
/**
53+
* @brief Set reset pin state.
54+
*
55+
* @param dev pointer to the mspi device structure.
56+
* @param psel pin number
57+
*
58+
* @retval non-negative the observed state of the on-off service associated
59+
* with the clock machine at the time the request was
60+
* processed (see onoff_release()), if successful.
61+
* @retval -EIO if service has recorded an error.
62+
* @retval -ENOTSUP if the service is not in a state that permits release.
63+
*/
64+
static inline int nrf_mspi_reset_pin_set(const struct device *dev, const struct gpio_dt_spec *spec,
65+
const struct mspi_dev_id *dev_id, int value)
66+
{
67+
const struct nrf_mspi_driver_api *api = (const struct nrf_mspi_driver_api *)dev->api;
68+
69+
return api->reset_pin_set(dev, spec, dev_id, value);
70+
}
71+
72+
#ifdef __cplusplus
73+
}
74+
#endif
75+
76+
#endif /* ZEPHYR_INCLUDE_DRIVERS_MSPI_NRF_MSPI_H_ */

include/drivers/mspi/nrfe_mspi.h

+24-5
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#ifndef DRIVERS_MSPI_NRFE_MSPI_H
88
#define DRIVERS_MSPI_NRFE_MSPI_H
99

10+
#include <drivers/mspi/nrf_mspi.h>
1011
#include <zephyr/drivers/pinctrl.h>
11-
#include <zephyr/drivers/mspi.h>
1212
#include <hal/nrf_timer.h>
1313

1414
#ifdef __cplusplus
@@ -25,10 +25,12 @@ extern "C" {
2525
typedef enum {
2626
NRFE_MSPI_EP_BOUNDED = 0,
2727
NRFE_MSPI_CONFIG_TIMER_PTR, /* nrfe_mspi_flpr_timer_msg_t */
28-
NRFE_MSPI_CONFIG_PINS, /* nrfe_mspi_pinctrl_soc_pin_msg_t */
29-
NRFE_MSPI_CONFIG_DEV, /* nrfe_mspi_dev_config_msg_t */
30-
NRFE_MSPI_CONFIG_XFER, /* nrfe_mspi_xfer_config_msg_t */
31-
NRFE_MSPI_TX, /* nrfe_mspi_xfer_packet_msg_t + data buffer at the end */
28+
NRFE_MSPI_CONFIG_PINS, /* nrfe_mspi_pinctrl_soc_pin_msg_t */
29+
NRFE_MSPI_CONFIG_RESET, /* nrfe_mspi_reset_config_msg_t */
30+
NRFE_MSPI_SET_RESET, /* nrfe_mspi_reset_set_msg_t */
31+
NRFE_MSPI_CONFIG_DEV, /* nrfe_mspi_dev_config_msg_t */
32+
NRFE_MSPI_CONFIG_XFER, /* nrfe_mspi_xfer_config_msg_t */
33+
NRFE_MSPI_TX, /* nrfe_mspi_xfer_packet_msg_t + data buffer at the end */
3234
NRFE_MSPI_TXRX,
3335
NRFE_MSPI_SDP_APP_HARD_FAULT,
3436
NRFE_MSPI_WRONG_OPCODE,
@@ -37,6 +39,11 @@ typedef enum {
3739
NREE_MSPI_OPCODES_MAX = 0xFFFFFFFFU,
3840
} nrfe_mspi_opcode_t;
3941

42+
typedef struct {
43+
uint8_t pin_number;
44+
bool inversed;
45+
} nrfe_mspi_reset_config_t;
46+
4047
typedef struct {
4148
enum mspi_io_mode io_mode;
4249
enum mspi_cpp_mode cpp;
@@ -65,6 +72,18 @@ typedef struct {
6572
pinctrl_soc_pin_t pin[NRFE_MSPI_PINS_MAX];
6673
} nrfe_mspi_pinctrl_soc_pin_msg_t;
6774

75+
typedef struct {
76+
nrfe_mspi_opcode_t opcode; /* NRFE_MSPI_CONFIG_RESET */
77+
uint8_t device_index;
78+
nrfe_mspi_reset_config_t reset_config;
79+
} nrfe_mspi_reset_config_msg_t;
80+
81+
typedef struct {
82+
nrfe_mspi_opcode_t opcode; /* NRFE_MSPI_SET_RESET */
83+
uint8_t device_index;
84+
int value;
85+
} nrfe_mspi_reset_set_msg_t;
86+
6887
typedef struct {
6988
nrfe_mspi_opcode_t opcode; /* NRFE_MSPI_CONFIG_DEV */
7089
uint8_t device_index;

0 commit comments

Comments
 (0)