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
19 /********************************************************************************************************
20 * @file flash.c
21 *
22 * @brief This is the source file for B91
23 *
24 * @author Driver Group
25 *
26 *******************************************************************************************************/
27 #include "flash.h"
28 #include "mspi.h"
29 #include "plic.h"
30 #include "timer.h"
31 #include "sys.h"
32 #include "core.h"
33 #include "stimer.h"
34
35 #if (CONFIG_BT_B91)
36 #include "stack/ble/controller/ble_controller.h"
37 #endif /* CONFIG_BT_B91 */
38
39 #define DISABLE_BTB __asm__("csrci 0x7D0,8")
40 #define ENABLE_BTB __asm__("csrsi 0x7D0,8")
41
42 volatile unsigned char flash_cnt = 1;
43
44 static preempt_config_t s_flash_preempt_config =
45 {
46 .preempt_en =0,
47 .threshold =1,
48 };
49
50 /**
51 * @brief This function serves to set priority threshold. when the interrupt priority > Threshold flash process will disturb by interrupt.
52 * @param[in] preempt_en - 1 can disturb by interrupt, 0 can disturb by interrupt.
53 * @param[in] threshold - priority Threshold.
54 * @return none.
55 */
flash_plic_preempt_config(unsigned char preempt_en,unsigned char threshold)56 void flash_plic_preempt_config(unsigned char preempt_en,unsigned char threshold)
57 {
58 s_flash_preempt_config.preempt_en=preempt_en;
59 s_flash_preempt_config.threshold=threshold;
60 }
61
62 /********************************************************************************************************
63 * Functions for internal use in flash,
64 * There is no need to add an evasion solution to solve the problem of access flash conflicts.
65 *******************************************************************************************************/
66 /**
67 * @brief This function to determine whether the flash is busy..
68 * @return 1:Indicates that the flash is busy. 0:Indicates that the flash is free
69 */
flash_is_busy(void)70 static inline int flash_is_busy(void)
71 {
72 return mspi_read() & 0x01; // the busy bit, pls check flash spec
73 }
74
75 /**
76 * @brief This function serves to set flash write command.This function interface is only used internally by flash,
77 * and is currently included in the H file for compatibility with other SDKs. When using this interface,
78 * please ensure that you understand the precautions of flash before using it.
79 * @param[in] cmd - set command.
80 * @return none.
81 */
flash_send_cmd(unsigned char cmd)82 _attribute_ram_code_sec_noinline_ void flash_send_cmd(unsigned char cmd)
83 {
84 mspi_high();
85 CLOCK_DLY_10_CYC;
86 mspi_low();
87 mspi_write(cmd);
88 mspi_wait();
89 }
90
91 /**
92 * @brief This function serves to send flash address.
93 * @param[in] addr - the flash address.
94 * @return none.
95 */
flash_send_addr(unsigned int addr)96 _attribute_ram_code_sec_noinline_ static void flash_send_addr(unsigned int addr)
97 {
98 mspi_write((unsigned char)(addr>>16));
99 mspi_wait();
100 mspi_write((unsigned char)(addr>>8));
101 mspi_wait();
102 mspi_write((unsigned char)(addr));
103 mspi_wait();
104 }
105
106 /**
107 * @brief This function serves to wait flash done.(make this a asynchorous version).
108 * @return none.
109 */
flash_wait_done(void)110 _attribute_ram_code_sec_noinline_ static void flash_wait_done(void)
111 {
112 flash_send_cmd(FLASH_READ_STATUS_CMD);
113
114 int i;
115 for(i = 0; i < 10000000; ++i){
116 if(!flash_is_busy()){
117 flash_cnt++;
118 break;
119 }
120 #if (CONFIG_BT_B91)
121 blc_sdk_irq_handler();
122 #endif /* CONFIG_BT_B91 */
123 }
124 mspi_high();
125 }
126
127
128 /********************************************************************************************************
129 * It is necessary to add an evasion plan to solve the problem of access flash conflict.
130 *******************************************************************************************************/
131 /**
132 * @brief This function serves to erase a sector.
133 * @param[in] addr - the start address of the sector needs to erase.
134 * @return none.
135 */
flash_erase_sector_ram(unsigned long addr)136 _attribute_ram_code_sec_noinline_ void flash_erase_sector_ram(unsigned long addr)
137 {
138 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
139 mspi_stop_xip();
140 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
141 flash_send_cmd(FLASH_SECT_ERASE_CMD);
142 flash_send_addr(addr);
143 mspi_high();
144 flash_wait_done();
145 CLOCK_DLY_5_CYC;
146 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
147 }
flash_erase_sector(unsigned long addr)148 _attribute_text_sec_ void flash_erase_sector(unsigned long addr)
149 {
150 DISABLE_BTB;
151 flash_erase_sector_ram(addr);
152 ENABLE_BTB;
153 }
154
155 /**
156 * @brief This function writes the buffer's content to a page.
157 * @param[in] addr - the start address of the page.
158 * @param[in] len - the length(in byte) of content needs to write into the page.
159 * @param[in] buf - the start address of the content needs to write into.
160 * @return none.
161 */
flash_write_page_ram(unsigned long addr,unsigned long len,unsigned char * buf)162 _attribute_ram_code_sec_noinline_ void flash_write_page_ram(unsigned long addr, unsigned long len, unsigned char *buf)
163 {
164 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
165 mspi_stop_xip();
166 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
167 flash_send_cmd(FLASH_WRITE_CMD);
168 flash_send_addr(addr);
169
170 unsigned int i;
171 for(i = 0; i < len; ++i){
172 mspi_write(buf[i]); /* write data */
173 mspi_wait();
174 }
175 mspi_high();
176 flash_wait_done();
177 CLOCK_DLY_5_CYC;
178 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
179 }
flash_write_page(unsigned long addr,unsigned long len,unsigned char * buf)180 _attribute_text_sec_ void flash_write_page(unsigned long addr, unsigned long len, unsigned char *buf)
181 {
182 unsigned int ns = PAGE_SIZE - (addr & 0xff);
183 int nw = 0;
184
185 do{
186 nw = len > ns ? ns : len;
187 DISABLE_BTB;
188 flash_write_page_ram(addr,nw,buf);
189 ENABLE_BTB;
190 ns = PAGE_SIZE;
191 addr += nw;
192 buf += nw;
193 len -= nw;
194 }while(len > 0);
195 }
196
197 /**
198 * @brief This function reads the content from a page to the buf.
199 * @param[in] addr - the start address of the page.
200 * @param[in] len - the length(in byte) of content needs to read out from the page.
201 * @param[out] buf - the start address of the buffer.
202 * @return none.
203 */
flash_read_page_ram(unsigned long addr,unsigned long len,unsigned char * buf)204 _attribute_ram_code_sec_noinline_ void flash_read_page_ram(unsigned long addr, unsigned long len, unsigned char *buf)
205 {
206 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
207 mspi_stop_xip();
208 flash_send_cmd(FLASH_READ_CMD);
209 flash_send_addr(addr);
210
211 mspi_write(0x00); /* dummy, to issue clock */
212 mspi_wait();
213 mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */
214 mspi_wait();
215 /* get data */
216 for(unsigned int i = 0; i < len; ++i){
217 *buf++ = mspi_get();
218 mspi_wait();
219 }
220 mspi_fm_rd_dis(); /* off read auto mode */
221 mspi_high();
222 CLOCK_DLY_5_CYC;
223 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
224 }
flash_read_page(unsigned long addr,unsigned long len,unsigned char * buf)225 _attribute_text_sec_ void flash_read_page(unsigned long addr, unsigned long len, unsigned char *buf)
226 {
227 DISABLE_BTB;
228 flash_read_page_ram(addr,len,buf);
229 ENABLE_BTB;
230 }
231
232 /**
233 * @brief This function serves to erase a chip.
234 * @return none.
235 */
flash_erase_chip_ram(void)236 _attribute_ram_code_sec_noinline_ void flash_erase_chip_ram(void)
237 {
238 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
239 mspi_stop_xip();
240 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
241 flash_send_cmd(FLASH_CHIP_ERASE_CMD);
242 mspi_high();
243 flash_wait_done();
244 CLOCK_DLY_5_CYC;
245 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
246 }
flash_erase_chip(void)247 _attribute_text_sec_ void flash_erase_chip(void)
248 {
249 DISABLE_BTB;
250 flash_erase_chip_ram();
251 ENABLE_BTB;
252 }
253
254 /**
255 * @brief This function serves to erase a page(256 bytes).
256 * @param[in] addr - the start address of the page needs to erase.
257 * @return none.
258 */
flash_erase_page_ram(unsigned int addr)259 _attribute_ram_code_sec_noinline_ void flash_erase_page_ram(unsigned int addr)
260 {
261 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
262
263 mspi_stop_xip();
264 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
265 flash_send_cmd(FLASH_PAGE_ERASE_CMD);
266 flash_send_addr(addr);
267 mspi_high();
268 flash_wait_done();
269 CLOCK_DLY_5_CYC;
270 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
271 }
flash_erase_page(unsigned int addr)272 _attribute_text_sec_ void flash_erase_page(unsigned int addr)
273 {
274 DISABLE_BTB;
275 flash_erase_page_ram(addr);
276 ENABLE_BTB;
277 }
278
279 /**
280 * @brief This function serves to erase a block(32k).
281 * @param[in] addr - the start address of the block needs to erase.
282 * @return none.
283 */
flash_erase_32kblock_ram(unsigned int addr)284 _attribute_ram_code_sec_noinline_ void flash_erase_32kblock_ram(unsigned int addr)
285 {
286 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
287 mspi_stop_xip();
288 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
289 flash_send_cmd(FLASH_32KBLK_ERASE_CMD);
290 flash_send_addr(addr);
291 mspi_high();
292 flash_wait_done();
293 CLOCK_DLY_5_CYC;
294 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
295 }
flash_erase_32kblock(unsigned int addr)296 _attribute_text_sec_ void flash_erase_32kblock(unsigned int addr)
297 {
298 DISABLE_BTB;
299 flash_erase_32kblock_ram(addr);
300 ENABLE_BTB;
301 }
302
303 /**
304 * @brief This function serves to erase a block(64k).
305 * @param[in] addr - the start address of the block needs to erase.
306 * @return none.
307 */
flash_erase_64kblock_ram(unsigned int addr)308 _attribute_ram_code_sec_noinline_ void flash_erase_64kblock_ram(unsigned int addr)
309 {
310 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
311 mspi_stop_xip();
312 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
313 flash_send_cmd(FLASH_64KBLK_ERASE_CMD);
314 flash_send_addr(addr);
315 mspi_high();
316 flash_wait_done();
317 CLOCK_DLY_5_CYC;
318 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
319 }
flash_erase_64kblock(unsigned int addr)320 _attribute_text_sec_ void flash_erase_64kblock(unsigned int addr)
321 {
322 DISABLE_BTB;
323 flash_erase_64kblock_ram(addr);
324 ENABLE_BTB;
325 }
326
327 /**
328 * @brief This function write the status of flash.
329 * @param[in] data - the value of status.
330 * @return none.
331 */
flash_write_status_ram(unsigned short data)332 _attribute_ram_code_sec_noinline_ void flash_write_status_ram(unsigned short data)
333 {
334 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
335 mspi_stop_xip();
336 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
337 flash_send_cmd(FLASH_WRITE_STATUS_CMD);
338 mspi_write((unsigned char)data);
339 mspi_wait();
340 mspi_write((unsigned char)(data>>8));
341 mspi_wait();
342 mspi_high();
343 flash_wait_done();
344 mspi_high();
345 CLOCK_DLY_5_CYC;
346 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
347 }
flash_write_status(unsigned short data)348 _attribute_text_sec_ void flash_write_status(unsigned short data)
349 {
350 DISABLE_BTB;
351 flash_write_status_ram(data);
352 ENABLE_BTB;
353 }
354
355 /**
356 * @brief This function reads the status of flash.
357 * @return the value of status.
358 */
flash_read_status_ram(void)359 _attribute_ram_code_sec_noinline_ unsigned short flash_read_status_ram(void)
360 {
361 unsigned short status = 0;
362 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
363
364 mspi_stop_xip();
365 flash_send_cmd(FLASH_READ_STATUS_1_CMD); /* get high 8 bit status */
366 status = (mspi_read()<<8);
367 mspi_high();
368 flash_send_cmd(FLASH_READ_STATUS_CMD); /* get low 8 bit status */
369 status |= mspi_read();
370 mspi_high();
371 CLOCK_DLY_5_CYC;
372
373 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
374 return status;
375 }
flash_read_status(void)376 _attribute_text_sec_ unsigned short flash_read_status(void)
377 {
378 DISABLE_BTB;
379 unsigned short status = flash_read_status_ram();
380 ENABLE_BTB;
381 return status;
382 }
383
384 /**
385 * @brief Deep Power Down mode to put the device in the lowest consumption mode
386 * it can be used as an extra software protection mechanism,while the device
387 * is not in active use,since in the mode, all write,Program and Erase commands
388 * are ignored,except the Release from Deep Power-Down and Read Device ID(RDI)
389 * command.This release the device from this mode
390 * @return none.
391 */
flash_deep_powerdown_ram(void)392 _attribute_ram_code_sec_noinline_ void flash_deep_powerdown_ram(void)
393 {
394 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
395
396 mspi_stop_xip();
397 flash_send_cmd(FLASH_POWER_DOWN);
398 mspi_high();
399 delay_us(1);
400 CLOCK_DLY_5_CYC;
401
402 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
403 }
flash_deep_powerdown(void)404 _attribute_text_sec_ void flash_deep_powerdown(void)
405 {
406 DISABLE_BTB;
407 flash_deep_powerdown_ram();
408 ENABLE_BTB;
409 }
410
411 /**
412 * @brief The Release from Power-Down or High Performance Mode/Device ID command is a
413 * Multi-purpose command.it can be used to release the device from the power-Down
414 * State or High Performance Mode or obtain the devices electronic identification
415 * (ID)number.Release from Power-Down will take the time duration of tRES1 before
416 * the device will resume normal operation and other command are accepted.The CS#
417 * pin must remain high during the tRES1(8us) time duration.
418 * @return none.
419 */
flash_release_deep_powerdown_ram(void)420 _attribute_ram_code_sec_noinline_ void flash_release_deep_powerdown_ram(void)
421 {
422 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
423
424 mspi_stop_xip();
425 flash_send_cmd(FLASH_POWER_DOWN_RELEASE);
426 mspi_high();
427 flash_wait_done();
428 mspi_high();
429 CLOCK_DLY_5_CYC;
430
431 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
432 }
flash_release_deep_powerdown(void)433 _attribute_text_sec_ void flash_release_deep_powerdown(void)
434 {
435 DISABLE_BTB;
436 flash_release_deep_powerdown_ram();
437 ENABLE_BTB;
438 }
439
440 /**
441 * @brief This function serves to read MID of flash(MAC id). Before reading UID of flash,
442 * you must read MID of flash. and then you can look up the related table to select
443 * the idcmd and read UID of flash
444 * @return MID of the flash(4 bytes).
445 */
flash_read_mid_ram(void)446 _attribute_ram_code_sec_noinline_ unsigned int flash_read_mid_ram(void){
447
448 unsigned char j = 0;
449 unsigned int flash_mid = 0;
450 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
451
452 mspi_stop_xip();
453 flash_send_cmd(FLASH_GET_JEDEC_ID);
454 mspi_write(0x00); /* dummy, to issue clock */
455 mspi_wait();
456 mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */
457 mspi_wait();
458
459 for(j = 0; j < 3; ++j){
460 ((unsigned char*)(&flash_mid))[j] = mspi_get();
461 mspi_wait();
462 }
463 mspi_fm_rd_dis(); /* off read auto mode */
464 mspi_high();
465 CLOCK_DLY_5_CYC;
466
467 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
468 return flash_mid;
469 }
flash_read_mid(void)470 _attribute_text_sec_ unsigned int flash_read_mid(void){
471
472 unsigned int flash_mid = 0;
473 DISABLE_BTB;
474 flash_mid = flash_read_mid_ram();
475 ENABLE_BTB;
476 return flash_mid;
477 }
478
479 /**
480 * @brief This function serves to read UID of flash
481 * @param[in] idcmd - different flash vendor have different read-uid command. E.g: GD/PUYA:0x4B; XTX: 0x5A
482 * @param[in] buf - store UID of flash
483 * @return none.
484 */
flash_read_uid_ram(unsigned char idcmd,unsigned char * buf)485 _attribute_ram_code_sec_noinline_ void flash_read_uid_ram(unsigned char idcmd,unsigned char *buf)
486 {
487 unsigned char j = 0;
488 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
489
490 mspi_stop_xip();
491 flash_send_cmd(idcmd);
492 if(idcmd==FLASH_GD_PUYA_READ_UID_CMD) //< GD/puya
493 {
494 flash_send_addr(0x00);
495 mspi_write(0x00); /* dummy, to issue clock */
496 mspi_wait();
497 }
498 else if (idcmd==FLASH_XTX_READ_UID_CMD) //< XTX
499 {
500 flash_send_addr(0x80);
501 mspi_write(0x00); /* dummy, to issue clock */
502 mspi_wait();
503
504 }
505 mspi_write(0x00); /* dummy, to issue clock */
506 mspi_wait();
507 mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */
508 mspi_wait();
509
510 for(j = 0; j < 16; ++j){
511 *buf++ = mspi_get();
512 mspi_wait();
513 }
514 mspi_fm_rd_dis(); /* off read auto mode */
515 mspi_high();
516 CLOCK_DLY_5_CYC;
517
518 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
519 }
flash_read_uid(unsigned char idcmd,unsigned char * buf)520 _attribute_text_sec_ void flash_read_uid(unsigned char idcmd,unsigned char *buf)
521 {
522 DISABLE_BTB;
523 flash_read_uid_ram(idcmd,buf);
524 ENABLE_BTB;
525 }
526
527
528 /**
529 * @brief This function serves to set the protection area of the flash.
530 * @param[in] type - flash type include Puya.
531 * @param[in] data - refer to Driver API Doc.
532 * @return none.
533 */
flash_lock_ram(flash_type_e type,unsigned short data)534 _attribute_ram_code_sec_noinline_ void flash_lock_ram(flash_type_e type , unsigned short data)
535 {
536 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
537
538 mspi_stop_xip();
539 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
540 flash_send_cmd(FLASH_WRITE_STATUS_CMD);
541 if(type == FLASH_TYPE_PUYA)
542 {
543 mspi_write((unsigned char)data);
544 mspi_wait();
545 mspi_write((unsigned char)(data>>8));//16bit status
546
547 }
548 mspi_wait();
549 mspi_high();
550 flash_wait_done();
551 mspi_high();
552 CLOCK_DLY_5_CYC;
553
554 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
555 }
flash_lock(flash_type_e type,unsigned short data)556 _attribute_text_sec_ void flash_lock(flash_type_e type , unsigned short data)
557 {
558 DISABLE_BTB;
559 flash_lock_ram(type,data);
560 ENABLE_BTB;
561 }
562
563 /**
564 * @brief This function serves to flash release protection.
565 * @param[in] type - flash type include Puya.
566 * @return none.
567 */
flash_unlock_ram(flash_type_e type)568 _attribute_ram_code_sec_noinline_ void flash_unlock_ram(flash_type_e type)
569 {
570 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
571
572 mspi_stop_xip();
573 flash_send_cmd(FLASH_WRITE_ENABLE_CMD);
574 flash_send_cmd(FLASH_WRITE_STATUS_CMD);
575 if(type == FLASH_TYPE_PUYA)
576 {
577 mspi_write(0);
578 mspi_wait();
579 mspi_write(0);//16bit status
580 }
581 mspi_wait();
582 mspi_high();
583 flash_wait_done();
584 mspi_high();
585 CLOCK_DLY_5_CYC;
586
587 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
588 }
flash_unlock(flash_type_e type)589 _attribute_text_sec_ void flash_unlock(flash_type_e type)
590 {
591 DISABLE_BTB;
592 flash_unlock_ram(type);
593 ENABLE_BTB;
594 }
595 /**
596 * @brief This function is used to update the configuration parameters of xip(eXecute In Place),
597 * this configuration will affect the speed of MCU fetching,
598 * this parameter needs to be consistent with the corresponding parameters in the flash datasheet.
599 * @param[in] config - xip configuration,reference structure flash_xip_config_t
600 * @return none
601 */
flash_set_xip_config_sram(flash_xip_config_t config)602 _attribute_ram_code_sec_noinline_ void flash_set_xip_config_sram(flash_xip_config_t config)
603 {
604 unsigned int r=plic_enter_critical_sec(s_flash_preempt_config.preempt_en,s_flash_preempt_config.threshold);
605
606 mspi_stop_xip();
607 reg_mspi_xip_config = *((unsigned short*)(&config));
608 CLOCK_DLY_5_CYC;
609
610 plic_exit_critical_sec(s_flash_preempt_config.preempt_en,r);
611 }
flash_set_xip_config(flash_xip_config_t config)612 _attribute_text_sec_ void flash_set_xip_config(flash_xip_config_t config)
613 {
614 DISABLE_BTB;
615 flash_set_xip_config_sram(config);
616 ENABLE_BTB;
617 }
618
619 /********************************************************************************************************
620 * secondary calling function,
621 * there is no need to add an circumvention solution to solve the problem of access flash conflicts.
622 *******************************************************************************************************/
623 /**
624 * @brief This function serves to read flash mid and uid,and check the correctness of mid and uid.
625 * @param[out] flash_mid - Flash Manufacturer ID
626 * @param[out] flash_uid - Flash Unique ID
627 * @return 0: flash no uid or not a known flash model 1:the flash model is known and the uid is read.
628 */
flash_read_mid_uid_with_check(unsigned int * flash_mid,unsigned char * flash_uid)629 _attribute_text_sec_ int flash_read_mid_uid_with_check( unsigned int *flash_mid ,unsigned char *flash_uid){
630
631 unsigned char no_uid[16]={0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01};
632 int i,f_cnt=0;
633 unsigned int mid;
634
635 mid = flash_read_mid();
636 mid = mid&0xffff;
637 *flash_mid = mid;
638 // CMD MID
639 // P25Q80U 0x4b 0x6085
640 if(mid == 0x6085){
641 flash_read_uid(FLASH_GD_PUYA_READ_UID_CMD,(unsigned char *)flash_uid);
642 }else{
643 return 0;
644 }
645 for(i=0;i<16;i++){
646 if(flash_uid[i]==no_uid[i]){
647 f_cnt++;
648 }
649 }
650 if(f_cnt==16){ //no uid flash
651 return 0;
652 }else{
653 return 1;
654 }
655 }
656
657