Skip to content

Commit dd9bbd4

Browse files
jaz1-nordiccarlescufi
authored andcommitted
drivers: mspi: Use TIMER peripheral as a watchdog for SDP FW
TIMER is set up by the Host and cleared periodically by SDP FW. If SDP FW fails to clear the TIMER, the Host receives an IRQ signalling an SDP FW error. Signed-off-by: Jakub Zymelka <[email protected]>
1 parent 54bfc68 commit dd9bbd4

File tree

3 files changed

+97
-4
lines changed

3 files changed

+97
-4
lines changed

drivers/mspi/Kconfig.nrfe

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,22 @@ config MSPI_NRFE_IPC_NO_COPY
3434
this requires both cores to be able to access each others memory spaces.
3535
If n Data is passed through IPC by copy.
3636

37+
config MSPI_NRFE_FAULT_TIMER
38+
bool "SDP application fault timer"
39+
select COUNTER
40+
help
41+
Enable SDP application fault timer.
42+
Timer is used to detect application faults. If the timer expires,
43+
the application is considered to be in a fault state.
44+
45+
if MSPI_NRFE_FAULT_TIMER
46+
47+
config MSPI_NRFE_FAULT_TIMEOUT
48+
int "SDP application fault timeout"
49+
default 1000000
50+
help
51+
Fault timeout in microseconds.
52+
53+
endif # MSPI_NRFE_FAULT_TIMER
54+
3755
endif # MSPI_NRFE

drivers/mspi/mspi_nrfe.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <zephyr/kernel.h>
1010
#include <zephyr/drivers/mspi.h>
1111
#include <zephyr/drivers/pinctrl.h>
12+
#include <zephyr/drivers/counter.h>
1213
#include <zephyr/ipc/ipc_service.h>
1314
#include <zephyr/pm/device.h>
1415
#if !defined(CONFIG_MULTITHREADING)
@@ -113,6 +114,16 @@ static void ep_recv(const void *data, size_t len, void *priv)
113114
nrfe_mspi_flpr_response_msg_t *response = (nrfe_mspi_flpr_response_msg_t *)data;
114115

115116
switch (response->opcode) {
117+
#if defined(CONFIG_MSPI_NRFE_FAULT_TIMER)
118+
case NRFE_MSPI_CONFIG_TIMER_PTR: {
119+
#if defined(CONFIG_MULTITHREADING)
120+
k_sem_give(&ipc_sem);
121+
#else
122+
atomic_set_bit(&ipc_atomic_sem, NRFE_MSPI_CONFIG_TIMER_PTR);
123+
#endif
124+
break;
125+
}
126+
#endif
116127
case NRFE_MSPI_CONFIG_PINS: {
117128
#if defined(CONFIG_MULTITHREADING)
118129
k_sem_give(&ipc_sem_cfg);
@@ -219,6 +230,9 @@ static int nrfe_mspi_wait_for_response(nrfe_mspi_opcode_t opcode, uint32_t timeo
219230
int ret = 0;
220231

221232
switch (opcode) {
233+
case NRFE_MSPI_CONFIG_TIMER_PTR:
234+
ret = k_sem_take(&ipc_sem, K_MSEC(timeout));
235+
break;
222236
case NRFE_MSPI_CONFIG_PINS:
223237
case NRFE_MSPI_CONFIG_DEV:
224238
case NRFE_MSPI_CONFIG_XFER: {
@@ -633,6 +647,16 @@ static int dev_pm_action_cb(const struct device *dev, enum pm_device_action acti
633647
}
634648
#endif
635649

650+
#if defined(CONFIG_MSPI_NRFE_FAULT_TIMER)
651+
static void flpr_fault_handler(const struct device *dev, void *user_data)
652+
{
653+
ARG_UNUSED(dev);
654+
ARG_UNUSED(user_data);
655+
656+
LOG_ERR("SDP fault detected.");
657+
}
658+
#endif
659+
636660
/**
637661
* @brief Initialize the MSPI NRFE driver.
638662
*
@@ -655,6 +679,16 @@ static int nrfe_mspi_init(const struct device *dev)
655679
.config = drv_cfg->mspicfg,
656680
};
657681

682+
#if defined(CONFIG_MSPI_NRFE_FAULT_TIMER)
683+
const struct device *const flpr_fault_timer = DEVICE_DT_GET(DT_NODELABEL(fault_timer));
684+
const struct counter_top_cfg top_cfg = {
685+
.callback = flpr_fault_handler,
686+
.user_data = NULL,
687+
.flags = 0,
688+
.ticks = counter_us_to_ticks(flpr_fault_timer, CONFIG_MSPI_NRFE_FAULT_TIMEOUT)
689+
};
690+
#endif
691+
658692
ret = pinctrl_apply_state(drv_cfg->pcfg, PINCTRL_STATE_DEFAULT);
659693
if (ret) {
660694
return ret;
@@ -691,6 +725,40 @@ static int nrfe_mspi_init(const struct device *dev)
691725
return ret;
692726
}
693727
#endif
728+
729+
#if defined(CONFIG_MSPI_NRFE_FAULT_TIMER)
730+
/* Configure timer as SDP `watchdog` */
731+
if (!device_is_ready(flpr_fault_timer)) {
732+
LOG_ERR("FLPR timer not ready");
733+
return -1;
734+
}
735+
736+
ret = counter_set_top_value(flpr_fault_timer, &top_cfg);
737+
if (ret < 0) {
738+
LOG_ERR("counter_set_top_value() failure");
739+
return ret;
740+
}
741+
742+
/* Send timer address to FLPR */
743+
nrfe_mspi_flpr_timer_msg_t timer_data = {
744+
.opcode = NRFE_MSPI_CONFIG_TIMER_PTR,
745+
.timer_ptr = (NRF_TIMER_Type *)DT_REG_ADDR(DT_NODELABEL(fault_timer)),
746+
};
747+
748+
ret = send_data(NRFE_MSPI_CONFIG_TIMER_PTR, (const void *)&timer_data.opcode,
749+
sizeof(nrfe_mspi_flpr_timer_msg_t));
750+
if (ret < 0) {
751+
LOG_ERR("Send timer configuration failure");
752+
return ret;
753+
}
754+
755+
ret = counter_start(flpr_fault_timer);
756+
if (ret < 0) {
757+
LOG_ERR("counter_start() failure");
758+
return ret;
759+
}
760+
#endif
761+
694762
return ret;
695763
}
696764

include/drivers/mspi/nrfe_mspi.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <zephyr/drivers/pinctrl.h>
1111
#include <zephyr/drivers/mspi.h>
12+
#include <hal/nrf_timer.h>
1213

1314
#ifdef __cplusplus
1415
extern "C" {
@@ -32,10 +33,11 @@ extern "C" {
3233
/** @brief eMSPI opcodes. */
3334
typedef enum {
3435
NRFE_MSPI_EP_BOUNDED = 0,
35-
NRFE_MSPI_CONFIG_PINS, /* nrfe_mspi_pinctrl_soc_pin_msg_t */
36-
NRFE_MSPI_CONFIG_DEV, /* nrfe_mspi_dev_config_msg_t */
37-
NRFE_MSPI_CONFIG_XFER, /* nrfe_mspi_xfer_config_msg_t */
38-
NRFE_MSPI_TX, /* nrfe_mspi_xfer_packet_msg_t + data buffer at the end */
36+
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 */
3941
NRFE_MSPI_TXRX,
4042
NRFE_MSPI_WRONG_OPCODE,
4143
NRFE_MSPI_ALL_OPCODES = NRFE_MSPI_WRONG_OPCODE,
@@ -58,6 +60,11 @@ typedef struct {
5860
uint16_t rx_dummy;
5961
} nrfe_mspi_xfer_config_t;
6062

63+
typedef struct {
64+
nrfe_mspi_opcode_t opcode; /* NRFE_MSPI_CONFIG_TIMER_PTR */
65+
NRF_TIMER_Type *timer_ptr;
66+
} nrfe_mspi_flpr_timer_msg_t;
67+
6168
typedef struct {
6269
nrfe_mspi_opcode_t opcode; /* NRFE_MSPI_CONFIG_PINS */
6370
pinctrl_soc_pin_t pin[NRFE_MSPI_PINS_MAX];

0 commit comments

Comments
 (0)