1 /*
2 * Copyright (c) 2024 Ambiq Micro Inc. <www.ambiq.com>
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <zephyr/device.h>
7 #include <zephyr/drivers/gpio.h>
8 #include <zephyr/drivers/mspi.h>
9 #include <zephyr/drivers/mspi_emul.h>
10 #include <zephyr/ztest.h>
11
12 #define TEST_MSPI_REINIT 1
13
14 #define MSPI_BUS_NODE DT_ALIAS(mspi0)
15
16 /* add else if for other SoC platforms */
17 #if defined(CONFIG_SOC_POSIX)
18 typedef struct mspi_timing_cfg mspi_timing_cfg;
19 typedef enum mspi_timing_param mspi_timing_param;
20 #define MSPI_PORT 0
21 #elif defined(CONFIG_SOC_FAMILY_AMBIQ)
22 #include "mspi_ambiq.h"
23 typedef struct mspi_ambiq_timing_cfg mspi_timing_cfg;
24 typedef enum mspi_ambiq_timing_param mspi_timing_param;
25 #define MSPI_PORT ((DT_REG_ADDR(MSPI_BUS_NODE) - MSPI0_BASE) / (MSPI1_BASE - MSPI0_BASE))
26 #else
27 #define MSPI_PORT 0
28 #endif
29
30 static const struct device *mspi_devices[] = {
31 DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, DEVICE_DT_GET, (,))
32 };
33
34 static struct gpio_dt_spec ce_gpios[] = MSPI_CE_GPIOS_DT_SPEC_GET(MSPI_BUS_NODE);
35
36 #if TEST_MSPI_REINIT
37 struct mspi_cfg hardware_cfg = {
38 .channel_num = MSPI_PORT,
39 .op_mode = DT_ENUM_IDX_OR(MSPI_BUS_NODE, op_mode, MSPI_OP_MODE_CONTROLLER),
40 .duplex = DT_ENUM_IDX_OR(MSPI_BUS_NODE, duplex, MSPI_HALF_DUPLEX),
41 .dqs_support = DT_PROP_OR(MSPI_BUS_NODE, dqs_support, false),
42 .ce_group = ce_gpios,
43 .num_ce_gpios = ARRAY_SIZE(ce_gpios),
44 .num_periph = DT_CHILD_NUM(MSPI_BUS_NODE),
45 .max_freq = DT_PROP(MSPI_BUS_NODE, clock_frequency),
46 .re_init = true,
47 };
48 #endif
49
50
51 static struct mspi_dev_id dev_id[] = {
52 DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, MSPI_DEVICE_ID_DT, (,))
53 };
54
55 static struct mspi_dev_cfg device_cfg[] = {
56 DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, MSPI_DEVICE_CONFIG_DT, (,))
57 };
58
59 #if CONFIG_MSPI_XIP
60 static struct mspi_xip_cfg xip_cfg[] = {
61 DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, MSPI_XIP_CONFIG_DT, (,))
62 };
63 #endif
64
65 #if CONFIG_MSPI_SCRAMBLE
66 static struct mspi_scramble_cfg scramble_cfg[] = {
67 DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, MSPI_SCRAMBLE_CONFIG_DT, (,))
68 };
69 #endif
70
ZTEST(mspi_api,test_mspi_api)71 ZTEST(mspi_api, test_mspi_api)
72 {
73 int ret = 0;
74 const struct device *mspi_bus = DEVICE_DT_GET(MSPI_BUS_NODE);
75
76 zassert_true(device_is_ready(mspi_bus), "mspi_bus is not ready");
77
78 #if TEST_MSPI_REINIT
79 const struct mspi_dt_spec spec = {
80 .bus = mspi_bus,
81 .config = hardware_cfg,
82 };
83
84 ret = mspi_config(&spec);
85 zassert_equal(ret, 0, "mspi_config failed.");
86 #endif
87
88 for (int dev_idx = 0; dev_idx < ARRAY_SIZE(mspi_devices); ++dev_idx) {
89
90 zassert_true(device_is_ready(mspi_devices[dev_idx]), "mspi_device is not ready");
91
92 ret = mspi_dev_config(mspi_bus, &dev_id[dev_idx],
93 MSPI_DEVICE_CONFIG_ALL, &device_cfg[dev_idx]);
94 zassert_equal(ret, 0, "mspi_dev_config failed.");
95
96 #if CONFIG_MSPI_XIP
97 ret = mspi_xip_config(mspi_bus, &dev_id[dev_idx], &xip_cfg[dev_idx]);
98 zassert_equal(ret, 0, "mspi_xip_config failed.");
99 #endif
100
101 #if CONFIG_MSPI_SCRAMBLE
102 ret = mspi_scramble_config(mspi_bus, &dev_id[dev_idx], &scramble_cfg[dev_idx]);
103 zassert_equal(ret, 0, "mspi_scramble_config failed.");
104 #endif
105
106 #if CONFIG_MSPI_TIMING
107 mspi_timing_cfg timing_cfg;
108 mspi_timing_param timing_cfg_mask = 0;
109
110 ret = mspi_timing_config(mspi_bus, &dev_id[dev_idx], timing_cfg_mask, &timing_cfg);
111 zassert_equal(ret, 0, "mspi_timing_config failed.");
112 #endif
113
114 ret = mspi_register_callback(mspi_bus, &dev_id[dev_idx],
115 MSPI_BUS_XFER_COMPLETE, NULL, NULL);
116 if (ret == -ENOTSUP) {
117 printf("mspi_register_callback not supported.\n");
118 } else {
119 zassert_equal(ret, 0, "mspi_register_callback failed.");
120 }
121
122 ret = mspi_get_channel_status(mspi_bus, 0);
123 zassert_equal(ret, 0, "mspi_get_channel_status failed.");
124
125 }
126 }
127
128 ZTEST_SUITE(mspi_api, NULL, NULL, NULL, NULL, NULL);
129