• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 #include "flash.h"
19 #include "core.h"
20 #include "ext_driver/ext_misc.h"
21 #include "mspi.h"
22 #include "plic.h"
23 #include "stimer.h"
24 #include "sys.h"
25 #include "timer.h"
26 #include "watchdog.h"
27 
28 #include "los_timer.h"
29 #include "los_task.h"
30 
31 #define RAMCODE_OPTIMIZE_UNUSED_FLASH_API_NOT_IMPLEMENT 1
32 
33 _attribute_data_retention_sec_ volatile unsigned char flash_cnt = 1;
34 
35 static preempt_config_t s_flash_preempt_config = {
36     .preempt_en = 0,
37     .threshold = 1,
38 };
39 
40 /**
41  * @brief 		This function serves to set priority threshold.
42  *              when the interrupt priority > Threshold flash process will disturb by interrupt.
43  * @param[in]   preempt_en	- 1 can disturb by interrupt, 0 can disturb by interrupt.
44  * @param[in]	threshold	- priority Threshold.
45  * @return    	none.
46  */
flash_plic_preempt_config(unsigned char preempt_en,unsigned char threshold)47 void flash_plic_preempt_config(unsigned char preempt_en, unsigned char threshold)
48 {
49     s_flash_preempt_config.preempt_en = preempt_en;
50     s_flash_preempt_config.threshold = threshold;
51 }
52 
53 /**
54  * @brief		This function to determine whether the flash is busy..
55  * @return		1:Indicates that the flash is busy. 0:Indicates that the flash is free
56  */
flash_is_busy(void)57 static inline int flash_is_busy(void)
58 {
59     return mspi_read() & 0x01;  //  the busy bit, pls check flash spec
60 }
61 
62 /**
63  * @brief		This function serves to set flash write command.
64  *              This function interface is only used internally by flash,
65  * 				and is currently included in the H file for compatibility with other SDKs. When using this interface,
66  * 				please ensure that you understand the precautions of flash before using it.
67  * @param[in]	cmd	- set command.
68  * @return		none.
69  */
flash_send_cmd(unsigned char cmd)70 _attribute_ram_code_sec_noinline_ void flash_send_cmd(unsigned char cmd)
71 {
72     mspi_high();
73     CLOCK_DLY_10_CYC;
74     mspi_low();
75     mspi_write(cmd);
76     mspi_wait();
77 }
78 
79 /**
80  * @brief		This function serves to send flash address.
81  * @param[in]	addr	- the flash address.
82  * @return		none.
83  */
flash_send_addr(unsigned int addr)84 _attribute_ram_code_sec_noinline_ static void flash_send_addr(unsigned int addr)
85 {
86     mspi_write((unsigned char)(addr >> 16));
87     mspi_wait();
88     mspi_write((unsigned char)(addr >> 8));
89     mspi_wait();
90     mspi_write((unsigned char)(addr));
91     mspi_wait();
92 }
93 
94 /**
95  * @brief     This function serves to wait flash done.(make this a asynchorous version).
96  * @return    none.
97  */
flash_wait_done(void)98 _attribute_ram_code_sec_noinline_ static void flash_wait_done(void)
99 {
100     flash_send_cmd(FLASH_READ_STATUS_CMD);
101 
102     int i;
103     for (i = 0; i < 10000000; ++i) {
104         if (!flash_is_busy()) {
105             flash_cnt++;
106             break;
107         }
108     }
109     mspi_high();
110 }
111 
112 /**
113  * @brief 		This function serves to erase a sector.
114  * @param[in]   addr	- the start address of the sector needs to erase.
115  * @return 		none.
116  */
flash_erase_sector_ram(unsigned long addr)117 _attribute_ram_code_sec_noinline_ void flash_erase_sector_ram(unsigned long addr)
118 {
119     LOS_SysTickTimerGet()->lock();
120     LOS_TaskLock();
121 #if SUPPORT_PFT_ARCH
122     unsigned int r = core_interrupt_disable();
123     reg_irq_threshold = 1;
124     core_restore_interrupt(r);
125 #else
126     unsigned int r = core_interrupt_disable();
127 #endif
128     mspi_stop_xip();
129     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
130     flash_send_cmd(FLASH_SECT_ERASE_CMD);
131     flash_send_addr(addr);
132     mspi_high();
133     flash_wait_done();
134     CLOCK_DLY_5_CYC;
135 #if SUPPORT_PFT_ARCH
136     r = core_interrupt_disable();
137     reg_irq_threshold = 0;
138     core_restore_interrupt(r);
139 #else
140     core_restore_interrupt(r);
141 #endif
142     LOS_SysTickTimerGet()->unlock();
143     LOS_TaskUnlock();
144 }
flash_erase_sector(unsigned long addr)145 _attribute_text_sec_ void flash_erase_sector(unsigned long addr)
146 {
147     wd_clear();                     // clear watch dog (ble team add code)
148     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
149     flash_erase_sector_ram(addr);
150     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
151 }
152 
153 /**
154  * @brief 		This function writes the buffer's content to a page.
155  * @param[in]   addr	- the start address of the page.
156  * @param[in]   len		- the length(in byte) of content needs to write into the page.
157  * @param[in]   buf		- the start address of the content needs to write into.
158  * @return 		none.
159  */
flash_write_page_ram(unsigned long addr,unsigned long len,unsigned char * buf)160 _attribute_ram_code_sec_noinline_ void flash_write_page_ram(unsigned long addr, unsigned long len, unsigned char *buf)
161 {
162     LOS_SysTickTimerGet()->lock();
163     LOS_TaskLock();
164 #if SUPPORT_PFT_ARCH
165     unsigned int r = core_interrupt_disable();
166     reg_irq_threshold = 1;
167     core_restore_interrupt(r);
168 #else
169     unsigned int r = core_interrupt_disable();  // ???irq_disable();
170 #endif
171     mspi_stop_xip();
172     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
173     flash_send_cmd(FLASH_WRITE_CMD);
174     flash_send_addr(addr);
175 
176     unsigned int i;
177     for (i = 0; i < len; ++i) {
178         mspi_write(buf[i]); /* write data */
179         mspi_wait();
180     }
181     mspi_high();
182     flash_wait_done();
183     CLOCK_DLY_5_CYC;
184 
185 #if SUPPORT_PFT_ARCH
186     r = core_interrupt_disable();
187     reg_irq_threshold = 0;
188     core_restore_interrupt(r);
189 #else
190     core_restore_interrupt(r);                  // ???irq_restore(r);
191 #endif
192     LOS_SysTickTimerGet()->unlock();
193     LOS_TaskUnlock();
194 }
flash_write_page(unsigned long addr,unsigned long len,unsigned char * buf)195 _attribute_text_sec_ void flash_write_page(unsigned long addr, unsigned long len, unsigned char *buf)
196 {
197     unsigned int ns = PAGE_SIZE - (addr & 0xff);
198     int nw = 0;
199 
200     do {
201         nw = len > ns ? ns : len;
202         __asm__("csrci 	mmisc_ctl,8");  // disable BTB
203         flash_write_page_ram(addr, nw, buf);
204         __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
205         ns = PAGE_SIZE;
206         addr += nw;
207         buf += nw;
208         len -= nw;
209     } while (len > 0);
210 }
211 
212 /**
213  * @brief 		This function reads the content from a page to the buf.
214  * @param[in]   addr	- the start address of the page.
215  * @param[in]   len		- the length(in byte) of content needs to read out from the page.
216  * @param[out]  buf		- the start address of the buffer.
217  * @return 		none.
218  */
flash_read_page_ram(unsigned long addr,unsigned long len,unsigned char * buf)219 _attribute_ram_code_sec_noinline_ void flash_read_page_ram(unsigned long addr, unsigned long len, unsigned char *buf)
220 {
221     LOS_SysTickTimerGet()->lock();
222     LOS_TaskLock();
223 #if SUPPORT_PFT_ARCH
224     unsigned int r = core_interrupt_disable();
225     reg_irq_threshold = 1;
226     core_restore_interrupt(r);
227 #else
228     unsigned int r = core_interrupt_disable();  // ???irq_disable();
229 #endif
230     mspi_stop_xip();
231     flash_send_cmd(FLASH_READ_CMD);
232     flash_send_addr(addr);
233 
234     mspi_write(0x00); /* dummy,  to issue clock */
235     mspi_wait();
236     mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */
237     mspi_wait();
238     /* get data */
239     for (unsigned int i = 0; i < len; ++i) {
240         *buf++ = mspi_get();
241         mspi_wait();
242     }
243     mspi_fm_rd_dis(); /* off read auto mode */
244     mspi_high();
245     CLOCK_DLY_5_CYC;
246 #if SUPPORT_PFT_ARCH
247     r = core_interrupt_disable();
248     reg_irq_threshold = 0;
249     core_restore_interrupt(r);
250 #else
251     core_restore_interrupt(r);                  // ???irq_restore(r);
252 #endif
253     LOS_SysTickTimerGet()->unlock();
254     LOS_TaskUnlock();
255 }
flash_read_page(unsigned long addr,unsigned long len,unsigned char * buf)256 _attribute_text_sec_ void flash_read_page(unsigned long addr, unsigned long len, unsigned char *buf)
257 {
258     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
259     flash_read_page_ram(addr, len, buf);
260     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
261 }
262 
263 /**
264  * @brief     	This function serves to erase a chip.
265  * @return    	none.
266  */
flash_erase_chip_ram(void)267 _attribute_ram_code_sec_noinline_ void flash_erase_chip_ram(void)
268 {
269 #if SUPPORT_PFT_ARCH
270     unsigned int r = core_interrupt_disable();
271     reg_irq_threshold = 1;
272     core_restore_interrupt(r);
273 #else
274     unsigned int r = core_interrupt_disable();
275 #endif
276     mspi_stop_xip();
277     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
278     flash_send_cmd(FLASH_CHIP_ERASE_CMD);
279     mspi_high();
280     flash_wait_done();
281     CLOCK_DLY_5_CYC;
282 #if SUPPORT_PFT_ARCH
283     r = core_interrupt_disable();
284     reg_irq_threshold = 0;
285     core_restore_interrupt(r);
286 #else
287     core_restore_interrupt(r);
288 #endif
289 }
flash_erase_chip(void)290 _attribute_text_sec_ void flash_erase_chip(void)
291 {
292     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
293     flash_erase_chip_ram();
294     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
295 }
296 
297 #if (!RAMCODE_OPTIMIZE_UNUSED_FLASH_API_NOT_IMPLEMENT)
298 /**
299  * @brief     	This function serves to erase a page(256 bytes).
300  * @param[in] 	addr	- the start address of the page needs to erase.
301  * @return    	none.
302  */
flash_erase_page_ram(unsigned int addr)303 _attribute_ram_code_sec_noinline_ void flash_erase_page_ram(unsigned int addr)
304 {
305 #if SUPPORT_PFT_ARCH
306     unsigned int r = core_interrupt_disable();
307     reg_irq_threshold = 1;
308     core_restore_interrupt(r);
309 #else
310     unsigned int r = core_interrupt_disable();
311 #endif
312 
313     mspi_stop_xip();
314     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
315     flash_send_cmd(FLASH_PAGE_ERASE_CMD);
316     flash_send_addr(addr);
317     mspi_high();
318     flash_wait_done();
319     CLOCK_DLY_5_CYC;
320 #if SUPPORT_PFT_ARCH
321     r = core_interrupt_disable();
322     reg_irq_threshold = 0;
323     core_restore_interrupt(r);
324 #else
325     core_restore_interrupt(r);  // ???irq_restore(r);
326 #endif
327 }
flash_erase_page(unsigned int addr)328 _attribute_text_sec_ void flash_erase_page(unsigned int addr)
329 {
330     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
331     flash_erase_page_ram(addr);
332     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
333 }
334 
335 /**
336  * @brief 		This function serves to erase a block(32k).
337  * @param[in]   addr	- the start address of the block needs to erase.
338  * @return 		none.
339  */
flash_erase_32kblock_ram(unsigned int addr)340 _attribute_ram_code_sec_noinline_ void flash_erase_32kblock_ram(unsigned int addr)
341 {
342 #if SUPPORT_PFT_ARCH
343     unsigned int r = core_interrupt_disable();
344     reg_irq_threshold = 1;
345     core_restore_interrupt(r);
346 #else
347     unsigned int r = core_interrupt_disable();
348 #endif
349 
350     mspi_stop_xip();
351     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
352     flash_send_cmd(FLASH_32KBLK_ERASE_CMD);
353     flash_send_addr(addr);
354     mspi_high();
355     flash_wait_done();
356     CLOCK_DLY_5_CYC;
357 #if SUPPORT_PFT_ARCH
358     r = core_interrupt_disable();
359     reg_irq_threshold = 0;
360     core_restore_interrupt(r);
361 #else
362     core_restore_interrupt(r);  // ???irq_restore(r);
363 #endif
364 }
flash_erase_32kblock(unsigned int addr)365 _attribute_text_sec_ void flash_erase_32kblock(unsigned int addr)
366 {
367     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
368     flash_erase_32kblock_ram(addr);
369     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
370 }
371 
372 /**
373  * @brief 		This function serves to erase a block(64k).
374  * @param[in]   addr	- the start address of the block needs to erase.
375  * @return 		none.
376  */
flash_erase_64kblock_ram(unsigned int addr)377 _attribute_ram_code_sec_noinline_ void flash_erase_64kblock_ram(unsigned int addr)
378 {
379 #if SUPPORT_PFT_ARCH
380     unsigned int r = core_interrupt_disable();
381     reg_irq_threshold = 1;
382     core_restore_interrupt(r);
383 #else
384     unsigned int r = core_interrupt_disable();
385 #endif
386 
387     mspi_stop_xip();
388     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
389     flash_send_cmd(FLASH_64KBLK_ERASE_CMD);
390     flash_send_addr(addr);
391     mspi_high();
392     flash_wait_done();
393     CLOCK_DLY_5_CYC;
394 #if SUPPORT_PFT_ARCH
395     r = core_interrupt_disable();
396     reg_irq_threshold = 0;
397     core_restore_interrupt(r);
398 #else
399     core_restore_interrupt(r);  // ???irq_restore(r);
400 #endif
401 }
flash_erase_64kblock(unsigned int addr)402 _attribute_text_sec_ void flash_erase_64kblock(unsigned int addr)
403 {
404     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
405     flash_erase_64kblock_ram(addr);
406     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
407 }
408 
409 /**
410  * @brief 		This function write the status of flash.
411  * @param[in]  	data	- the value of status.
412  * @return 		none.
413  */
flash_write_status_ram(unsigned short data)414 _attribute_ram_code_sec_noinline_ void flash_write_status_ram(unsigned short data)
415 {
416 #if SUPPORT_PFT_ARCH
417     unsigned int r = core_interrupt_disable();
418     reg_irq_threshold = 1;
419     core_restore_interrupt(r);
420 #else
421     unsigned int r = core_interrupt_disable();
422 #endif
423     mspi_stop_xip();
424     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
425     flash_send_cmd(FLASH_WRITE_STATUS_CMD);
426     mspi_write((unsigned char)data);
427     mspi_wait();
428     mspi_write((unsigned char)(data >> 8));
429     mspi_wait();
430     mspi_high();
431     flash_wait_done();
432     mspi_high();
433     CLOCK_DLY_5_CYC;
434 #if SUPPORT_PFT_ARCH
435     r = core_interrupt_disable();
436     reg_irq_threshold = 0;
437     core_restore_interrupt(r);
438 #else
439     core_restore_interrupt(r);  // ???irq_restore(r);
440 #endif
441 }
flash_write_status(unsigned short data)442 _attribute_text_sec_ void flash_write_status(unsigned short data)
443 {
444     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
445     flash_write_status_ram(data);
446     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
447 }
448 
449 /**
450  * @brief 		This function reads the status of flash.
451  * @return 		the value of status.
452  */
flash_read_status_ram(void)453 _attribute_ram_code_sec_noinline_ unsigned short flash_read_status_ram(void)
454 {
455     unsigned short status = 0;
456 #if SUPPORT_PFT_ARCH
457     unsigned int r = core_interrupt_disable();
458     reg_irq_threshold = 1;
459     core_restore_interrupt(r);
460 #else
461     unsigned int r = core_interrupt_disable();
462 #endif
463 
464     mspi_stop_xip();
465     flash_send_cmd(FLASH_READ_STATUS_1_CMD); /* get high 8 bit status */
466     status = (mspi_read() << 8);
467     mspi_high();
468     flash_send_cmd(FLASH_READ_STATUS_CMD); /* get low 8 bit status */
469     status |= mspi_read();
470     mspi_high();
471     CLOCK_DLY_5_CYC;
472 
473 #if SUPPORT_PFT_ARCH
474     r = core_interrupt_disable();
475     reg_irq_threshold = 0;
476     core_restore_interrupt(r);
477 #else
478     core_restore_interrupt(r);  // ???irq_restore(r);
479 #endif
480     return status;
481 }
flash_read_status(void)482 _attribute_text_sec_ unsigned short flash_read_status(void)
483 {
484     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
485     unsigned short status = flash_read_status_ram();
486     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
487     return status;
488 }
489 
490 /**
491  * @brief		Deep Power Down mode to put the device in the lowest consumption mode
492  * 				it can be used as an extra software protection mechanism,while the device
493  * 				is not in active use,since in the mode,  all write,Program and Erase commands
494  * 				are ignored,except the Release from Deep Power-Down and Read Device ID(RDI)
495  * 				command.This release the device from this mode
496  * @return 		none.
497  */
flash_deep_powerdown_ram(void)498 _attribute_ram_code_sec_noinline_ void flash_deep_powerdown_ram(void)
499 {
500 #if SUPPORT_PFT_ARCH
501     unsigned int r = core_interrupt_disable();
502     reg_irq_threshold = 1;
503     core_restore_interrupt(r);
504 #else
505     unsigned int r = core_interrupt_disable();
506 #endif
507 
508     mspi_stop_xip();
509     flash_send_cmd(FLASH_POWER_DOWN);
510     mspi_high();
511     delay_us(1);
512     CLOCK_DLY_5_CYC;
513 
514 #if SUPPORT_PFT_ARCH
515     r = core_interrupt_disable();
516     reg_irq_threshold = 0;
517     core_restore_interrupt(r);
518 #else
519     core_restore_interrupt(r);  // ???irq_restore(r);
520 #endif
521 }
flash_deep_powerdown(void)522 _attribute_text_sec_ void flash_deep_powerdown(void)
523 {
524     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
525     flash_deep_powerdown_ram();
526     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
527 }
528 
529 /**
530  * @brief		The Release from Power-Down or High Performance Mode/Device ID command is a
531  * 				Multi-purpose command.it can be used to release the device from the power-Down
532  * 				State or High Performance Mode or obtain the devices electronic identification
533  * 				(ID)number.Release from Power-Down will take the time duration of tRES1 before
534  * 				the device will resume normal operation and other command are accepted.The CS#
535  * 				pin must remain high during the tRES1(8us) time duration.
536  * @return      none.
537  */
flash_release_deep_powerdown_ram(void)538 _attribute_ram_code_sec_noinline_ void flash_release_deep_powerdown_ram(void)
539 {
540 #if SUPPORT_PFT_ARCH
541     unsigned int r = core_interrupt_disable();
542     reg_irq_threshold = 1;
543     core_restore_interrupt(r);
544 #else
545     unsigned int r = core_interrupt_disable();
546 #endif
547 
548     mspi_stop_xip();
549     flash_send_cmd(FLASH_POWER_DOWN_RELEASE);
550     mspi_high();
551     flash_wait_done();
552     mspi_high();
553     CLOCK_DLY_5_CYC;
554 
555 #if SUPPORT_PFT_ARCH
556     r = core_interrupt_disable();
557     reg_irq_threshold = 0;
558     core_restore_interrupt(r);
559 #else
560     core_restore_interrupt(r);  // ???irq_restore(r);
561 #endif
562 }
flash_release_deep_powerdown(void)563 _attribute_text_sec_ void flash_release_deep_powerdown(void)
564 {
565     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
566     flash_release_deep_powerdown_ram();
567     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
568 }
569 
570 #endif
571 
572 /**
573  * @brief	  	This function serves to read MID of flash(MAC id). Before reading UID of flash,
574  * 				you must read MID of flash. and then you can look up the related table to select
575  * 				the idcmd and read UID of flash
576  * @param[in] 	buf		- store MID of flash
577  * @return    	none.
578  */
flash_read_mid_ram(unsigned char * buf)579 _attribute_ram_code_sec_noinline_ void flash_read_mid_ram(unsigned char *buf)
580 {
581     unsigned char j = 0;
582 #if SUPPORT_PFT_ARCH
583     unsigned int r = core_interrupt_disable();
584     reg_irq_threshold = 1;
585     core_restore_interrupt(r);
586 #else
587     unsigned int r = core_interrupt_disable();
588 #endif
589 
590     mspi_stop_xip();
591     flash_send_cmd(FLASH_GET_JEDEC_ID);
592     mspi_write(0x00); /* dummy,  to issue clock */
593     mspi_wait();
594     mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */
595     mspi_wait();
596 
597     for (j = 0; j < 3; ++j) {
598         *buf++ = mspi_get();
599         mspi_wait();
600     }
601     mspi_fm_rd_dis(); /* off read auto mode */
602     mspi_high();
603     CLOCK_DLY_5_CYC;
604 
605 #if SUPPORT_PFT_ARCH
606     r = core_interrupt_disable();
607     reg_irq_threshold = 0;
608     core_restore_interrupt(r);
609 #else
610     core_restore_interrupt(r);  // ???irq_restore(r);
611 #endif
612 }
flash_read_mid(unsigned char * buf)613 _attribute_text_sec_ void flash_read_mid(unsigned char *buf)
614 {
615     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
616     flash_read_mid_ram(buf);
617     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
618 }
619 
620 /**
621  * @brief	  	This function serves to read UID of flash
622  * @param[in] 	idcmd	- different flash vendor have different read-uid command. E.g: GD/PUYA:0x4B; XTX: 0x5A
623  * @param[in] 	buf		- store UID of flash
624  * @return    	none.
625  */
flash_read_uid_ram(unsigned char idcmd,unsigned char * buf)626 _attribute_ram_code_sec_noinline_ void flash_read_uid_ram(unsigned char idcmd, unsigned char *buf)
627 {
628     unsigned char j = 0;
629 #if SUPPORT_PFT_ARCH
630     unsigned int r = core_interrupt_disable();
631     reg_irq_threshold = 1;
632     core_restore_interrupt(r);
633 #else
634     unsigned int r = core_interrupt_disable();
635 #endif
636 
637     mspi_stop_xip();
638     flash_send_cmd(idcmd);
639     if (idcmd == FLASH_GD_PUYA_READ_UID_CMD) {  // < GD/puya
640         flash_send_addr(0x00);
641         mspi_write(0x00); /* dummy,  to issue clock */
642         mspi_wait();
643     } else if (idcmd == FLASH_XTX_READ_UID_CMD) {  // < XTX
644         flash_send_addr(0x80);
645         mspi_write(0x00); /* dummy,  to issue clock */
646         mspi_wait();
647     }
648     mspi_write(0x00); /* dummy,  to issue clock */
649     mspi_wait();
650     mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */
651     mspi_wait();
652 
653     for (j = 0; j < 16; ++j) {
654         *buf++ = mspi_get();
655         mspi_wait();
656     }
657     mspi_fm_rd_dis(); /* off read auto mode */
658     mspi_high();
659     CLOCK_DLY_5_CYC;
660 
661 #if SUPPORT_PFT_ARCH
662     r = core_interrupt_disable();
663     reg_irq_threshold = 0;
664     core_restore_interrupt(r);
665 #else
666     core_restore_interrupt(r);  // ???irq_restore(r);
667 #endif
668 }
flash_read_uid(unsigned char idcmd,unsigned char * buf)669 _attribute_text_sec_ void flash_read_uid(unsigned char idcmd, unsigned char *buf)
670 {
671     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
672     flash_read_uid_ram(idcmd, buf);
673     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
674 }
675 
676 /**
677  * @brief		This function serves to read flash mid and uid,and check the correctness of mid and uid.
678  * @param[out]	flash_mid	- Flash Manufacturer ID
679  * @param[out]	flash_uid	- Flash Unique ID
680  * @return		0:error 1:ok
681  */
flash_read_mid_uid_with_check_ram(unsigned int * flash_mid,unsigned char * flash_uid)682 _attribute_ram_code_sec_noinline_ int flash_read_mid_uid_with_check_ram(unsigned int *flash_mid,
683                                                                         unsigned char *flash_uid)
684 {
685     unsigned char no_uid[16] = {0x51, 0x01, 0x51, 0x01, 0x51, 0x01, 0x51, 0x01,
686                                 0x51, 0x01, 0x51, 0x01, 0x51, 0x01, 0x51, 0x01};
687     int i, f_cnt = 0;
688     unsigned int mid;
689 
690     mspi_stop_xip();
691     flash_read_mid((unsigned char *)&mid);
692     mid = mid & 0xffff;
693     *flash_mid = mid;
694     //     	  			CMD         MID
695     //  GD25LD40C		0x4b		0x60c8
696     //  GD25LD05C		0x4b		0x60c8
697     //  P25Q40L			0x4b		0x6085
698     //  MD25D40DGIG		0x4b		0x4051
699     if ((mid == 0x60C8) || (mid == 0x6085) || (mid == 0x4051)) {
700         flash_read_uid(FLASH_GD_PUYA_READ_UID_CMD, (unsigned char *)flash_uid);
701     } else {
702         return 0;
703     }
704     for (i = 0; i < 16; i++) {
705         if (flash_uid[i] == no_uid[i]) {
706             f_cnt++;
707         }
708     }
709     if (f_cnt == 16) {  // no uid flash
710         return 0;
711     } else {
712         return 1;
713     }
714     CLOCK_DLY_5_CYC;
715 }
flash_read_mid_uid_with_check(unsigned int * flash_mid,unsigned char * flash_uid)716 _attribute_text_sec_ int flash_read_mid_uid_with_check(unsigned int *flash_mid, unsigned char *flash_uid)
717 {
718     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
719     int result = flash_read_mid_uid_with_check_ram(flash_mid, flash_uid);
720     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
721     return result;
722 }
723 
724 #if (!RAMCODE_OPTIMIZE_UNUSED_FLASH_API_NOT_IMPLEMENT)
725 /**
726  * @brief 		This function serves to set the protection area of the flash.
727  * @param[in]   type	- flash type include Puya.
728  * @param[in]   data	- refer to Driver API Doc.
729  * @return 		none.
730  */
flash_lock_ram(flash_type_e type,unsigned short data)731 _attribute_ram_code_sec_noinline_ void flash_lock_ram(flash_type_e type, unsigned short data)
732 {
733 #if SUPPORT_PFT_ARCH
734     unsigned int r = core_interrupt_disable();
735     reg_irq_threshold = 1;
736     core_restore_interrupt(r);
737 #else
738     unsigned int r = core_interrupt_disable();
739 #endif
740 
741     mspi_stop_xip();
742     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
743     flash_send_cmd(FLASH_WRITE_STATUS_CMD);
744     if (type == FLASH_TYPE_PUYA) {
745         mspi_write((unsigned char)data);
746         mspi_wait();
747         mspi_write((unsigned char)(data >> 8));  // 16bit status
748     }
749     mspi_wait();
750     mspi_high();
751     flash_wait_done();
752     mspi_high();
753     CLOCK_DLY_5_CYC;
754 
755 #if SUPPORT_PFT_ARCH
756     r = core_interrupt_disable();
757     reg_irq_threshold = 0;
758     core_restore_interrupt(r);
759 #else
760     core_restore_interrupt(r);  // ???irq_restore(r);
761 #endif
762 }
flash_lock(flash_type_e type,unsigned short data)763 _attribute_text_sec_ void flash_lock(flash_type_e type, unsigned short data)
764 {
765     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
766     flash_lock_ram(type, data);
767     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
768 }
769 
770 /**
771  * @brief 		This function serves to flash release protection.
772  * @param[in]   type	- flash type include Puya.
773  * @return 		none.
774  */
flash_unlock_ram(flash_type_e type)775 _attribute_ram_code_sec_noinline_ void flash_unlock_ram(flash_type_e type)
776 {
777 #if SUPPORT_PFT_ARCH
778     unsigned int r = core_interrupt_disable();
779     reg_irq_threshold = 1;
780     core_restore_interrupt(r);
781 #else
782     unsigned int r = core_interrupt_disable();
783 #endif
784 
785     mspi_stop_xip();
786     flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
787     flash_send_cmd(FLASH_WRITE_STATUS_CMD);
788     if (type == FLASH_TYPE_PUYA) {
789         mspi_write(0);
790         mspi_wait();
791         mspi_write(0);  // 16bit status
792     }
793     mspi_wait();
794     mspi_high();
795     flash_wait_done();
796     mspi_high();
797     CLOCK_DLY_5_CYC;
798 #if SUPPORT_PFT_ARCH
799     r = core_interrupt_disable();
800     reg_irq_threshold = 0;
801     core_restore_interrupt(r);
802 #else
803     core_restore_interrupt(r);  // ???irq_restore(r);
804 #endif
805 }
flash_unlock(flash_type_e type)806 _attribute_text_sec_ void flash_unlock(flash_type_e type)
807 {
808     __asm__("csrci 	mmisc_ctl,8");  // disable BTB
809     flash_unlock_ram(type);
810     __asm__("csrsi 	mmisc_ctl,8");  // enable BTB
811 }
812 
813 #endif
814