• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
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 /**
17  * @file    wm_internal_fls.c
18  *
19  * @brief   flash Driver Module
20  *
21  * @author  dave
22  *
23  * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
24  */
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include "wm_dbg.h"
29 #include "wm_mem.h"
30 #include "list.h"
31 #include "wm_regs.h"
32 #include "wm_internal_flash.h"
33 #include "wm_flash_map.h"
34 
35 static struct tls_inside_fls *inside_fls = NULL;
36 
37 /**System parameter, default for 2M flash*/
38 unsigned int  TLS_FLASH_PARAM_DEFAULT        =          (0x81FB000UL);
39 unsigned int  TLS_FLASH_PARAM1_ADDR          =          (0x81FC000UL);
40 unsigned int  TLS_FLASH_PARAM2_ADDR          =          (0x81FD000UL);
41 unsigned int  TLS_FLASH_PARAM_RESTORE_ADDR   =          (0x81FE000UL);
42 unsigned int  TLS_FLASH_OTA_FLAG_ADDR        =          (0x81FF000UL);
43 unsigned int  TLS_FLASH_END_ADDR             =          (0x81FFFFFUL);
44 
read_first_value(void)45 static vu32 read_first_value(void)
46 {
47     return M32(RSA_BASE_ADDRESS);
48 }
49 
writeEnable(void)50 static void writeEnable(void)
51 {
52     M32(HR_FLASH_CMD_ADDR) = 0x6;
53     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
54 }
55 
readRID(void)56 unsigned char readRID(void)
57 {
58     M32(HR_FLASH_CMD_ADDR) = 0x2c09F;
59     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
60     return read_first_value() & 0xFF;
61 }
62 
writeBpBit_for_1wreg(char cmp,char bp4,char bp3,char bp2,char bp1,char bp0)63 static void writeBpBit_for_1wreg(char cmp, char bp4, char bp3, char bp2, char bp1, char bp0)
64 {
65     int status = 0;
66     int bpstatus = 0;
67 
68     M32(HR_FLASH_CMD_ADDR) = 0x0C005;
69     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
70     status =  read_first_value() & 0xFF;
71 
72     M32(HR_FLASH_CMD_ADDR) = 0x0C035;
73     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
74     status  |=  (read_first_value() & 0xFF) << 8;
75 
76     /* Write Enable */
77     M32(HR_FLASH_CMD_ADDR) = 0x6;
78     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
79 
80     bpstatus  = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
81     status      = (status & 0xBF83) | bpstatus | (cmp << 14);
82 
83     M32(RSA_BASE_ADDRESS)  = status;
84     M32(HR_FLASH_CMD_ADDR) = 0x1A001;
85     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
86 }
87 
writeBpBit_for_2wreg(char cmp,char bp4,char bp3,char bp2,char bp1,char bp0)88 static void writeBpBit_for_2wreg(char cmp, char bp4, char bp3, char bp2, char bp1, char bp0)
89 {
90     int status = 0;
91     int bpstatus = 0;
92 
93     M32(HR_FLASH_CMD_ADDR) = 0x0C005;
94     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
95     status =  read_first_value() & 0xFF;
96 
97     M32(HR_FLASH_CMD_ADDR) = 0x0C035;
98     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
99     status  |=  (read_first_value() & 0xFF) << 8;
100 
101     /* Write Enable */
102     M32(HR_FLASH_CMD_ADDR) = 0x6;
103     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
104 
105     bpstatus  = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
106     bpstatus      = (status & 0x83) | bpstatus;
107 
108     M32(RSA_BASE_ADDRESS)  = bpstatus;
109     M32(HR_FLASH_CMD_ADDR) = 0xA001;
110     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
111 
112     M32(HR_FLASH_CMD_ADDR) = 0x6;
113     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
114 
115     status      = ((status>>8) & 0xBF) | (cmp << 6);
116     M32(RSA_BASE_ADDRESS)   = status;
117     M32(HR_FLASH_CMD_ADDR)  = 0xA031;
118     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
119 }
120 
writeESMTBpBit(char cmp,char bp4,char bp3,char bp2,char bp1,char bp0)121 static void writeESMTBpBit(char cmp, char bp4, char bp3, char bp2, char bp1, char bp0)
122 {
123     int status = 0;
124     int bpstatus = 0;
125 
126     M32(HR_FLASH_CMD_ADDR) = 0x0C005;
127     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
128     status =  read_first_value() & 0xFF;
129     bpstatus  = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
130     status      = (status & 0x83) | bpstatus;
131 
132     /* Write Enable */
133     M32(HR_FLASH_CMD_ADDR) = 0x6;
134     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
135 
136     bpstatus  = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
137     status      = (status & 0x83) | bpstatus | (cmp << 14);
138 
139     M32(RSA_BASE_ADDRESS)  = status;
140     M32(HR_FLASH_CMD_ADDR) = 0x0A001;
141     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
142 
143     M32(HR_FLASH_CMD_ADDR) = 0x0C085;
144     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
145     status  =  read_first_value() & 0xFF;
146 
147     /* Write Enable */
148     M32(HR_FLASH_CMD_ADDR) = 0x6;
149     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
150 
151     status        = (status & 0xBF) | (cmp << 6);
152     M32(RSA_BASE_ADDRESS)  = status;
153     M32(HR_FLASH_CMD_ADDR) = 0x0A0C1;
154     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
155 }
156 
flashunlock(void)157 static int flashunlock(void)
158 {
159     switch (readRID()) {
160         case SPIFLASH_MID_GD:
161         case SPIFLASH_MID_TSINGTENG:
162             writeBpBit_for_1wreg(0, 0, 0, 0, 0, 0);
163             break;
164         case SPIFLASH_MID_PUYA:
165         case SPIFLASH_MID_XTX:
166         case SPIFLASH_MID_BOYA:
167         case SPIFLASH_MID_FUDANMICRO:
168         case SPIFLASH_MID_XMC:
169             writeBpBit_for_2wreg(0, 0, 0, 0, 0, 0);
170             break;
171         case SPIFLASH_MID_ESMT:
172             writeESMTBpBit(0, 0, 0, 0, 0, 0);
173             break;
174         default:
175             return -1;
176     }
177     return 0;
178 }
179 
flashlock(void)180 static int flashlock(void)
181 {
182     switch (readRID()) {
183         case SPIFLASH_MID_GD:
184         case SPIFLASH_MID_TSINGTENG:
185             writeBpBit_for_1wreg(0, 1, 1, 0, 1, 0);
186             break;
187         case SPIFLASH_MID_PUYA:
188         case SPIFLASH_MID_XTX:
189         case SPIFLASH_MID_BOYA:
190         case SPIFLASH_MID_FUDANMICRO:
191         case SPIFLASH_MID_XMC:
192             writeBpBit_for_2wreg(0, 1, 1, 0, 1, 0);
193             break;
194         case SPIFLASH_MID_ESMT:
195             writeESMTBpBit(0, 1, 1, 0, 1, 0);
196             break;
197         default:
198             return -1; /* do not clear QIO Mode */
199     }
200     return 0;
201 }
202 
writeLbBit_for_1wreg(unsigned int val)203 static void writeLbBit_for_1wreg(unsigned int val)
204 {
205     int status = 0;
206 
207     M32(HR_FLASH_CMD_ADDR) = 0x0C005;
208     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
209     status =  read_first_value() & 0xFF;
210 
211     M32(HR_FLASH_CMD_ADDR) = 0x0C035;
212     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
213     status  |=  (read_first_value() & 0xFF) << 8;
214 
215     /* Write Enable */
216     M32(HR_FLASH_CMD_ADDR) = 0x6;
217     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
218 
219     status |= (val);
220 
221     M32(RSA_BASE_ADDRESS)  = status;
222     M32(HR_FLASH_CMD_ADDR) = 0x1A001;
223     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
224 }
225 
writeLbBit_for_2wreg(unsigned int val)226 static void writeLbBit_for_2wreg(unsigned int val)
227 {
228     int status = 0;
229 
230     M32(HR_FLASH_CMD_ADDR) = 0x0C005;
231     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
232     status =  read_first_value() & 0xFF;
233 
234     M32(HR_FLASH_CMD_ADDR) = 0x0C035;
235     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
236     status  |=  (read_first_value() & 0xFF) << 8;
237 
238     /* Write Enable */
239     M32(HR_FLASH_CMD_ADDR) = 0x6;
240     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
241 
242     status |= (val);
243     status      = (status>>8);
244     M32(RSA_BASE_ADDRESS)   = status;
245     M32(HR_FLASH_CMD_ADDR)  = 0xA031;
246     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
247 }
248 
programSR(unsigned int cmd,unsigned long addr,unsigned char * buf,unsigned int sz)249 static int programSR(unsigned int  cmd, unsigned long addr, unsigned char *buf,  unsigned int sz)
250 {
251     unsigned long base_addr = 0;
252     unsigned int size = 0;
253     unsigned char *buf_tmp = buf;
254     if (sz > INSIDE_FLS_PAGE_SIZE) {
255         sz = INSIDE_FLS_PAGE_SIZE;
256     }
257 
258     base_addr = RSA_BASE_ADDRESS;
259     size = sz;
260     while (size) {
261         M32(base_addr) = *((unsigned long *)buf_tmp);
262         base_addr += 4; // 4:byte alignment
263         buf_tmp += 4; // 4:byte alignment
264         size -= 4; // 4:byte alignment
265     }
266 
267     writeEnable();
268     M32(HR_FLASH_CMD_ADDR) = cmd | ((sz - 1) << 16); // 16:byte alignment
269     M32(HR_FLASH_ADDR) = (addr & 0x1FFFFFF);
270     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
271 
272     return 0;
273 }
274 
programPage(unsigned long adr,unsigned long sz,unsigned char * buf)275 static int programPage (unsigned long adr, unsigned long sz, unsigned char *buf)
276 {
277     programSR(0x80009002, adr, buf, sz);
278     return(0);
279 }
280 
eraseSR(unsigned int cmd,unsigned long addr)281 static int eraseSR(unsigned int cmd, unsigned long addr)
282 {
283     /* Write Enable */
284     writeEnable();
285     M32(HR_FLASH_CMD_ADDR) = cmd;
286     M32(HR_FLASH_ADDR) = (addr & 0x1FFFFFF);
287     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
288 
289     return 0;
290 }
291 
eraseSector(unsigned long adr)292 static int eraseSector (unsigned long adr)
293 {
294     eraseSR(0x80000820, adr);
295 
296     return (0);                                                  // Finished without Errors
297 }
298 
299 /* only for w800 c400 flash */
erasePage(unsigned long addr)300 static int erasePage (unsigned long addr)
301 {
302     eraseSR(0x80000881, addr);
303     return (0);                                                  // Finished without Errors
304 }
305 
getFlashDensity(void)306 static unsigned int getFlashDensity(void)
307 {
308     unsigned char density = 0;
309 
310     M32(HR_FLASH_CMD_ADDR) = 0x2c09F;
311     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
312 
313     density = ((read_first_value() & 0xFFFFFF) >> 16) & 0xFF;
314     if (density && (density <= 28)) {
315         return (1 << density);
316     }
317 
318     return 0;
319 }
320 
__readByCMD(unsigned char cmd,unsigned long addr,unsigned char * buf,unsigned long sz)321 int __readByCMD(unsigned char cmd, unsigned long addr, unsigned char *buf, unsigned long sz)
322 {
323     int i = 0;
324     int word = sz / 4; // 4:byte alignment
325     int byte = sz % 4; // 4:byte alignment
326     unsigned char cmd_tmp = cmd;
327     unsigned char *buf_tmp = buf;
328     unsigned long addr_read;
329     if (!(M32(HR_FLASH_CR)&0x1)) { /* non-QIO mode, only single line command can be used */
330         if (cmd_tmp > 0x0B) {
331             cmd_tmp = 0x0B;
332         }
333     }
334 
335     switch (cmd_tmp) {
336         case 0x03:
337             M32(HR_FLASH_CMD_ADDR) = 0x8000C003 | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
338             M32(HR_FLASH_ADDR) = addr & 0x1FFFFFF;
339             M32(HR_FLASH_CMD_START) = CMD_START_Msk;
340             break;
341         case 0x0B:
342             if ((M32(HR_FLASH_CR) & 0x2) == 0x2) {
343                 M32(HR_FLASH_CMD_ADDR) = 0xB400C00B | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
344             } else {
345                 M32(HR_FLASH_CMD_ADDR) = 0xBC00C00B | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
346             }
347             M32(HR_FLASH_ADDR) = addr & 0x1FFFFFF;
348             M32(HR_FLASH_CMD_START) = CMD_START_Msk;
349             break;
350         case 0xBB:
351             M32(HR_FLASH_CMD_ADDR) = 0xE400C0BB | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
352             M32(HR_FLASH_ADDR) = addr & 0x1FFFFFF;
353             M32(HR_FLASH_CMD_START) = CMD_START_Msk;
354             break;
355 
356         case 0xEB:
357             M32(HR_FLASH_CMD_ADDR) = 0xEC00C0EB | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
358             M32(HR_FLASH_ADDR) = addr & 0x1FFFFFF;
359             M32(HR_FLASH_CMD_START) = CMD_START_Msk;
360             break;
361 
362         default:
363             return -1;
364     }
365     addr_read = RSA_BASE_ADDRESS;
366     for (i = 0; i < word; i ++) {
367         M32(buf_tmp) = M32(addr_read);
368         buf_tmp += 4; // 4:byte alignment
369         addr_read += 4; // 4:byte alignment
370     }
371 
372     if (byte > 0) {
373         M32(buf_tmp) = M32(addr_read);
374         buf_tmp += 3;                            // 3:point last byte
375         byte = 4 - byte; // 4:byte alignment
376         while (byte) {
377             *buf_tmp = 0;
378             buf_tmp --;
379             byte --;
380         }
381     }
382     return 0;
383 }
384 
385 /**
386  * @brief          This function is used to read data from the flash.
387  *
388  * @param[in]      cmd                 0xEB in QSPI mode; 0x0b in SPI mode.
389  * @param[in]      addr                is byte offset addr for read from the flash.
390  * @param[in]      buf                 is user for data buffer of flash read
391  * @param[in]      len                 is byte length for read.
392  *
393  * @retval         TLS_FLS_STATUS_OK        if read sucsess
394  * @retval         TLS_FLS_STATUS_EPERM        if inside fls does not initialized.
395  *
396  * @note           None
397  */
readByCMD(unsigned char cmd,unsigned long addr,unsigned char * buf,unsigned long sz)398 int readByCMD(unsigned char cmd, unsigned long addr, unsigned char *buf, unsigned long sz)
399 {
400     if (inside_fls == NULL) {
401         return TLS_FLS_STATUS_EPERM;
402     }
403 
404     tls_os_sem_acquire(inside_fls->fls_lock, 0);
405     __readByCMD(cmd, addr, buf, sz);
406     tls_os_sem_release(inside_fls->fls_lock);
407     return TLS_FLS_STATUS_OK;
408 }
409 
flashRead(unsigned long addr,unsigned char * buf,unsigned long sz)410 int flashRead(unsigned long addr, unsigned char *buf, unsigned long sz)
411 {
412 #define INSIDE_FLS_MAX_RD_SIZE (1024)
413 
414     unsigned int flash_addr;
415     unsigned int sz_pagenum = 0;
416     unsigned int sz_remain = 0;
417     int i = 0;
418     int page_offset = addr & (INSIDE_FLS_PAGE_SIZE - 1);
419     unsigned char *buf_tmp = buf;
420 
421     if ((page_offset == 0)
422         && (((unsigned int)buf_tmp&0x3) == 0)
423         && ((sz&0x3) == 0)) { /* Use 4-bytes aligned and buf must be 4 times, sz must be 4 times */
424         flash_addr = addr;
425         unsigned int max_size = 0;
426         if (sz >= 512) {
427             max_size = INSIDE_FLS_MAX_RD_SIZE;
428         } else {
429             max_size = INSIDE_FLS_PAGE_SIZE;
430         }
431 
432         sz_pagenum = sz / max_size;
433         sz_remain = sz % max_size;
434         for (i = 0; i < sz_pagenum; i++) {
435             __readByCMD(0xEB, flash_addr, (unsigned char *)buf_tmp, max_size);
436             buf_tmp         += max_size;
437             flash_addr    += max_size;
438         }
439 
440         if (sz_remain) {
441             __readByCMD(0xEB, flash_addr, (unsigned char *)buf_tmp, sz_remain);
442         }
443     } else {
444         char *cache = tls_mem_alloc(INSIDE_FLS_PAGE_SIZE);
445         if (cache == NULL) {
446             TLS_DBGPRT_ERR("allocate sector cache memory fail!\n");
447             return TLS_FLS_STATUS_ENOMEM;
448         }
449         flash_addr = addr & ~(INSIDE_FLS_PAGE_SIZE - 1);
450         __readByCMD(0xEB, flash_addr, (unsigned char *)cache, INSIDE_FLS_PAGE_SIZE);
451         if (sz > INSIDE_FLS_PAGE_SIZE - page_offset) {
452             MEMCPY(buf_tmp, cache + page_offset, INSIDE_FLS_PAGE_SIZE - page_offset);
453             buf_tmp += INSIDE_FLS_PAGE_SIZE - page_offset;
454             flash_addr     += INSIDE_FLS_PAGE_SIZE;
455 
456             sz_pagenum = (sz - (INSIDE_FLS_PAGE_SIZE - page_offset)) / INSIDE_FLS_PAGE_SIZE;
457             sz_remain = (sz - (INSIDE_FLS_PAGE_SIZE - page_offset)) % INSIDE_FLS_PAGE_SIZE;
458             for (i = 0; i < sz_pagenum; i++) {
459                 __readByCMD(0xEB, flash_addr, (unsigned char *)cache, INSIDE_FLS_PAGE_SIZE);
460                 MEMCPY(buf_tmp, cache, INSIDE_FLS_PAGE_SIZE);
461                 buf_tmp         += INSIDE_FLS_PAGE_SIZE;
462                 flash_addr     += INSIDE_FLS_PAGE_SIZE;
463             }
464 
465             if (sz_remain) {
466                 __readByCMD(0xEB, flash_addr, (unsigned char *)cache, sz_remain + (4- sz_remain%4));
467                 MEMCPY(buf_tmp, cache, sz_remain);
468             }
469         } else {
470             MEMCPY(buf_tmp, cache + page_offset, sz);
471         }
472         tls_mem_free(cache);
473     }
474 
475     return 0;
476 }
477 
478 /**
479  * @brief           This function is used to unlock flash protect area [0x0~0x2000].
480  *
481  * @param       None
482  *
483  * @return         0-success,non-zero-failure
484  *
485  * @note           None
486  */
tls_flash_unlock(void)487 int tls_flash_unlock(void)
488 {
489     int ret = 0;
490     if (inside_fls == NULL) {
491         return TLS_FLS_STATUS_EPERM;
492     }
493     tls_os_sem_acquire(inside_fls->fls_lock, 0);
494     ret = flashunlock();
495     tls_os_sem_release(inside_fls->fls_lock);
496 
497     return ret;
498 }
499 
500 /**
501  * @brief           This function is used to lock flash protect area [0x0~0x2000].
502  *
503  * @param       None
504  *
505  * @return        0-success,non-zero-failure
506  *
507  * @note           None
508  */
tls_flash_lock(void)509 int tls_flash_lock(void)
510 {
511     int ret = 0;
512     if (inside_fls == NULL) {
513         return TLS_FLS_STATUS_EPERM;
514     }
515     tls_os_sem_acquire(inside_fls->fls_lock, 0);
516     ret = flashlock();
517     tls_os_sem_release(inside_fls->fls_lock);
518 
519     return ret;
520 }
521 
522 /**
523  * @brief           This function is used to semaphore protect.
524  *
525  * @param       None
526  *
527  * @return         None
528  *
529  * @note           None
530  */
tls_fls_sem_lock(void)531 void tls_fls_sem_lock(void)
532 {
533     if (inside_fls == NULL) {
534         return;
535     }
536     tls_os_sem_acquire(inside_fls->fls_lock, 0);
537 }
538 
539 /**
540  * @brief           This function is used to semaphore protect cancel.
541  *
542  * @param       None
543  *
544  * @return         None
545  *
546  * @note           None
547  */
tls_fls_sem_unlock(void)548 void tls_fls_sem_unlock(void)
549 {
550     if (inside_fls == NULL) {
551         return;
552     }
553     tls_os_sem_release(inside_fls->fls_lock);
554 }
555 
556 /**
557  * @brief          This function is used to read the unique id of the internal flash.
558  *
559  * @param[out]    uuid  Specified the address to save the uuid, the length must be greater than or equals to 18 bytes.
560  *
561  * @retval         TLS_FLS_STATUS_OK        if read sucsess
562  * @retval         TLS_FLS_STATUS_EIO        if read fail
563  *
564  * @note           The uuid's length must be greater than or equals to 18 bytes.
565  */
tls_fls_read_unique_id(unsigned char * uuid)566 int tls_fls_read_unique_id(unsigned  char *uuid)
567 {
568     unsigned int value = 0;
569     unsigned int addr_read = 0;
570     int i = 0;
571     int len;
572     unsigned char FLASH_BUF[20];
573     unsigned char *addr = &FLASH_BUF[0];
574     int dumy_bytes = 0;
575     int uni_bytes = 0;
576     unsigned char rid;
577     int word;
578     int byte;
579     if (inside_fls == NULL) {
580         return TLS_FLS_STATUS_EPERM;
581     }
582 
583     tls_os_sem_acquire(inside_fls->fls_lock, 0);
584     memset(uuid, 0xFF, 18);
585     rid = readRID();
586     switch (rid) {
587         case SPIFLASH_MID_GD:
588         case SPIFLASH_MID_PUYA:
589         case SPIFLASH_MID_TSINGTENG:
590             dumy_bytes = 4;
591             uni_bytes = 16;
592             break;
593         case SPIFLASH_MID_WINBOND:
594         case SPIFLASH_MID_FUDANMICRO:
595         case SPIFLASH_MID_BOYA:
596         case SPIFLASH_MID_XMC:
597             dumy_bytes = 4;
598             uni_bytes = 8;
599             break;
600         case SPIFLASH_MID_ESMT:
601         case SPIFLASH_MID_XTX:
602         default:
603             tls_os_sem_release(inside_fls->fls_lock);
604             return -1;
605     }
606     uuid[0] = rid;
607     uuid[1] = (unsigned char)(uni_bytes & 0xFF);
608     len = dumy_bytes + uni_bytes;
609     word = len/4;
610     byte = len%4;
611 
612     value = 0xC04B|((len-1) << 16);
613     M32(HR_FLASH_CMD_ADDR) = value;
614     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
615 
616     addr_read = RSA_BASE_ADDRESS;
617     for (i = 0;i < word; i ++) {
618         M32(addr) = M32(addr_read);
619         addr += 4;
620         addr_read += 4;
621     }
622 
623     if (byte > 0) {
624         M32(addr) = M32(addr_read);
625         addr += 3;                            // point last byte
626         while (byte) {
627             *addr = 0;
628             addr --;
629             byte --;
630         }
631     }
632     addr = &FLASH_BUF[0];
633     memcpy(&uuid[2], addr + dumy_bytes, uni_bytes);
634     tls_os_sem_release(inside_fls->fls_lock);
635 
636     return 0;
637 }
638 
tls_fls_otp_read(u32 addr,u8 * buf,u32 len)639 int tls_fls_otp_read(u32 addr, u8 *buf, u32 len)
640 {
641     int err;
642 
643     int word = len/4;
644     int byte = len%4;
645     unsigned long addr_read = 0xBC00C048;
646     volatile unsigned long value;
647     unsigned long addr_offset = 0;
648     unsigned long sz_need = len;
649 
650     if (inside_fls == NULL) {
651         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
652         return TLS_FLS_STATUS_EPERM;
653     }
654     tls_os_sem_acquire(inside_fls->fls_lock, 0);
655 
656     if (buf) {
657         addr_offset = addr % 16;
658         sz_need = (addr_offset + len + 16) / 16 * 16;
659         addr = addr / 16 * 16;
660     }
661     M32(HR_FLASH_CMD_ADDR) = addr_read|(((sz_need-1)&0x3FF)<<16);
662     M32(HR_FLASH_ADDR) = (addr&0x1FFFFFF);
663     M32(HR_FLASH_CMD_START) = tls_reg_read32(HR_FLASH_CMD_START) | CMD_START_Msk;
664 
665     if (buf) {
666         addr_read = RSA_BASE_ADDRESS + (addr_offset / 4 * 4);
667         int i = (4 - addr_offset % 4) % 4;
668         if (i > len) {
669             byte = len;
670         } else {
671             byte = i;
672         }
673         if (byte) {
674             value = M32(addr_read);
675             memcpy_s(buf, sizeof(buf), ((char *)&value) + 4 - i, byte);
676             addr_read += 4;
677             buf += byte;
678         }
679         word = (len - byte) / 4;
680         for (i = 0;i < word; i ++) {
681             value = M32(addr_read);
682             memcpy_s(buf, sizeof(buf), (char*)&value, 4);
683             buf += 4;
684             addr_read += 4;
685         }
686         byte = (len - byte) % 4;
687         if (byte > 0) {
688             value = M32(addr_read);
689             memcpy_s(buf, sizeof(buf), (char *)&value, byte);
690         }
691     }
692 
693     err = TLS_FLS_STATUS_OK;
694     tls_os_sem_release(inside_fls->fls_lock);
695     return err;
696 }
697 
tls_fls_otp_write(u32 addr,u8 * buf,u32 len)698 int tls_fls_otp_write(u32 addr, u8 *buf, u32 len)
699 {
700     int ret = 0;
701     unsigned int erasecmd = 0x80000844;
702     unsigned int writecmd = 0x80009042;
703     uint32_t eraseAddr = 0;
704     uint16_t eraseSize = 0;
705     uint16_t pageSize = 0;
706     unsigned char flashid = 0;
707     int l = 0;
708     unsigned char *backbuf = NULL;
709     unsigned long size = 0;
710     unsigned long p = 0;
711     unsigned char *q = NULL;
712 
713     if (!buf) {
714         return TLS_FLS_STATUS_EINVAL;
715     }
716     if (inside_fls == NULL) {
717         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
718         return TLS_FLS_STATUS_EPERM;
719     }
720     eraseSize = inside_fls->OTPWRParam.eraseSize;
721     pageSize = inside_fls->OTPWRParam.pageSize;
722     if (eraseSize == 0 || pageSize == 0) {
723         TLS_DBGPRT_ERR("flash type is not supported!\n");
724         return TLS_FLS_STATUS_ENOSUPPORT;
725     }
726     eraseAddr = addr & ~(eraseSize - 1);
727     if (addr < eraseAddr || len > eraseSize - (addr - eraseAddr)) {
728         return TLS_FLS_STATUS_EINVAL;
729     }
730     TLS_DBGPRT_INFO("addr 0x%x, eraseAddr 0x%x, eraseSize 0x%x, pageSize 0x%x\n", addr, eraseAddr, eraseSize, pageSize);
731     backbuf = tls_mem_alloc(eraseSize);
732     if (!backbuf) {
733         ret = TLS_FLS_STATUS_ENOMEM;
734         goto out;
735     }
736     p = eraseAddr;
737     q = backbuf;
738     size = eraseSize;
739     while (size > 0) {
740         l = size > pageSize ? pageSize : size;
741         if (tls_fls_otp_read(p, q, l) != TLS_FLS_STATUS_OK) {
742             ret = TLS_FLS_STATUS_EPERM;
743             goto out;
744         }
745         q += l;
746         p += l;
747         size -= l;
748     }
749     tls_os_sem_acquire(inside_fls->fls_lock, 0);
750     eraseSR(erasecmd, eraseAddr);
751     memcpy_s(backbuf + (addr - eraseAddr), sizeof(backbuf + (addr - eraseAddr)), buf, len);
752     p = eraseAddr;
753     q = backbuf;
754     size = eraseSize;
755     while (size > 0) {
756         l = size > pageSize ? pageSize : size;
757         programSR(writecmd, p, q, l);
758         q += l;
759         p += l;
760         size -= l;
761     }
762     tls_os_sem_release(inside_fls->fls_lock);
763 out:
764     if (backbuf) {
765         tls_mem_free(backbuf);
766     }
767     return ret;
768 }
769 
tls_fls_otp_lock(void)770 int tls_fls_otp_lock(void)
771 {
772     if (inside_fls == NULL) {
773         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
774         return TLS_FLS_STATUS_EPERM;
775     }
776     tls_os_sem_acquire(inside_fls->fls_lock, 0);
777     switch (inside_fls->flashid) {
778         case SPIFLASH_MID_GD:
779         case SPIFLASH_MID_TSINGTENG:
780             writeLbBit_for_1wreg((1<<10));
781             break;
782         case SPIFLASH_MID_FUDANMICRO:
783             writeLbBit_for_2wreg((1<<10));
784             break;
785         case SPIFLASH_MID_BOYA:
786         case SPIFLASH_MID_XMC:
787         case SPIFLASH_MID_WINBOND:
788         case SPIFLASH_MID_PUYA:
789             writeLbBit_for_2wreg((7<<11));
790             break;
791         case SPIFLASH_MID_XTX:
792         case SPIFLASH_MID_ESMT:
793         default:
794             TLS_DBGPRT_ERR("flash is not supported!\n");
795             return TLS_FLS_STATUS_ENOSUPPORT;
796     }
797     tls_os_sem_release(inside_fls->fls_lock);
798     return 0;
799 }
800 
801 /**
802  * @brief          This function is used to read data from the flash.
803  *
804  * @param[in]      addr                 is byte offset addr for read from the flash.
805  * @param[in]      buf                   is user for data buffer of flash read
806  * @param[in]      len                   is byte length for read.
807  *
808  * @retval         TLS_FLS_STATUS_OK        if read sucsess
809  * @retval         TLS_FLS_STATUS_EIO        if read fail
810  *
811  * @note           None
812  */
tls_fls_read(u32 addr,u8 * buf,u32 len)813 int tls_fls_read(u32 addr, u8 *buf, u32 len)
814 {
815     int err;
816 
817     if (inside_fls == NULL) {
818         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
819         return TLS_FLS_STATUS_EPERM;
820     }
821 
822     if (((addr & (INSIDE_FLS_BASE_ADDR - 1)) >=  inside_fls->density) || (len == 0) || (buf == NULL)) {
823         return TLS_FLS_STATUS_EINVAL;
824     }
825 
826     tls_os_sem_acquire(inside_fls->fls_lock, 0);
827 
828     flashRead(addr, buf, len);
829 
830     err = TLS_FLS_STATUS_OK;
831     tls_os_sem_release(inside_fls->fls_lock);
832     return err;
833 }
834 
835 /**
836  * @brief          This function is used to write data to the flash.
837  *
838  * @param[in]      addr     is byte offset addr for write to the flash
839  * @param[in]      buf       is the data buffer want to write to flash
840  * @param[in]      len       is the byte length want to write
841  *
842  * @retval         TLS_FLS_STATUS_OK               if write flash success
843  * @retval         TLS_FLS_STATUS_EPERM        if flash struct point is null
844  * @retval         TLS_FLS_STATUS_ENODRV        if flash driver is not installed
845  * @retval         TLS_FLS_STATUS_EINVAL        if argument is invalid
846  * @retval         TLS_FLS_STATUS_EIO           if io error
847  *
848  * @note           None
849  */
tls_fls_write(u32 addr,u8 * buf,u32 len)850 int tls_fls_write(u32 addr, u8 *buf, u32 len)
851 {
852     u8 *cache;
853     unsigned int secpos;
854     unsigned int secoff;
855     unsigned int secremain;
856     unsigned int i;
857     unsigned int offaddr;
858 
859     if (inside_fls == NULL) {
860         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
861         return TLS_FLS_STATUS_EPERM;
862     }
863 
864     if (((addr & (INSIDE_FLS_BASE_ADDR - 1)) >=  inside_fls->density) || (len == 0) || (buf == NULL)) {
865         return TLS_FLS_STATUS_EINVAL;
866     }
867 
868     tls_os_sem_acquire(inside_fls->fls_lock, 0);
869 
870     cache = tls_mem_alloc(INSIDE_FLS_SECTOR_SIZE);
871     if (cache == NULL) {
872         tls_os_sem_release(inside_fls->fls_lock);
873         TLS_DBGPRT_ERR("allocate sector cache memory fail!\n");
874         return TLS_FLS_STATUS_ENOMEM;
875     }
876 
877     offaddr = addr & (INSIDE_FLS_BASE_ADDR - 1);            // Offset of 0X08000000
878     secpos = offaddr / INSIDE_FLS_SECTOR_SIZE;                // Section addr
879     secoff = (offaddr % INSIDE_FLS_SECTOR_SIZE);            // Offset in section
880     secremain = INSIDE_FLS_SECTOR_SIZE - secoff;    // ����ʣ��ռ��С
881     if (len <= secremain) {
882         secremain = len;                                // Not bigger with remain size in section
883     }
884 
885     flashRead(secpos * INSIDE_FLS_SECTOR_SIZE, cache, INSIDE_FLS_SECTOR_SIZE);
886     while (1) {
887         eraseSector(secpos * INSIDE_FLS_SECTOR_SIZE);
888         for (i = 0; i < secremain; i++) { // ����
889             cache[i + secoff] = buf[i];
890         }
891         for (i = 0; i < (INSIDE_FLS_SECTOR_SIZE / INSIDE_FLS_PAGE_SIZE); i++) {
892             programPage(secpos * INSIDE_FLS_SECTOR_SIZE + i * INSIDE_FLS_PAGE_SIZE, \
893                         INSIDE_FLS_PAGE_SIZE, &cache[i * INSIDE_FLS_PAGE_SIZE]);    // Write
894         }
895         if (len == secremain) {
896             break;              // д�������
897         } else {                   // д��δ����
898             secpos++;           // ������ַ��1
899             secoff = 0;         // ƫ��λ��Ϊ0
900             buf += secremain;   // ָ��ƫ��
901             len -= secremain;
902             if (len > (INSIDE_FLS_SECTOR_SIZE)) {
903                 secremain = INSIDE_FLS_SECTOR_SIZE; // ��һ����������д����
904             } else {
905                 secremain = len;                    // Next section will finish
906                 flashRead(secpos * INSIDE_FLS_SECTOR_SIZE, cache, INSIDE_FLS_SECTOR_SIZE);
907             }
908         }
909     }
910 
911     tls_mem_free(cache);
912     tls_os_sem_release(inside_fls->fls_lock);
913     return TLS_FLS_STATUS_OK;
914 }
915 
916 /**
917  * @brief          This function is used to write data into the flash without erase.
918  *
919  * @param[in]      addr     Specifies the starting address to write to
920  * @param[in]      buf      Pointer to a byte array that is to be written
921  * @param[in]      len      Specifies the length of the data to be written
922  *
923  * @retval         TLS_FLS_STATUS_OK            if write flash success
924  * @retval         TLS_FLS_STATUS_EPERM            if flash struct point is null
925  * @retval         TLS_FLS_STATUS_ENODRV        if flash driver is not installed
926  * @retval         TLS_FLS_STATUS_EINVAL        if argument is invalid
927  *
928  * @note           Erase action should be excuted by API tls_fls_erase in user layer.
929  */
tls_fls_write_without_erase(u32 addr,u8 * buf,u32 len)930 int tls_fls_write_without_erase(u32 addr, u8 *buf, u32 len)
931 {
932     u8 *cache;
933     unsigned int pagepos;
934     unsigned int pageoff;
935     unsigned int pageremain;
936     unsigned int i;
937     unsigned int offaddr;
938 
939     if (inside_fls == NULL) {
940         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
941         return TLS_FLS_STATUS_EPERM;
942     }
943 
944     if (((addr & (INSIDE_FLS_BASE_ADDR - 1)) >=  inside_fls->density) || (len == 0) || (buf == NULL)) {
945         return TLS_FLS_STATUS_EINVAL;
946     }
947 
948     tls_os_sem_acquire(inside_fls->fls_lock, 0);
949 
950     cache = tls_mem_alloc(INSIDE_FLS_PAGE_SIZE);
951     if (cache == NULL) {
952         tls_os_sem_release(inside_fls->fls_lock);
953         TLS_DBGPRT_ERR("allocate page cache memory fail!\n");
954         return TLS_FLS_STATUS_ENOMEM;
955     }
956 
957     offaddr = addr & (INSIDE_FLS_BASE_ADDR - 1);    // Offset of 0X08000000
958     pagepos = offaddr / INSIDE_FLS_PAGE_SIZE;        // Page addr
959     pageoff = (offaddr % INSIDE_FLS_PAGE_SIZE);        // Offset in page
960     pageremain = INSIDE_FLS_PAGE_SIZE - pageoff;    // size remained in one page
961     if (len <= pageremain) {
962         pageremain = len;                            // Not bigger with remain size in one page
963     }
964 
965     flashRead(pagepos * INSIDE_FLS_PAGE_SIZE, cache, INSIDE_FLS_PAGE_SIZE);
966     while (1) {
967         for (i = 0; i < pageremain; i++) {
968             cache[i + pageoff] = buf[i];
969         }
970 
971         programPage(pagepos * INSIDE_FLS_PAGE_SIZE, INSIDE_FLS_PAGE_SIZE, &cache[0]); // Write
972         if (len == pageremain) { // page program over
973             break;
974         } else {
975             pagepos++;           // next page
976             pageoff = 0;         // page offset set to zero
977             buf += pageremain;   // buffer modified
978             len -= pageremain;   // len decrease
979             if (len > (INSIDE_FLS_PAGE_SIZE)) {
980                 pageremain = INSIDE_FLS_PAGE_SIZE; // size next to write
981             } else {
982                 pageremain = len;                    // last data to write
983                 flashRead(pagepos * INSIDE_FLS_PAGE_SIZE, cache, INSIDE_FLS_PAGE_SIZE);
984             }
985         }
986     }
987 
988     tls_mem_free(cache);
989     tls_os_sem_release(inside_fls->fls_lock);
990     return TLS_FLS_STATUS_OK;
991 }
992 
993 /**
994  * @brief              This function is used to erase the appoint sector
995  *
996  * @param[in]          sector     sector num of the flash, 4K byte a sector
997  *
998  * @retval             TLS_FLS_STATUS_OK            if read sucsess
999  * @retval             other                        if read fail
1000  *
1001  * @note               None
1002  */
tls_fls_erase(u32 sector)1003 int tls_fls_erase(u32 sector)
1004 {
1005     u32 addr;
1006     if (inside_fls == NULL) {
1007         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1008         return TLS_FLS_STATUS_EPERM;
1009     }
1010 
1011     if (sector >= (inside_fls->density / INSIDE_FLS_SECTOR_SIZE + INSIDE_FLS_BASE_ADDR / INSIDE_FLS_SECTOR_SIZE)) {
1012         TLS_DBGPRT_ERR("the sector to be erase overflow!\n");
1013         return TLS_FLS_STATUS_EINVAL;
1014     }
1015 
1016     tls_os_sem_acquire(inside_fls->fls_lock, 0);
1017 
1018     addr = sector * INSIDE_FLS_SECTOR_SIZE;
1019 
1020     eraseSector(addr);
1021 
1022     tls_os_sem_release(inside_fls->fls_lock);
1023 
1024     return TLS_FLS_STATUS_OK;
1025 }
1026 
1027 static u8 *gsflscache = NULL;
1028 static u32 gsSector = 0;
1029 
1030 /**
1031  * @brief              This function is used to flush the appoint sector
1032  *
1033  * @param          None
1034  *
1035  * @return             None
1036  *
1037  * @note               None
1038  */
tls_fls_flush_sector(void)1039 static void tls_fls_flush_sector(void)
1040 {
1041     u32 addr;
1042     if (gsSector < (inside_fls->density / INSIDE_FLS_SECTOR_SIZE + INSIDE_FLS_BASE_ADDR / INSIDE_FLS_SECTOR_SIZE)) {
1043         addr = gsSector * INSIDE_FLS_SECTOR_SIZE;
1044 
1045         eraseSector(addr);
1046         for (int i = 0; i < INSIDE_FLS_SECTOR_SIZE / INSIDE_FLS_PAGE_SIZE; i++) {
1047             programPage(gsSector * INSIDE_FLS_SECTOR_SIZE +
1048                         i * INSIDE_FLS_PAGE_SIZE, INSIDE_FLS_PAGE_SIZE,
1049                         &gsflscache[i * INSIDE_FLS_PAGE_SIZE]);
1050         }
1051     }
1052 }
1053 
1054 /**
1055  * @brief              This function is used to fast write flash initialize
1056  *
1057  * @param          None
1058  *
1059  * @retval             TLS_FLS_STATUS_OK            sucsess
1060  * @retval             other                        fail
1061  *
1062  * @note               None
1063  */
tls_fls_fast_write_init(void)1064 int tls_fls_fast_write_init(void)
1065 {
1066     if (inside_fls == NULL) {
1067         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1068         return TLS_FLS_STATUS_EPERM;
1069     }
1070     if (gsflscache != NULL) {
1071         TLS_DBGPRT_ERR("tls_fls_fast_write_init installed!\n");
1072         return -1;
1073     }
1074     gsflscache = tls_mem_alloc(INSIDE_FLS_SECTOR_SIZE);
1075     if (gsflscache == NULL) {
1076         TLS_DBGPRT_ERR("tls_fls_fast_write_init malloc err!\n");
1077         return -1;
1078     }
1079     return TLS_FLS_STATUS_OK;
1080 }
1081 
1082 /**
1083  * @brief              This function is used to destroy fast write flash
1084  *
1085  * @param          None
1086  *
1087  * @return             None
1088  *
1089  * @note               None
1090  */
tls_fls_fast_write_destroy(void)1091 void tls_fls_fast_write_destroy(void)
1092 {
1093     if (gsflscache != NULL) {
1094         if (inside_fls == NULL) {
1095             TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1096             return;
1097         } else {
1098             tls_os_sem_acquire(inside_fls->fls_lock, 0);
1099             tls_fls_flush_sector();
1100             tls_os_sem_release(inside_fls->fls_lock);
1101         }
1102 
1103         tls_mem_free(gsflscache);
1104         gsflscache = NULL;
1105     }
1106 }
1107 
1108 /**
1109  * @brief              This function is used to fast write data to the flash.
1110  *
1111  * @param[in]          addr         is byte offset addr for write to the flash
1112  * @param[in]          buf           is the data buffer want to write to flash
1113  * @param[in]          length      is the byte length want to write
1114  *
1115  * @retval             TLS_FLS_STATUS_OK    success
1116  * @retval            other                fail
1117  *
1118  * @note               None
1119  */
tls_fls_fast_write(u32 addr,u8 * buf,u32 length)1120 int tls_fls_fast_write(u32 addr, u8 *buf, u32 length)
1121 {
1122     u32 sector, offset, maxlen, len;
1123 
1124     if (inside_fls == NULL) {
1125         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1126         return TLS_FLS_STATUS_EPERM;
1127     }
1128     if (((addr & (INSIDE_FLS_BASE_ADDR - 1)) >=  inside_fls->density) || (length == 0) || (buf == NULL)) {
1129         return TLS_FLS_STATUS_EINVAL;
1130     }
1131     tls_os_sem_acquire(inside_fls->fls_lock, 0);
1132 
1133     sector = addr / INSIDE_FLS_SECTOR_SIZE;
1134     offset = addr % INSIDE_FLS_SECTOR_SIZE;
1135     maxlen = INSIDE_FLS_SECTOR_SIZE;
1136 
1137     if ((sector != gsSector) && (gsSector != 0)) {
1138         tls_fls_flush_sector();
1139     }
1140     gsSector = sector;
1141     if (offset > 0) {
1142         maxlen -= offset;
1143     }
1144     while (length > 0) {
1145         len = (length > maxlen) ? maxlen : length;
1146         MEMCPY(gsflscache + offset, buf, len);
1147         if (offset + len >= INSIDE_FLS_SECTOR_SIZE) {
1148             tls_fls_flush_sector();
1149             gsSector++;
1150         }
1151         offset = 0;
1152         maxlen = INSIDE_FLS_SECTOR_SIZE;
1153         buf += len;
1154         length -= len;
1155     }
1156 
1157     tls_os_sem_release(inside_fls->fls_lock);
1158 
1159     return TLS_FLS_STATUS_OK;
1160 }
1161 
1162 /**
1163  * @brief              This function is used to erase flash all chip
1164  *
1165  * @param          None
1166  *
1167  * @retval             TLS_FLS_STATUS_OK            sucsess
1168  * @retval             other                        fail
1169  *
1170  * @note               None
1171  */
tls_fls_chip_erase(void)1172 int tls_fls_chip_erase(void)
1173 {
1174     int i, j;
1175     u8 *cache;
1176 
1177     if (inside_fls == NULL) {
1178         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1179         return TLS_FLS_STATUS_EPERM;
1180     }
1181 
1182     tls_os_sem_acquire(inside_fls->fls_lock, 0);
1183 
1184     cache = tls_mem_alloc(INSIDE_FLS_SECTOR_SIZE);
1185     if (cache == NULL) {
1186         tls_os_sem_release(inside_fls->fls_lock);
1187         TLS_DBGPRT_ERR("allocate sector cache memory fail!\n");
1188         return TLS_FLS_STATUS_ENOMEM;
1189     }
1190 
1191     for (i = 0; i < (inside_fls->density - (INSIDE_FLS_SECBOOT_ADDR & 0xFFFFF)) / INSIDE_FLS_SECTOR_SIZE; i ++) {
1192         flashRead(INSIDE_FLS_SECBOOT_ADDR + i * INSIDE_FLS_SECTOR_SIZE, cache, INSIDE_FLS_SECTOR_SIZE);
1193         for (j = 0; j < INSIDE_FLS_SECTOR_SIZE; j++) {
1194             if (cache[j] != 0xFF) {
1195                 eraseSector(INSIDE_FLS_SECBOOT_ADDR + i * INSIDE_FLS_SECTOR_SIZE);
1196                 break;
1197             }
1198         }
1199     }
1200 
1201     tls_mem_free(cache);
1202 
1203     tls_os_sem_release(inside_fls->fls_lock);
1204 
1205     return TLS_FLS_STATUS_OK;
1206 }
1207 
1208 /**
1209  * @brief              This function is used to get flash param
1210  *
1211  * @param[in]          type        the type of the param need to get
1212  * @param[out]         param    point to addr of out param
1213  *
1214  * @retval             TLS_FLS_STATUS_OK            sucsess
1215  * @retval             other                        fail
1216  *
1217  * @note               None
1218  */
tls_fls_get_param(u8 type,void * param)1219 int tls_fls_get_param(u8 type, void *param)
1220 {
1221     int err;
1222 
1223     if (inside_fls == NULL) {
1224         TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1225         return TLS_FLS_STATUS_EPERM;
1226     }
1227 
1228     if (param == NULL) {
1229         return TLS_FLS_STATUS_EINVAL;
1230     }
1231     tls_os_sem_acquire(inside_fls->fls_lock, 0);
1232     err = TLS_FLS_STATUS_OK;
1233     switch (type) {
1234         case TLS_FLS_PARAM_TYPE_ID:
1235             *((u32 *) param) = 0x2013;
1236             break;
1237 
1238         case TLS_FLS_PARAM_TYPE_SIZE:
1239             *((u32 *) param) = inside_fls->density;
1240             break;
1241 
1242         case TLS_FLS_PARAM_TYPE_PAGE_SIZE:
1243             *((u32 *) param) = INSIDE_FLS_PAGE_SIZE;
1244             break;
1245 
1246         case TLS_FLS_PARAM_TYPE_PROG_SIZE:
1247             *((u32 *) param) = INSIDE_FLS_PAGE_SIZE;
1248             break;
1249 
1250         case TLS_FLS_PARAM_TYPE_SECTOR_SIZE:
1251             *((u32 *) param) = INSIDE_FLS_SECTOR_SIZE;
1252             break;
1253 
1254         default:
1255             TLS_DBGPRT_WARNING("invalid parameter ID!\n");
1256             err = TLS_FLS_STATUS_EINVAL;
1257             break;
1258     }
1259     tls_os_sem_release(inside_fls->fls_lock);
1260     return err;
1261 }
1262 
1263 /**
1264  * @brief              This function is used to initialize the flash module
1265  *
1266  * @param          None
1267  *
1268  * @retval             TLS_FLS_STATUS_OK            sucsess
1269  * @retval             other                        fail
1270  *
1271  * @note               None
1272  */
tls_fls_init(void)1273 int tls_fls_init(void)
1274 {
1275     struct tls_inside_fls *fls;
1276     int err;
1277 
1278     if (inside_fls != NULL) {
1279         TLS_DBGPRT_ERR("flash driver module has been installed!\n");
1280         return TLS_FLS_STATUS_EBUSY;
1281     }
1282 
1283     fls = (struct tls_inside_fls *) tls_mem_alloc(sizeof(struct tls_inside_fls));
1284     if (fls == NULL) {
1285         TLS_DBGPRT_ERR("allocate @inside_fls fail!\n");
1286         return TLS_FLS_STATUS_ENOMEM;
1287     }
1288 
1289     memset_s(fls, sizeof(fls), 0, sizeof(*fls));
1290     err = tls_os_sem_create(&fls->fls_lock, 1);
1291     if (err != TLS_OS_SUCCESS) {
1292         tls_mem_free(fls);
1293         TLS_DBGPRT_ERR("create semaphore @fls_lock fail!\n");
1294         return TLS_FLS_STATUS_ENOMEM;
1295     }
1296     fls->flashid = readRID();
1297     fls->density = getFlashDensity();
1298     fls->OTPWRParam.pageSize = 256;
1299     switch (fls->flashid) {
1300         case SPIFLASH_MID_GD:
1301             fls->OTPWRParam.eraseSize = 1024;
1302             break;
1303         case SPIFLASH_MID_FUDANMICRO:
1304             fls->OTPWRParam.eraseSize = 1024;
1305             if (fls->density <= (1 << 20))  { // 8Mbit
1306                 fls->OTPWRParam.eraseSize = 256;
1307             }
1308             break;
1309         case SPIFLASH_MID_TSINGTENG:
1310         case SPIFLASH_MID_BOYA:
1311         case SPIFLASH_MID_XMC:
1312         case SPIFLASH_MID_WINBOND:
1313             fls->OTPWRParam.eraseSize = 256;
1314             break;
1315         case SPIFLASH_MID_PUYA:
1316             fls->OTPWRParam.eraseSize = 512;
1317             break;
1318         case SPIFLASH_MID_XTX:
1319         case SPIFLASH_MID_ESMT:
1320             fls->OTPWRParam.eraseSize = 0; // not support
1321             break;
1322         default:
1323             tls_mem_free(fls);
1324             TLS_DBGPRT_ERR("flash is not supported!\n");
1325             return TLS_FLS_STATUS_ENOSUPPORT;
1326     }
1327 
1328     inside_fls = fls;
1329 
1330     return TLS_FLS_STATUS_OK;
1331 }
1332 
tls_fls_exit(void)1333 int tls_fls_exit(void)
1334 {
1335     TLS_DBGPRT_FLASH_INFO("Not support flash driver module uninstalled!\n");
1336     return TLS_FLS_STATUS_EPERM;
1337 }
1338 
1339 /**
1340  * @brief              This function is used to initialize system parameter postion by flash density
1341  *
1342  * @param          None
1343  *
1344  * @retval             None
1345  *
1346  * @note               must be called before function tls_param_init
1347  */
tls_fls_sys_param_postion_init(void)1348 void tls_fls_sys_param_postion_init(void)
1349 {
1350     unsigned int density = 0;
1351     int err;
1352     err = tls_fls_get_param(TLS_FLS_PARAM_TYPE_SIZE, (void *)&density);
1353     if (TLS_FLS_STATUS_OK == err) {
1354         TLS_FLASH_END_ADDR            = (FLASH_BASE_ADDR|density) - 1;
1355         TLS_FLASH_OTA_FLAG_ADDR       = (FLASH_BASE_ADDR|density) - 0x1000;
1356         TLS_FLASH_PARAM_RESTORE_ADDR  =    (FLASH_BASE_ADDR|density) - 0x2000;
1357         TLS_FLASH_PARAM2_ADDR           =    (FLASH_BASE_ADDR|density) - 0x3000;
1358         TLS_FLASH_PARAM1_ADDR           =    (FLASH_BASE_ADDR|density) - 0x4000;
1359         TLS_FLASH_PARAM_DEFAULT          =    (FLASH_BASE_ADDR|density) - 0x5000;
1360     } else {
1361         TLS_DBGPRT_ERR("system parameter postion use default!\n");
1362     }
1363 }