1 /*
2 * Copyright 2022 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/logging/log.h>
9 #include <zephyr/device.h>
10 #include <zephyr/devicetree.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <zephyr/drivers/mspi.h>
14
15 #define MSPI_BUS DT_BUS(DT_ALIAS(dev0))
16 #define MSPI_TARGET DT_ALIAS(dev0)
17
18 #define BUF_SIZE 1024
19
20 #if CONFIG_MEMC_MSPI_APS6404L
21 #define DEVICE_MEM_WRITE_INSTR 0x38
22 #define DEVICE_MEM_READ_INSTR 0xEB
23 #endif
24
25 uint8_t memc_write_buffer[BUF_SIZE];
26 uint8_t memc_read_buffer[BUF_SIZE];
27
28 struct user_context {
29 uint32_t status;
30 uint32_t total_packets;
31 };
32
async_cb(struct mspi_callback_context * mspi_cb_ctx,uint32_t status)33 void async_cb(struct mspi_callback_context *mspi_cb_ctx, uint32_t status)
34 {
35 volatile struct user_context *usr_ctx = mspi_cb_ctx->ctx;
36
37 mspi_cb_ctx->mspi_evt.evt_data.status = status;
38 if (mspi_cb_ctx->mspi_evt.evt_data.packet_idx == usr_ctx->total_packets - 1) {
39 usr_ctx->status = 0;
40 }
41 }
42
43 struct mspi_xfer_packet packet1[] = {
44 {
45 .dir = MSPI_TX,
46 .cmd = DEVICE_MEM_WRITE_INSTR,
47 .address = 0,
48 .num_bytes = 256,
49 .data_buf = memc_write_buffer,
50 .cb_mask = MSPI_BUS_NO_CB,
51 },
52 {
53 .dir = MSPI_TX,
54 .cmd = DEVICE_MEM_WRITE_INSTR,
55 .address = 256,
56 .num_bytes = 256,
57 .data_buf = memc_write_buffer + 256,
58 .cb_mask = MSPI_BUS_NO_CB,
59 },
60 {
61 .dir = MSPI_TX,
62 .cmd = DEVICE_MEM_WRITE_INSTR,
63 .address = 512,
64 .num_bytes = 256,
65 .data_buf = memc_write_buffer + 512,
66 .cb_mask = MSPI_BUS_NO_CB,
67 },
68 {
69 .dir = MSPI_TX,
70 .cmd = DEVICE_MEM_WRITE_INSTR,
71 .address = 512 + 256,
72 .num_bytes = 256,
73 .data_buf = memc_write_buffer + 512 + 256,
74 .cb_mask = MSPI_BUS_XFER_COMPLETE_CB,
75 },
76 };
77
78 struct mspi_xfer_packet packet2[] = {
79 {
80 .dir = MSPI_RX,
81 .cmd = DEVICE_MEM_READ_INSTR,
82 .address = 0,
83 .num_bytes = 256,
84 .data_buf = memc_read_buffer,
85 .cb_mask = MSPI_BUS_NO_CB,
86 },
87 {
88 .dir = MSPI_RX,
89 .cmd = DEVICE_MEM_READ_INSTR,
90 .address = 256,
91 .num_bytes = 256,
92 .data_buf = memc_read_buffer + 256,
93 .cb_mask = MSPI_BUS_NO_CB,
94 },
95 {
96 .dir = MSPI_RX,
97 .cmd = DEVICE_MEM_READ_INSTR,
98 .address = 512,
99 .num_bytes = 256,
100 .data_buf = memc_read_buffer + 512,
101 .cb_mask = MSPI_BUS_NO_CB,
102 },
103 {
104 .dir = MSPI_RX,
105 .cmd = DEVICE_MEM_READ_INSTR,
106 .address = 512 + 256,
107 .num_bytes = 256,
108 .data_buf = memc_read_buffer + 512 + 256,
109 .cb_mask = MSPI_BUS_XFER_COMPLETE_CB,
110 },
111 };
112
113 struct mspi_xfer xfer1 = {
114 .async = true,
115 .xfer_mode = MSPI_DMA,
116 .tx_dummy = 0,
117 .cmd_length = 1,
118 .addr_length = 3,
119 .priority = 1,
120 .packets = (struct mspi_xfer_packet *)&packet1,
121 .num_packet = sizeof(packet1) / sizeof(struct mspi_xfer_packet),
122 };
123
124 struct mspi_xfer xfer2 = {
125 .async = true,
126 .xfer_mode = MSPI_DMA,
127 .rx_dummy = 6,
128 .cmd_length = 1,
129 .addr_length = 3,
130 .priority = 1,
131 .packets = (struct mspi_xfer_packet *)&packet2,
132 .num_packet = sizeof(packet2) / sizeof(struct mspi_xfer_packet),
133 };
134
main(void)135 int main(void)
136 {
137 const struct device *controller = DEVICE_DT_GET(MSPI_BUS);
138 struct mspi_dev_id dev_id = MSPI_DEVICE_ID_DT(MSPI_TARGET);
139 struct mspi_callback_context cb_ctx1, cb_ctx2;
140 volatile struct user_context write_ctx, read_ctx;
141 int i, j;
142 int ret;
143
144 /* Initialize write buffer */
145 for (i = 0; i < BUF_SIZE; i++) {
146 memc_write_buffer[i] = (uint8_t)i;
147 }
148
149 ret = mspi_dev_config(controller, &dev_id, MSPI_DEVICE_CONFIG_NONE, NULL);
150 if (ret) {
151 printk("Failed to get controller access\n");
152 return 1;
153 }
154
155 write_ctx.total_packets = xfer1.num_packet;
156 write_ctx.status = ~0;
157 cb_ctx1.ctx = (void *)&write_ctx;
158 ret = mspi_register_callback(controller, &dev_id, MSPI_BUS_XFER_COMPLETE,
159 (mspi_callback_handler_t)async_cb, &cb_ctx1);
160 if (ret) {
161 printk("Failed to register callback\n");
162 return 1;
163 }
164
165 ret = mspi_transceive(controller, &dev_id, &xfer1);
166 if (ret) {
167 printk("Failed to send transceive\n");
168 return 1;
169 }
170
171 read_ctx.total_packets = xfer2.num_packet;
172 read_ctx.status = ~0;
173 cb_ctx2.ctx = (void *)&read_ctx;
174 ret = mspi_register_callback(controller, &dev_id, MSPI_BUS_XFER_COMPLETE,
175 (mspi_callback_handler_t)async_cb, &cb_ctx2);
176 if (ret) {
177 printk("Failed to register callback\n");
178 return 1;
179 }
180
181 ret = mspi_transceive(controller, &dev_id, &xfer2);
182 if (ret) {
183 printk("Failed to send transceive\n");
184 return 1;
185 }
186
187 while (write_ctx.status != 0 || read_ctx.status != 0) {
188 printk("Waiting for complete..., write completed:%d, read completed:%d\n",
189 cb_ctx1.mspi_evt.evt_data.packet_idx,
190 cb_ctx2.mspi_evt.evt_data.packet_idx);
191 k_busy_wait(100000);
192 }
193
194 for (j = 0; j < BUF_SIZE; j++) {
195 if (memc_write_buffer[j] != memc_read_buffer[j]) {
196 printk("Error: data differs at offset %d\n", j);
197 break;
198 }
199 }
200 if (j == BUF_SIZE) {
201 printk("Read data matches written data\n");
202 }
203
204 return 0;
205 }
206