• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Unionman Technology 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 #undef LOG_TAG
17 #define LOG_TAG "spi_test"
18 
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <securec.h>
24 #include <fcntl.h>
25 #include <sys/ioctl.h>
26 #include <linux/i2c.h>
27 #include <linux/i2c-dev.h>
28 #include <linux/types.h>
29 #include <linux/spi/spidev.h>
30 #include "hilog/log.h"
31 #include "um_spi.h"
32 
33 static unsigned char g_mode = SPI_MODE_0;
34 static unsigned char g_bits = 8;
35 static unsigned int g_speed = 1000000;
36 
sysfs_gpio_export(int s32GpioNum,int bExport)37 void sysfs_gpio_export(int s32GpioNum, int bExport)
38 {
39     char buffer[EXP_MAXSIZ];
40     if (bExport) {
41         (void)snprintf_s(buffer, sizeof(buffer), sizeof(buffer), "echo %d > /sys/class/gpio/export", s32GpioNum);
42     } else {
43         (void)snprintf_s(buffer, sizeof(buffer), sizeof(buffer), "echo %d > /sys/class/gpio/unexport", s32GpioNum);
44     }
45     printf("shl %s\n", buffer);
46     system(buffer);
47 }
48 
sysfs_gpio_direction(int Pin,int Dir)49 int sysfs_gpio_direction(int Pin, int Dir)
50 {
51     const char dir_str[] = "in\0out";
52     char path[DIR_MAXSIZ];
53     int fd = 0;
54     // 初始化设置方向的文件名
55     (void)snprintf_s(path, sizeof(path), DIR_MAXSIZ, "/sys/class/gpio/gpio%d/direction", Pin);
56     // 以只写的方式打开path文件,得到返回值fd
57     // 当文件打开成功时,返回一个非负整数:
58     // 句柄,我们后面对于文件的读写,关闭等都通过句柄来操作;
59     // 句柄可以理解为指向这些文件的指针;
60     // 当文件打开失败时,返回-1
61     fd = open(path, O_WRONLY);
62     if (fd < 0) {
63         HILOG_ERROR(LOG_CORE, "Set Direction failed: Pin%d\n", Pin);
64         return SPI_OPEN_DIRECTION_FAIL;
65     }
66     // 成功打开后当Dir=IN即0时,写in到path文件中
67     // 当Dir=OUT即1时,写out到path文件中
68     // 写失败则报错
69     if (write(fd, &dir_str[Dir == IN ? 0 : 3L], Dir == IN ? 2L : 3L) < 0) {
70         HILOG_ERROR(LOG_CORE, "failed to set direction!\r\n");
71         return SPI_SET_DIRECTION_FAIL;
72     }
73     // 关闭文件
74     close(fd);
75     return SPI_SUCCESS;
76 }
77 
sysfs_gpio_write(int Pin,int value)78 int sysfs_gpio_write(int Pin, int value)
79 {
80     const char s_values_str[] = "01";
81     char path[DIR_MAXSIZ];
82     int fd = 0;
83 
84     (void)snprintf_s(path, sizeof(path), DIR_MAXSIZ, "/sys/class/gpio/gpio%d/value", Pin);
85     fd = open(path, O_WRONLY);
86     if (fd < 0) {
87         HILOG_ERROR(LOG_CORE, "Write failed : Pin%{public}d,value = %{public}d\n", Pin, value);
88         return SPI_OPEN_VALUE_FAIL;
89     }
90 
91     if (write(fd, &s_values_str[value == LOW ? 0 : 1], 1) < 0) {
92         HILOG_ERROR(LOG_CORE, "failed to write value!\n");
93         return SPI_WRITE_VALUE_FAIL;
94     }
95 
96     close(fd);
97     return SPI_SUCCESS;
98 }
99 
spi_open(void)100 int spi_open(void)
101 {
102     int fd = 0, ret = 0;
103     // 以读写的方式打开
104     fd = open(DEFAULT_DEV, O_RDWR);
105     if (fd < 0) {
106         HILOG_ERROR(LOG_CORE, "can not open SPI device\n");
107         return SPI_NOT_OPENED_FAIL;
108     }
109     // 设置spi接口传输字的比特数为8位
110     // SPI_IOC_WR_BITS_PER_WORD或SPI_IOC_RD_BITS_PER_WORD
111     // 传递一个指向字节的指针,该字节将返回(RD)或分配(WR)每个SPI传输字的比特数。
112     ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &g_bits);
113     if (ret == -1) {
114         HILOG_ERROR(LOG_CORE, "can't set bits per word\n");
115         return SPI_SET_MODE_FAIL;
116     }
117     // 得到spi接口传输字的比特数
118     ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &g_bits);
119     if (ret == -1) {
120         HILOG_ERROR(LOG_CORE, "can't get bits per word\n");
121         return SPI_GET_MODE_FAIL;
122     }
123     // SPI_MODE_0模式即(0|0)
124     // 检测是否四种模式都可以设置以及得到模式值
125     ret = ioctl(fd, SPI_IOC_WR_MODE, &g_mode);
126     if (ret == -1) {
127         HILOG_ERROR(LOG_CORE, "can't set spi mode\n");
128         return SPI_SET_MODE_FAIL;
129     }
130     g_mode &= ~SPI_CS_HIGH;
131     g_mode &= ~SPI_NO_CS;
132     ret = ioctl(fd, SPI_IOC_WR_MODE, &g_mode);
133     if (ret == -1) {
134         HILOG_ERROR(LOG_CORE, "can't set spi mode 1\n");
135         return SPI_SET_MODE_FAIL;
136     }
137     g_mode &= ~SPI_LSB_FIRST;
138     ret = ioctl(fd, SPI_IOC_WR_MODE, &g_mode);
139     if (ret == -1) {
140         HILOG_ERROR(LOG_CORE, "can't set spi mode 2\n");
141         return SPI_SET_MODE_FAIL;
142     }
143     ret = ioctl(fd, SPI_IOC_RD_MODE, &g_mode);
144     if (ret == -1) {
145         HILOG_ERROR(LOG_CORE, "can't get spi mode\n");
146         return SPI_GET_MODE_FAIL;
147     }
148     // 设置传输速率
149     ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &g_speed);
150     if (ret == -1) {
151         HILOG_ERROR(LOG_CORE, "can't set max speed hz\n");
152         return SPI_SET_MODE_FAIL;
153     }
154     ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &g_speed);
155     if (ret == -1) {
156         HILOG_ERROR(LOG_CORE, "can't get max speed hz\n");
157         return SPI_GET_MODE_FAIL;
158     }
159     // 返回/dev/spidev0.0文件的话柄
160     return fd;
161 }
162 
spi_read_flashid(void)163 int spi_read_flashid(void)
164 {
165     int ret;
166     int len = 4L;
167     uint8_t readIDCmd[4];
168     uint8_t dataID[4] = {0};
169 
170     // 初始化发送的指令:查看flash的id
171     readIDCmd[0] = 0x9f;
172     readIDCmd[1] = 0x0;
173     readIDCmd[2L] = 0x0;
174     readIDCmd[3L] = 0x0;
175 
176     ret = spi_transfer_fullduplex(readIDCmd, len, dataID);
177     if (ret < 0) {
178         HILOG_ERROR(LOG_CORE, "can't read FlashID\n");
179         return READ_FLASHID_FAIL;
180     }
181     printf("SPI_readFlashID\n");
182     spi_read_data(0, 3L, dataID);
183 
184     return ret;
185 }
186 
spi_read_deviceid(void)187 int spi_read_deviceid(void)
188 {
189     int ret;
190     int len = 6L;
191     uint8_t readIDCmd[4];
192     uint8_t dataID[6L] = {0};
193 
194     // 初始化发送的指令:查看flash的id
195     readIDCmd[0] = 0x90;
196     readIDCmd[1] = 0x0;
197     readIDCmd[2L] = 0x0;
198     readIDCmd[3L] = 0x0;
199 
200     ret = spi_transfer_fullduplex(readIDCmd, len, dataID);
201     if (ret < 0) {
202         HILOG_ERROR(LOG_CORE, "can't read DeviceID\n");
203         return READ_DEVICEID_FAIL;
204     }
205     printf("spi_readDeviceID\n");
206     spi_read_data(4L, len - 1, dataID);
207 
208     return ret;
209 }
210 
read_status_register(uint8_t * data,int len)211 int read_status_register(uint8_t *data, int len)
212 {
213     uint8_t *pData = data;
214     uint8_t readIDCmd[1];
215     const int minlen = 2;
216     int ret;
217     // len=1时在传命令,len=2时,才在传状态寄存器中的值
218     if (data == NULL) {
219         HILOG_ERROR(LOG_CORE, "Data pointer is null\n");
220         return SPI_PARAM_FAIL;
221     }
222     if (len < minlen) {
223         HILOG_ERROR(LOG_CORE, "Parameter len error\n");
224         return SPI_PARAM_FAIL;
225     }
226     // 初始化发送的指令
227     readIDCmd[0] = 0x05;
228 
229     ret = spi_transfer_fullduplex(readIDCmd, len, pData);
230     if (ret < 0) {
231         HILOG_ERROR(LOG_CORE, "can't read Status Register\n");
232         return READ_STATUS_REGISTER_FAIL;
233     }
234     return ret;
235 }
236 
spi_flash_writeenable(void)237 int spi_flash_writeenable(void)
238 {
239     int ret = 0;
240     int len = 1;
241     uint8_t readIDCmd[1];
242     uint8_t data[1] = {0};
243     uint8_t reData[3L] = {0};
244     readIDCmd[0] = 0x06;
245 
246     ret = spi_transfer_fullduplex(readIDCmd, len, data);
247     if (ret < 0) {
248         HILOG_ERROR(LOG_CORE, "can't set write enable\n");
249         return SPI_SET_FLASH_WRITE_ENABLE;
250     }
251     read_status_register(reData, 3L);
252     if ((reData[2L] & 0x02) == 0x02) {
253         printf("set spi flash write enable success\n");
254     } else {
255         HILOG_ERROR(LOG_CORE, "can't set spi flash write enable\n");
256         return SET_WRITEENABLE_FAIL;
257     }
258 
259     return ret;
260 }
261 
spi_read_data(int first,int last,uint8_t * data)262 int spi_read_data(int first, int last, uint8_t *data)
263 {
264     int i = 0;
265     if (data == NULL) {
266         HILOG_ERROR(LOG_CORE, "data pointer is null\n");
267         return SPI_PARAM_FAIL;
268     }
269     if (first > last) {
270         HILOG_ERROR(LOG_CORE, "********************Error:overflow\n");
271         return SPI_PARAM_FAIL;
272     }
273     for (i = first; i <= last; i++) {
274         printf("data[%d]************************************************* = %x\n", i, data[i]);
275     }
276     return SPI_SUCCESS;
277 }
278 
spi_transfer_fullduplex(uint8_t * txbuf,int len,uint8_t * rxbuf)279 int spi_transfer_fullduplex(uint8_t *txbuf, int len, uint8_t *rxbuf)
280 {
281     int ret = 0;
282     int fd = 0;
283     uint8_t *prxbuf = rxbuf;
284     // xfer用于发送指令和接受数据
285     struct spi_ioc_transfer xfer;
286     // 将xfer结构体中的内容全初始化为0
287     (void)memset_s(&xfer, sizeof(xfer), 0, sizeof(xfer));
288     // 发送数据为txbuf
289     xfer.tx_buf = (unsigned long)txbuf;
290     // 接受数据为rxbuf
291     xfer.rx_buf = (unsigned long)prxbuf;
292     // 传输的长度为len
293     xfer.len = len;
294     if (txbuf == NULL) {
295         HILOG_ERROR(LOG_CORE, "txbuf pointer is null\n");
296         return SPI_PARAM_FAIL;
297     }
298     if (rxbuf == NULL) {
299         HILOG_ERROR(LOG_CORE, "rxbuf pointer is null\n");
300         return SPI_PARAM_FAIL;
301     }
302     // 打开spi接口同时初始化
303     fd = spi_open();
304     if (fd < 0) {
305         HILOG_ERROR(LOG_CORE, "fail open device ==================fd = %{public}d\n", fd);
306         return SPI_OPEN_DEVICE_FAIL;
307     }
308     // 输出片选信号 低电平有效
309     // SPI从设备是否被选中的,只有片选信号为预先规定的使能信号时(高电位或低电位),对此 SPI 从设备的操作才有效。
310     sysfs_gpio_write(UM_GPIO_SPI_CS, 0);
311     // SPI_IOC_MESSAGE(1)的1表示spi_ioc_transfer的数量
312     ret = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
313     if (ret < 0) {
314         HILOG_ERROR(LOG_CORE, "********************Error: SPI_IOC_MESSAGE\n");
315         close(fd);
316         return SPI_TRANSFER_FAIL;
317     }
318     // 片选信号变为无效高电平
319     sysfs_gpio_write(UM_GPIO_SPI_CS, 1);
320 
321     close(fd);
322 
323     return ret;
324 }
325 
spi_wait_writeend(void)326 void spi_wait_writeend(void)
327 {
328     // 读取状态寄存器,当最后一位s0为正在擦除/写入(忙)位
329     // 当编程、擦除或写入状态/安全寄存器指令完成时,
330     // 忙位将被清除为0状态,表示设备已准备好接受进一步指令。
331     uint8_t redata[3L] = {0};
332     int len = 3L;
333     // 当忙位为1时,继续读取状态寄存器等待,知道忙位为0,结束等待
334     do {
335         read_status_register(redata, len);
336     } while ((redata[2L] & 0x01) == 0x01);
337 }
338 
spi_sector_erase(uint32_t SectorAddr)339 int spi_sector_erase(uint32_t SectorAddr)
340 {
341     // 初始化擦除指令和地址
342     int ret;
343     int len = 4L;
344     uint8_t readIDCmd[4];
345     uint8_t data[10] = {0};
346 
347     readIDCmd[0] = 0x20;
348     readIDCmd[1] = ((SectorAddr & FLASH_ADDRESS_HIGHT) >> 16L);
349     readIDCmd[2L] = ((SectorAddr & FLASH_ADDRESS_MIDDLE) >> 8L);
350     readIDCmd[3L] = SectorAddr & FLASH_ADDRESS_LOW;
351     // 开写使能
352     spi_flash_writeenable();
353     // 等待写入空闲
354     spi_wait_writeend();
355     ret = spi_transfer_fullduplex(readIDCmd, len, data);
356     if (ret < 0) {
357         HILOG_ERROR(LOG_CORE, "Erase failed\n");
358         return SPI_FLASH_SECTOR_ERASE_FAIL;
359     }
360     spi_wait_writeend();
361     return SPI_SUCCESS;
362 }
363 
spi_page_write(uint8_t * Buffer,uint32_t WriteAddr,uint16_t NumByteToWrite)364 int spi_page_write(uint8_t *Buffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
365 {
366     int ret = 0;
367     uint16_t numByteToWrite = NumByteToWrite;
368     int len = 4L + numByteToWrite;
369     uint8_t readIDCmd[260];
370     uint8_t data[256] = {0};
371     uint8_t *pBuffer = Buffer;
372     readIDCmd[0] = 0x02;
373     readIDCmd[1] = ((WriteAddr & FLASH_ADDRESS_HIGHT) >> 16L);
374     readIDCmd[2L] = ((WriteAddr & FLASH_ADDRESS_MIDDLE) >> 8L);
375     readIDCmd[3L] = WriteAddr & FLASH_ADDRESS_LOW;
376     int i = 4L;
377 
378     if (pBuffer == NULL) {
379         HILOG_ERROR(LOG_CORE, "pBuffer pointer is null\n");
380         return SPI_PARAM_FAIL;
381     }
382     // 写使能
383     spi_flash_writeenable();
384     // 等待写入空闲
385     spi_wait_writeend();
386     // 错误处理
387     if (numByteToWrite > SPI_FLASH_PerWritePageSize) {
388         numByteToWrite = SPI_FLASH_PerWritePageSize;
389         HILOG_ERROR(LOG_CORE, "spi_page_write too large!\n");
390     }
391     while (numByteToWrite--) {
392         readIDCmd[i] = *pBuffer;
393         i++;
394         pBuffer++;
395     }
396     ret = spi_transfer_fullduplex(readIDCmd, len, data);
397     if (ret < 0) {
398         HILOG_ERROR(LOG_CORE, "write failed\n");
399         return SPI_FLASH_PAGE_WRITE_FAIL;
400     }
401     spi_wait_writeend();
402     return SPI_SUCCESS;
403 }
404 
spi_buffer_read(uint8_t * Buffer,uint32_t ReadAddr,uint16_t NumByteToRead)405 int spi_buffer_read(uint8_t *Buffer, uint32_t ReadAddr, uint16_t NumByteToRead)
406 {
407     int ret;
408     int i = 4L;
409     uint16_t numByteToRead = NumByteToRead;
410     int len = 4L + numByteToRead;
411     uint8_t readIDCmd[4];
412     uint8_t *data;
413     uint8_t *pBuffer = Buffer;
414     // 声明一个大小为len的数组
415     data = (uint8_t *)malloc(len * sizeof(uint8_t));
416     readIDCmd[0] = 0x03;
417     readIDCmd[1] = ((ReadAddr & FLASH_ADDRESS_HIGHT) >> 16L);
418     readIDCmd[2L] = ((ReadAddr & FLASH_ADDRESS_MIDDLE) >> 8L);
419     readIDCmd[3L] = ReadAddr & FLASH_ADDRESS_LOW;
420 
421     if (pBuffer == NULL) {
422         HILOG_ERROR(LOG_CORE, "txbuf pointer is null\n");
423         return SPI_PARAM_FAIL;
424     }
425     ret = spi_transfer_fullduplex(readIDCmd, len, data);
426     if (ret < 0) {
427         HILOG_ERROR(LOG_CORE, "read buffer failed\n");
428         return SPI_FLASH_BUFFER_READ_FAIL;
429     }
430     while (numByteToRead--) {
431         *pBuffer = data[i];
432         i++;
433         pBuffer++;
434     }
435     return SPI_SUCCESS;
436 }
437 
spi_buffer_write(uint8_t * Buffer,uint32_t WriteAddr,uint16_t NumByteToWrite)438 int spi_buffer_write(uint8_t *Buffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
439 {
440     int ret = 0;
441     uint8_t *pBuffer = Buffer;
442     uint32_t writeAddr = WriteAddr;
443     uint16_t numByteToWrite = NumByteToWrite;
444     uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
445     // 取模,检查有几页
446     Addr = WriteAddr % SPI_FLASH_PageSize;
447     // 差count 个数值,刚好对齐到页地址
448     count = SPI_FLASH_PageSize - Addr;
449     // 整数页
450     NumOfPage = numByteToWrite / SPI_FLASH_PageSize;
451     // 不满一页的字节数
452     NumOfSingle = numByteToWrite % SPI_FLASH_PageSize;
453     if (pBuffer == NULL) {
454         HILOG_ERROR(LOG_CORE, "txbuf pointer is null\n");
455         return SPI_PARAM_FAIL;
456     }
457     // Addr=0 刚好按页对齐
458     if (Addr == 0) {
459         // numByteToWrite < SPI_FLASH_PageSize
460         if (NumOfPage == 0) {
461             ret = spi_page_write(pBuffer, writeAddr, numByteToWrite);
462             if (ret < 0) {
463                 return SPI_FLASH_PAGE_WRITE_FAIL;
464             }
465             return SPI_SUCCESS;
466         }
467         // 一页写步下 numByteToWrite > SPI_FLASH_PageSize
468         while (NumOfPage--) {
469             ret = spi_page_write(pBuffer, writeAddr, SPI_FLASH_PageSize);
470             if (ret < 0) {
471                 return SPI_FLASH_PAGE_WRITE_FAIL;
472             }
473             writeAddr += SPI_FLASH_PageSize;
474             pBuffer += SPI_FLASH_PageSize;
475         }
476         // 剩余不满的写完
477         ret = spi_page_write(pBuffer, writeAddr, NumOfSingle);
478         if (ret < 0) {
479             return SPI_FLASH_PAGE_WRITE_FAIL;
480         }
481         return SPI_SUCCESS;
482     }
483     // Addr!=0 地址不对齐
484     /* numByteToWrite < SPI_FLASH_PageSize */
485     if (NumOfPage == 0) {
486         ret = spi_less_page_write(pBuffer, writeAddr, numByteToWrite);
487         if (ret < 0) {
488             return SPI_FLASH_PAGE_WRITE_FAIL;
489         }
490         return SPI_SUCCESS;
491     }
492     // Addr!=0 地址不对齐
493     /* numByteToWrite > SPI_FLASH_PageSize */
494     ret = spi_multi_pages_write(pBuffer, writeAddr, numByteToWrite);
495     if (ret < 0) {
496         return SPI_FLASH_PAGE_WRITE_FAIL;
497     }
498     return SPI_SUCCESS;
499 }
500 
spi_multi_pages_write(uint8_t * Buffer,uint32_t WriteAddr,uint16_t NumByteToWrite)501 int spi_multi_pages_write(uint8_t *Buffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
502 {
503     int ret = 0;
504     uint8_t *pBuffer = Buffer;
505     uint32_t writeAddr = WriteAddr;
506     uint16_t numByteToWrite = NumByteToWrite;
507     uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
508     // 取模,检查有几页
509     Addr = WriteAddr % SPI_FLASH_PageSize;
510     // 差count 个数值,刚好对齐到页地址
511     count = SPI_FLASH_PageSize - Addr;
512 
513     // 地址不对齐多出的count分开处理,重新计算页数
514     numByteToWrite -= count;
515     NumOfPage = numByteToWrite / SPI_FLASH_PageSize;
516     NumOfSingle = numByteToWrite % SPI_FLASH_PageSize;
517     // 先写完count个数据
518     ret = spi_page_write(pBuffer, writeAddr, count);
519     if (ret < 0) {
520         return SPI_FLASH_PAGE_WRITE_FAIL;
521     }
522     writeAddr += count;
523     pBuffer += count;
524     // 写整页
525     while (NumOfPage--) {
526         ret = spi_page_write(pBuffer, writeAddr, SPI_FLASH_PageSize);
527         if (ret < 0) {
528             return SPI_FLASH_PAGE_WRITE_FAIL;
529         }
530         writeAddr += SPI_FLASH_PageSize;
531         pBuffer += SPI_FLASH_PageSize;
532     }
533     // 多余不满一页的情况
534     if (NumOfSingle != 0) {
535         ret = spi_page_write(pBuffer, writeAddr, NumOfSingle);
536         if (ret < 0) {
537             return SPI_FLASH_PAGE_WRITE_FAIL;
538         }
539     }
540     return SPI_SUCCESS;
541 }
542 
spi_less_page_write(uint8_t * Buffer,uint32_t WriteAddr,uint16_t NumByteToWrite)543 int spi_less_page_write(uint8_t *Buffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
544 {
545     int ret = 0;
546     uint8_t *pBuffer = Buffer;
547     uint32_t writeAddr = WriteAddr;
548     uint16_t numByteToWrite = NumByteToWrite;
549     uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
550     // 取模,检查有几页
551     Addr = WriteAddr % SPI_FLASH_PageSize;
552     // 差count 个数值,刚好对齐到页地址
553     count = SPI_FLASH_PageSize - Addr;
554     // 整数页
555     NumOfPage = numByteToWrite / SPI_FLASH_PageSize;
556     // 不满一页的字节数
557     NumOfSingle = numByteToWrite % SPI_FLASH_PageSize;
558     // 当前剩余的count比NumOfSingle 小,一页写不完
559     if (NumOfSingle > count) {
560         temp = NumOfSingle - count;
561         // 先写完当页
562         ret = spi_page_write(pBuffer, writeAddr, count);
563         if (ret < 0) {
564             return SPI_FLASH_PAGE_WRITE_FAIL;
565         }
566         writeAddr += count;
567         pBuffer += count;
568         // 写剩余的
569         ret = spi_page_write(pBuffer, writeAddr, temp);
570         if (ret < 0) {
571             return SPI_FLASH_PAGE_WRITE_FAIL;
572         }
573     } else {
574         // 当前的剩余count 能写完numByteToWrite
575         ret = spi_page_write(pBuffer, writeAddr, numByteToWrite);
576         if (ret < 0) {
577             return SPI_FLASH_PAGE_WRITE_FAIL;
578         }
579     }
580     return SPI_SUCCESS;
581 }
582