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