• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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