1 /*
2 * Copyright (c) 2022 Talkweb Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include "hdf_log.h"
18 #include "spi_if.h"
19 #include "cmsis_os2.h"
20 #include "samgr_lite.h"
21 #include "ohos_run.h"
22
23 #define HDF_SPI_STACK_SIZE 0x1000
24 #define HDF_SPI_TASK_NAME "hdf_spi_test_task"
25 #define HDF_SPI_TASK_PRIORITY 25
26 uint8_t txBuffer[] = "welcome to OpenHarmony\n";
27 #define WIP_FLAG 0x01
28 #define SPI_FLASH_IDx 0x4018
29 #define Countof(a) (sizeof(a)/sizeof(*(a)))
30 #define bufferSize (Countof(txBuffer) - 1)
31
32 uint8_t rxBuffer[bufferSize] = {0};
33 #define USE_TRANSFER_API 1
34
BufferCmp(uint8_t * pBuffer1,uint8_t * pBuffer2,uint16_t BufferLength)35 static uint8_t BufferCmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
36 {
37 while (BufferLength--) {
38 if (*pBuffer1 != *pBuffer2) {
39 return 0;
40 }
41 pBuffer1++;
42 pBuffer2++;
43 }
44 return 1;
45 }
46
47 #if (USE_TRANSFER_API == 1)
ReadDeviceId(DevHandle spiHandle)48 static uint16_t ReadDeviceId(DevHandle spiHandle)
49 {
50 struct SpiMsg msg;
51 uint16_t deviceId = 0;
52 uint8_t rbuff[5] = { 0 };
53 uint8_t wbuff[5] = { 0xAB, 0xFF, 0xFF, 0xFF, 0xFF };
54 int32_t ret = 0;
55 msg.wbuf = wbuff;
56 msg.rbuf = rbuff;
57 msg.len = sizeof(wbuff);
58 msg.keepCs = 0;
59 msg.delayUs = 0;
60 ret = SpiTransfer(spiHandle, &msg, 1);
61 if (ret != 0) {
62 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
63 } else {
64 deviceId = rbuff[4];
65 }
66
67 return deviceId;
68 }
69
ReadFlashId(DevHandle spiHandle)70 static uint16_t ReadFlashId(DevHandle spiHandle)
71 {
72 int32_t ret = 0;
73 uint16_t flashId = 0;
74 uint8_t rbuff1[4] = { 0 };
75 uint8_t wbuff1[4] = { 0x9f, 0xFF, 0xFF, 0xFF };
76 struct SpiMsg msg1 = {0};
77 msg1.wbuf = wbuff1;
78 msg1.rbuf = rbuff1;
79 msg1.len = sizeof(wbuff1);
80 msg1.keepCs = 0;
81 msg1.delayUs = 0;
82 ret = SpiTransfer(spiHandle, &msg1, 1);
83 if (ret != 0) {
84 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
85 } else {
86 flashId = (msg1.rbuf[2]<<8)|msg1.rbuf[3];
87 }
88 return flashId;
89 }
90
WaitForWriteEnd(DevHandle spiHandle)91 static void WaitForWriteEnd(DevHandle spiHandle)
92 {
93 uint8_t FLASH_Status = 0;
94 /* Send "Read Status Register" instruction */
95 uint8_t wbuf[1] = {0x05};
96 uint8_t wbuf1[1] = {0xff};
97 uint8_t rbuf[1] = {0};
98 struct SpiMsg msg = {0};
99 msg.wbuf = wbuf;
100 msg.rbuf = rbuf;
101 msg.len = sizeof(wbuf);
102 msg.keepCs = 1;
103 msg.delayUs = 0;
104 int32_t ret = SpiTransfer(spiHandle, &msg, 1);
105 if (ret != 0) {
106 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
107 }
108
109 /* Loop as long as the memory is busy with a write cycle */
110 do {
111 msg.wbuf = wbuf1;
112 msg.rbuf = rbuf;
113 msg.len = sizeof(wbuf1);
114 msg.keepCs = 1;
115 msg.delayUs = 0;
116
117 ret = SpiTransfer(spiHandle, &msg, 1);
118 if (ret != 0) {
119 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
120 }
121 FLASH_Status = rbuf[0];
122 }
123 while ((FLASH_Status & WIP_FLAG) == 1); /* Write in progress */
124 msg.wbuf = wbuf1;
125 msg.rbuf = rbuf;
126 msg.len = sizeof(wbuf1);
127 msg.keepCs = 0;
128 msg.delayUs = 0;
129 ret = SpiTransfer(spiHandle, &msg, 1);
130 if (ret != 0) {
131 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
132 }
133 }
134
WriteEnable(DevHandle spiHandle)135 static void WriteEnable(DevHandle spiHandle)
136 {
137 uint8_t wbuf[1] = {0x06};
138 uint8_t rbuf[1] = {0};
139 struct SpiMsg msg = {0};
140 msg.wbuf = wbuf;
141 msg.rbuf = rbuf;
142 msg.len = sizeof(wbuf);
143 msg.keepCs = 0;
144 msg.delayUs = 0;
145 int32_t ret = SpiTransfer(spiHandle, &msg, 1);
146 if (ret != 0) {
147 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
148 }
149 }
150
BufferWrite(DevHandle spiHandle,const uint8_t * buf,uint32_t size)151 static void BufferWrite(DevHandle spiHandle, const uint8_t* buf, uint32_t size)
152 {
153 WriteEnable(spiHandle);
154 uint8_t wbuf[4] = {0x02, 0x00, 0x00, 0x00};
155 uint8_t rbuf[4] = {0};
156 uint8_t *rbuf1 = NULL;
157 int32_t ret = 0;
158
159 struct SpiMsg msg = {0};
160 msg.wbuf = wbuf;
161 msg.rbuf = rbuf;
162 msg.len = sizeof(wbuf);
163 msg.keepCs = 1;
164 msg.delayUs = 0;
165 ret = SpiTransfer(spiHandle, &msg, 1);
166 if (ret != 0) {
167 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
168 }
169
170 rbuf1 = (uint8_t*)OsalMemAlloc(size);
171 if (rbuf1 == NULL) {
172 HDF_LOGE("OsalMemAlloc failed.\n");
173 return;
174 }
175
176 memset_s(rbuf1, size, 0, size);
177 msg.wbuf = buf;
178 msg.rbuf = rbuf1;
179 msg.len = size;
180 msg.keepCs = 0;
181 msg.delayUs = 0;
182 ret = SpiTransfer(spiHandle, &msg, 1);
183 if (ret != 0) {
184 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
185 }
186
187 WaitForWriteEnd(spiHandle);
188
189 OsalMemFree(rbuf1);
190 }
191
BufferRead(DevHandle spiHandle,uint8_t * buf,uint32_t size)192 static void BufferRead(DevHandle spiHandle, uint8_t* buf, uint32_t size)
193 {
194 int32_t ret = 0;
195
196 uint8_t wbuf[4] = {0x03, 0x00, 0x00, 0x00};
197 uint8_t rbuf[4] = {0};
198 struct SpiMsg msg = {0};
199 msg.wbuf = wbuf;
200 msg.rbuf = rbuf;
201 msg.len = sizeof(wbuf);
202 msg.keepCs = 1;
203 msg.delayUs = 0;
204 ret = SpiTransfer(spiHandle, &msg, 1);
205 if (ret != 0) {
206 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
207 return;
208 }
209 uint8_t *wbuf1 = (uint8_t*)OsalMemAlloc(size);
210 if (wbuf1 == NULL) {
211 HDF_LOGE("OsalMemAlloc failed.\n");
212 return;
213 }
214 memset_s(wbuf1, size, 0xff, size);
215 msg.wbuf = wbuf1;
216 msg.rbuf = buf;
217 msg.len = size;
218 msg.keepCs = 0;
219 msg.delayUs = 0;
220 ret = SpiTransfer(spiHandle, &msg, 1);
221 if (ret != 0) {
222 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
223 return;
224 }
225
226 OsalMemFree(wbuf1);
227 }
228
SectorErase(DevHandle spiHandle)229 static void SectorErase(DevHandle spiHandle)
230 {
231 WriteEnable(spiHandle);
232 WaitForWriteEnd(spiHandle);
233 uint8_t wbuf[4] = {0x20, 0x00, 0x00, 0x00};
234 uint8_t rbuf[4] = {0};
235 struct SpiMsg msg = {0};
236 msg.wbuf = wbuf;
237 msg.rbuf = rbuf;
238 msg.len = sizeof(wbuf);
239 msg.keepCs = 0;
240 msg.delayUs = 0;
241 int32_t ret = SpiTransfer(spiHandle, &msg, 1);
242 if (ret != 0) {
243 HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
244 return;
245 }
246 WaitForWriteEnd(spiHandle);
247 }
248 #else
ReadDeviceId(DevHandle spiHandle)249 static uint16_t ReadDeviceId(DevHandle spiHandle)
250 {
251 struct SpiMsg msg;
252 uint16_t deviceId = 0;
253 uint8_t rbuff1[2] = { 0 };
254 uint8_t wbuff1[5] = {0x00, 0xAB, 0xff, 0xff, 0xff};
255 int32_t ret = 0;
256
257 ret =SpiWrite(spiHandle, wbuff1, 5);
258 if (ret != 0) {
259 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
260 }
261 rbuff1[0] = 0x01;
262 ret = SpiRead(spiHandle, rbuff1, 2);
263 if (ret != 0) {
264 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
265 }
266
267 deviceId = rbuff1[1];
268
269 return deviceId;
270 }
271
ReadFlashId(DevHandle spiHandle)272 static uint16_t ReadFlashId(DevHandle spiHandle)
273 {
274 int32_t ret = 0;
275 uint16_t flashId = 0;
276 uint8_t wbuff[2] = {0x00, 0x9f};
277 uint8_t rbuff[4] = {0};
278 ret =SpiWrite(spiHandle, wbuff, sizeof(wbuff));
279 if (ret != 0) {
280 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
281 }
282 rbuff[0] = 0x01;
283 ret = SpiRead(spiHandle, rbuff, 4);
284 if (ret != 0) {
285 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
286 }
287 flashId = (rbuff[2] << 8)|rbuff[3];
288 return flashId;
289 }
290
WaitForWriteEnd(DevHandle spiHandle)291 static void WaitForWriteEnd(DevHandle spiHandle)
292 {
293 uint8_t FLASH_Status = 0;
294 int32_t ret = 0;
295 uint8_t wbuff[2] = {0x00, 0x05};
296 uint8_t rbuff[2] = {0};
297 ret =SpiWrite(spiHandle, wbuff, sizeof(wbuff));
298 if (ret != 0) {
299 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
300 }
301 do {
302 rbuff[0] = 0;
303 ret = SpiRead(spiHandle, rbuff, 2);
304 if (ret != 0) {
305 HDF_LOGE("SpiRead: failed, ret %d\n", ret);
306 }
307 FLASH_Status = rbuff[1];
308 } while ((FLASH_Status & WIP_FLAG) == 1); /* Write in progress */
309
310 uint8_t wbuff1[1] = {0x01};
311 ret =SpiWrite(spiHandle, wbuff1, sizeof(wbuff1));
312 if (ret != 0) {
313 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
314 }
315 }
WriteEnable(DevHandle spiHandle)316 static void WriteEnable(DevHandle spiHandle)
317 {
318 uint8_t FLASH_Status = 0;
319 int32_t ret = 0;
320 uint8_t wbuff[2] = {0x01, 0x06};
321 ret =SpiWrite(spiHandle, wbuff, sizeof(wbuff));
322 if (ret != 0) {
323 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
324 }
325
326 return;
327 }
328
BufferWrite(DevHandle spiHandle,const uint8_t * buf,uint32_t size)329 static void BufferWrite(DevHandle spiHandle, const uint8_t* buf, uint32_t size)
330 {
331 WriteEnable(spiHandle);
332 uint8_t wbuf[5] = {0x01, 0x02, 0x00, 0x00, 0x00};
333 uint8_t rbuf[4] = {0};
334 uint8_t *wbuf1 = NULL;
335 int32_t ret = 0;
336 wbuf1 = (uint8_t*)OsalMemAlloc(size + sizeof(wbuf));
337
338 ret = strncpy_s(wbuf1, size + sizeof(wbuf), wbuf, sizeof(wbuf));
339 if (ret < 0) {
340 HDF_LOGE("strncpy wbuf failed, ret %d\n", ret);
341 }
342 ret = strncpy_s(wbuf1 + sizeof(wbuf), size, buf, size);
343 if (ret < 0) {
344 HDF_LOGE("strncpy buf failed, ret %d\n", ret);
345 }
346 ret = SpiWrite(spiHandle, wbuf1, size + sizeof(wbuf));
347 if (ret != 0) {
348 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
349 }
350
351 WaitForWriteEnd(spiHandle);
352 if (wbuf1!= NULL) {
353 OsalMemFree(wbuf1);
354 }
355 }
356
BufferRead(DevHandle spiHandle,uint8_t * buf,uint32_t size)357 static void BufferRead(DevHandle spiHandle, uint8_t* buf, uint32_t size)
358 {
359 WriteEnable(spiHandle);
360 uint8_t wbuf[5] = {0x00, 0x03, 0x00, 0x00, 0x00};
361 uint8_t *rbuf = NULL;
362 int32_t ret = 0;
363 rbuf = (uint8_t*)OsalMemAlloc(size + 1);
364
365 ret = SpiWrite(spiHandle, wbuf, sizeof(wbuf));
366 if (ret != 0) {
367 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
368 }
369 rbuf[0] = 0x01;
370 ret = SpiRead(spiHandle, rbuf, size + 1);
371 if (ret != 0) {
372 HDF_LOGE("SpiRead: failed, ret %d\n", ret);
373 }
374
375 strncpy_s(buf, size, rbuf + 1, size);
376
377 if (rbuf!= NULL) {
378 OsalMemFree(rbuf);
379 }
380
381 return;
382 }
383
SectorErase(DevHandle spiHandle)384 static void SectorErase(DevHandle spiHandle)
385 {
386 WriteEnable(spiHandle);
387 WaitForWriteEnd(spiHandle);
388 uint8_t wbuf[5] = {0x01, 0x20, 0x00, 0x00, 0x00};
389 uint8_t rbuf[5] = {0};
390 int32_t ret = 0;
391 ret = SpiWrite(spiHandle, wbuf, sizeof(wbuf));
392 if (ret != 0) {
393 HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
394 }
395 WaitForWriteEnd(spiHandle);
396 }
397
398 #endif
399
HdfSpiTestEntry(void * arg)400 static void* HdfSpiTestEntry(void* arg)
401 {
402 (void)arg;
403 #ifdef USE_SET_CFG
404 int32_t ret;
405 struct SpiCfg cfg;
406 #endif
407 uint16_t flashId = 0;
408 uint16_t deviceId = 0;
409 struct SpiDevInfo spiDevinfo;
410 DevHandle spiHandle;
411 spiDevinfo.busNum = 0;
412 spiDevinfo.csNum = 0;
413 spiHandle = SpiOpen(&spiDevinfo);
414 if (spiHandle == NULL) {
415 HDF_LOGE("SpiOpen: failed\n");
416 return NULL;
417 }
418 #ifdef USE_SET_CFG
419 ret = SpiGetCfg(spiHandle, &cfg);
420 if (ret != 0) {
421 HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret);
422 goto err;
423 }
424 HDF_LOGI("speed:%d, bitper:%d, mode:%d, transMode:%d\n", cfg.maxSpeedHz, cfg.bitsPerWord, cfg.mode, \
425 cfg.transferMode);
426 cfg.maxSpeedHz = 1;
427 cfg.bitsPerWord = 8;
428 cfg.mode = 0;
429 cfg.transferMode = 1;
430 ret = SpiSetCfg(spiHandle, &cfg);
431 if (ret != 0) {
432 HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret);
433 goto err;
434 }
435 SpiClose(spiHandle);
436 spiHandle = SpiOpen(&spiDevinfo);
437 if (spiHandle == NULL) {
438 HDF_LOGE("SpiOpen: failed\n");
439 return NULL;
440 }
441 #endif
442 deviceId = ReadDeviceId(spiHandle);
443 HDF_LOGI("read device id is 0x%02x\n", deviceId);
444 flashId = ReadFlashId(spiHandle);
445 HDF_LOGI("read flash id is 0x%02x\n", flashId);
446
447 if (flashId == SPI_FLASH_IDx) {
448 SectorErase(spiHandle);
449 BufferWrite(spiHandle, txBuffer, bufferSize);
450 HDF_LOGI("send buffer is %s\n", txBuffer);
451 BufferRead(spiHandle, rxBuffer, bufferSize);
452 HDF_LOGI("recv send buffer is %s\n", rxBuffer);
453
454 if (BufferCmp(txBuffer, rxBuffer, bufferSize)) {
455 HDF_LOGI("hdf spi write read flash success\n");
456 } else {
457 HDF_LOGI("hdf spi write read flash failed\n");
458 }
459 }
460 #ifdef USE_SET_CFG
461 err:
462 #endif
463 SpiClose(spiHandle);
464 return NULL;
465 }
466
StartHdfSpiTest(void)467 void StartHdfSpiTest(void)
468 {
469 osThreadAttr_t attr;
470
471 attr.name = HDF_SPI_TASK_NAME;
472 attr.attr_bits = 0U;
473 attr.cb_mem = NULL;
474 attr.cb_size = 0U;
475 attr.stack_mem = NULL;
476 attr.stack_size = HDF_SPI_STACK_SIZE;
477 attr.priority = HDF_SPI_TASK_PRIORITY;
478
479 if (osThreadNew((osThreadFunc_t)HdfSpiTestEntry, NULL, &attr) == NULL) {
480 printf("Failed to create thread1!\n");
481 }
482 }
483
484 OHOS_APP_RUN(StartHdfSpiTest);
485