Skip to content

Commit 3022645

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 06e084c commit 3022645

File tree

4 files changed

+212
-10
lines changed

4 files changed

+212
-10
lines changed

applications/sdp/mspi/src/main.c

+28
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static volatile uint8_t ce_vios_count;
6565
static volatile uint8_t ce_vios[DEVICES_MAX];
6666
static volatile uint8_t data_vios_count;
6767
static volatile uint8_t data_vios[DATA_PINS_MAX];
68+
static volatile nrfe_mspi_reset_config_t reset_configs[DEVICES_MAX];
6869
static volatile nrfe_mspi_dev_config_t nrfe_mspi_devices[DEVICES_MAX];
6970
static volatile nrfe_mspi_xfer_config_t nrfe_mspi_xfer_config;
7071
static volatile nrfe_mspi_xfer_config_t *nrfe_mspi_xfer_config_ptr = &nrfe_mspi_xfer_config;
@@ -356,6 +357,21 @@ static void config_pins(nrfe_mspi_pinctrl_soc_pin_msg_t *pins_cfg)
356357
}
357358
}
358359

360+
static void reset_set(uint8_t device_index, int value)
361+
{
362+
if (reset_configs[device_index].inversed) {
363+
value = (value != 0) ? 0 : 1;
364+
}
365+
366+
if (value == 0) {
367+
nrf_vpr_csr_vio_out_clear_set(
368+
BIT(pin_to_vio_map[reset_configs[device_index].pin_number]));
369+
} else {
370+
nrf_vpr_csr_vio_out_or_set(
371+
BIT(pin_to_vio_map[reset_configs[device_index].pin_number]));
372+
}
373+
}
374+
359375
static void ep_bound(void *priv)
360376
{
361377
atomic_set_bit(&ipc_atomic_sem, NRFE_MSPI_EP_BOUNDED);
@@ -394,6 +410,18 @@ static void ep_recv(const void *data, size_t len, void *priv)
394410
config_pins(pins_cfg);
395411
break;
396412
}
413+
case NRFE_MSPI_CONFIG_RESET: {
414+
nrfe_mspi_reset_config_msg_t *reset_cfg = (nrfe_mspi_reset_config_msg_t *)data;
415+
416+
reset_configs[reset_cfg->device_index] = reset_cfg->reset_config;
417+
break;
418+
}
419+
case NRFE_MSPI_SET_RESET: {
420+
nrfe_mspi_reset_set_msg_t *reset_cfg = (nrfe_mspi_reset_set_msg_t *)data;
421+
422+
reset_set(reset_cfg->device_index, reset_cfg->value);
423+
break;
424+
}
397425
case NRFE_MSPI_CONFIG_DEV: {
398426
nrfe_mspi_dev_config_msg_t *dev_config = (nrfe_mspi_dev_config_msg_t *)data;
399427

drivers/mspi/mspi_nrfe.c

+84-5
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)
@@ -27,6 +28,7 @@ LOG_MODULE_REGISTER(mspi_nrfe, CONFIG_MSPI_LOG_LEVEL);
2728
#define IPC_TIMEOUT_MS 100
2829
#define EP_SEND_TIMEOUT_MS 10
2930
#define CNT0_TOP_CALCULATE(freq) (NRFX_CEIL_DIV(SystemCoreClock, freq * 2) - 1)
31+
#define DEVICES_MAX 5
3032

3133
#define SDP_MPSI_PINCTRL_DEV_CONFIG_INIT(node_id) \
3234
{ \
@@ -84,6 +86,7 @@ static const struct mspi_nrfe_config dev_config = {
8486
};
8587

8688
static struct mspi_nrfe_data dev_data;
89+
static bool is_reset_sent[DEVICES_MAX];
8790

8891
static void ep_recv(const void *data, size_t len, void *priv);
8992

@@ -643,6 +646,77 @@ static int api_transceive(const struct device *dev, const struct mspi_dev_id *de
643646
return 0;
644647
}
645648

649+
static int api_reset_config(const struct device *dev, const struct mspi_dev_id *dev_id,
650+
const struct gpio_dt_spec *spec, uint8_t gpio_port_num,
651+
gpio_flags_t extra_flags)
652+
{
653+
const struct mspi_nrfe_config *drv_cfg = dev->config;
654+
const struct pinctrl_state *state = &drv_cfg->pcfg->states[PINCTRL_STATE_DEFAULT];
655+
gpio_flags_t flags = spec->dt_flags | extra_flags;
656+
uint8_t pin_number = spec->pin;
657+
nrfe_mspi_reset_config_msg_t mspi_reset_config;
658+
659+
/*
660+
* Check if reset pin is not the same as any pin declared for MSPI device.
661+
* If it is and it is valid, send the information to FLPR, otherwise treat it as a regular
662+
* GPIO pin.
663+
*/
664+
if (gpio_port_num == NRFE_MSPI_PORT_NUMBER) {
665+
for (uint8_t i = 0; i < state->pin_cnt; i++) {
666+
if (pin_number == NRF_PIN_NUMBER_TO_PIN(NRF_GET_PIN(state->pins[i]))) {
667+
switch (NRF_GET_FUN(state->pins[i])) {
668+
case NRF_FUN_SDP_MSPI_DQ0:
669+
case NRF_FUN_SDP_MSPI_DQ1:
670+
LOG_ERR("Reset pin cannot be the same as D0 or "
671+
"D1.");
672+
return -EINVAL;
673+
case NRF_FUN_SDP_MSPI_SCK:
674+
LOG_ERR("Reset pin cannot be the same as CLK.");
675+
return -EINVAL;
676+
case NRF_FUN_SDP_MSPI_CS0:
677+
case NRF_FUN_SDP_MSPI_CS1:
678+
case NRF_FUN_SDP_MSPI_CS2:
679+
case NRF_FUN_SDP_MSPI_CS3:
680+
LOG_ERR("Reset pin cannot be the same as any CS.");
681+
return -EINVAL;
682+
case NRF_FUN_SDP_MSPI_DQ2:
683+
case NRF_FUN_SDP_MSPI_DQ3:
684+
is_reset_sent[dev_id->dev_idx] = true;
685+
mspi_reset_config.device_index = dev_id->dev_idx;
686+
mspi_reset_config.reset_config.pin_number = pin_number;
687+
mspi_reset_config.reset_config.inversed =
688+
((flags & GPIO_ACTIVE_LOW) != 0);
689+
/* Send reset configuration to FLPR */
690+
return send_data(NRFE_MSPI_CONFIG_RESET,
691+
(const void *)&mspi_reset_config,
692+
sizeof(nrfe_mspi_reset_config_msg_t));
693+
default:
694+
break;
695+
}
696+
}
697+
}
698+
}
699+
700+
return gpio_pin_configure_dt(spec, flags);
701+
}
702+
703+
static int api_reset_set(const struct device *dev, const struct gpio_dt_spec *spec,
704+
const struct mspi_dev_id *dev_id, int value)
705+
{
706+
nrfe_mspi_reset_set_msg_t mspi_reset_set;
707+
708+
if (is_reset_sent[dev_id->dev_idx]) {
709+
mspi_reset_set.device_index = dev_id->dev_idx;
710+
mspi_reset_set.value = value;
711+
return send_data(NRFE_MSPI_SET_RESET, (const void *)&mspi_reset_set,
712+
sizeof(nrfe_mspi_reset_set_msg_t));
713+
} else {
714+
return gpio_pin_set_dt(spec, value);
715+
}
716+
717+
return 0;
718+
}
719+
646720
#if CONFIG_PM_DEVICE
647721
/**
648722
* @brief Callback function to handle power management actions.
@@ -790,11 +864,16 @@ static int nrfe_mspi_init(const struct device *dev)
790864
return ret;
791865
}
792866

793-
static const struct mspi_driver_api drv_api = {
794-
.config = api_config,
795-
.dev_config = api_dev_config,
796-
.get_channel_status = api_get_channel_status,
797-
.transceive = api_transceive,
867+
static const struct nrf_mspi_driver_api drv_api = {
868+
.std_api =
869+
{
870+
.config = api_config,
871+
.dev_config = api_dev_config,
872+
.get_channel_status = api_get_channel_status,
873+
.transceive = api_transceive,
874+
},
875+
.reset_pin_config = api_reset_config,
876+
.reset_pin_set = api_reset_set,
798877
};
799878

800879
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
@@ -34,16 +34,23 @@ extern "C" {
3434
typedef enum {
3535
NRFE_MSPI_EP_BOUNDED = 0,
3636
NRFE_MSPI_CONFIG_TIMER_PTR, /* nrfe_mspi_flpr_timer_msg_t */
37-
NRFE_MSPI_CONFIG_PINS, /* nrfe_mspi_pinctrl_soc_pin_msg_t */
38-
NRFE_MSPI_CONFIG_DEV, /* nrfe_mspi_dev_config_msg_t */
39-
NRFE_MSPI_CONFIG_XFER, /* nrfe_mspi_xfer_config_msg_t */
40-
NRFE_MSPI_TX, /* nrfe_mspi_xfer_packet_msg_t + data buffer at the end */
37+
NRFE_MSPI_CONFIG_PINS, /* nrfe_mspi_pinctrl_soc_pin_msg_t */
38+
NRFE_MSPI_CONFIG_RESET, /* nrfe_mspi_reset_config_msg_t */
39+
NRFE_MSPI_SET_RESET, /* nrfe_mspi_reset_set_msg_t */
40+
NRFE_MSPI_CONFIG_DEV, /* nrfe_mspi_dev_config_msg_t */
41+
NRFE_MSPI_CONFIG_XFER, /* nrfe_mspi_xfer_config_msg_t */
42+
NRFE_MSPI_TX, /* nrfe_mspi_xfer_packet_msg_t + data buffer at the end */
4143
NRFE_MSPI_TXRX,
4244
NRFE_MSPI_SDP_APP_HARD_FAULT,
4345
NRFE_MSPI_WRONG_OPCODE,
4446
NRFE_MSPI_ALL_OPCODES = NRFE_MSPI_WRONG_OPCODE,
4547
} nrfe_mspi_opcode_t;
4648

49+
typedef struct {
50+
uint8_t pin_number;
51+
bool inversed;
52+
} nrfe_mspi_reset_config_t;
53+
4754
typedef struct {
4855
enum mspi_io_mode io_mode;
4956
enum mspi_cpp_mode cpp;
@@ -71,6 +78,18 @@ typedef struct {
7178
pinctrl_soc_pin_t pin[NRFE_MSPI_PINS_MAX];
7279
} nrfe_mspi_pinctrl_soc_pin_msg_t;
7380

81+
typedef struct {
82+
nrfe_mspi_opcode_t opcode; /* NRFE_MSPI_CONFIG_RESET */
83+
uint8_t device_index;
84+
nrfe_mspi_reset_config_t reset_config;
85+
} nrfe_mspi_reset_config_msg_t;
86+
87+
typedef struct {
88+
nrfe_mspi_opcode_t opcode; /* NRFE_MSPI_SET_RESET */
89+
uint8_t device_index;
90+
int value;
91+
} nrfe_mspi_reset_set_msg_t;
92+
7493
typedef struct {
7594
nrfe_mspi_opcode_t opcode; /* NRFE_MSPI_CONFIG_DEV */
7695
uint8_t device_index;

0 commit comments

Comments
 (0)