@@ -263,9 +263,13 @@ esp_err_t bootloader_flash_erase_sector(size_t sector)
263
263
264
264
#include "esp_err.h"
265
265
#include "esp_log.h"
266
+ #include "esp8266/rom_functions.h"
266
267
267
268
#ifndef BOOTLOADER_BUILD
268
269
#include "esp_spi_flash.h"
270
+ #else
271
+ #include "bootloader_flash.h"
272
+ #include "priv/esp_spi_flash_raw.h"
269
273
#endif
270
274
271
275
#ifdef CONFIG_SOC_FULL_ICACHE
@@ -274,18 +278,11 @@ esp_err_t bootloader_flash_erase_sector(size_t sector)
274
278
#define SOC_CACHE_SIZE 0 // 16KB
275
279
#endif
276
280
277
- extern void Cache_Read_Disable ();
278
- extern void Cache_Read_Enable (uint8_t map , uint8_t p , uint8_t v );
279
-
280
- static const char * TAG = "bootloader_flash" ;
281
+ #define XMC_SUPPORT CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT
281
282
282
- typedef enum { SPI_FLASH_RESULT_OK = 0 ,
283
- SPI_FLASH_RESULT_ERR = 1 ,
284
- SPI_FLASH_RESULT_TIMEOUT = 2 } SpiFlashOpResult ;
283
+ #define BYTESHIFT (VAR , IDX ) (((VAR) >> ((IDX) * 8)) & 0xFF)
285
284
286
- SpiFlashOpResult SPIRead (uint32_t addr , void * dst , uint32_t size );
287
- SpiFlashOpResult SPIWrite (uint32_t addr , const uint8_t * src , uint32_t size );
288
- SpiFlashOpResult SPIEraseSector (uint32_t sector_num );
285
+ static const char * TAG = "bootloader_flash" ;
289
286
290
287
static bool mapped ;
291
288
@@ -406,4 +403,150 @@ esp_err_t bootloader_flash_erase_sector(size_t sector)
406
403
return ESP_OK ;
407
404
}
408
405
406
+ #ifdef BOOTLOADER_BUILD
407
+ uint32_t bootloader_read_flash_id (void )
408
+ {
409
+ uint32_t id = spi_flash_get_id_raw (& g_rom_flashchip );
410
+ id = ((id & 0xff ) << 16 ) | ((id >> 16 ) & 0xff ) | (id & 0xff00 );
411
+ return id ;
412
+ }
413
+
414
+ #if XMC_SUPPORT
415
+ static bool is_xmc_chip_strict (uint32_t rdid )
416
+ {
417
+ uint32_t vendor_id = BYTESHIFT (rdid , 2 );
418
+ uint32_t mfid = BYTESHIFT (rdid , 1 );
419
+ uint32_t cpid = BYTESHIFT (rdid , 0 );
420
+
421
+ if (vendor_id != XMC_VENDOR_ID ) {
422
+ return false;
423
+ }
424
+
425
+ bool matched = false;
426
+ if (mfid == 0x40 ) {
427
+ if (cpid >= 0x13 && cpid <= 0x20 ) {
428
+ matched = true;
429
+ }
430
+ } else if (mfid == 0x41 ) {
431
+ if (cpid >= 0x17 && cpid <= 0x20 ) {
432
+ matched = true;
433
+ }
434
+ } else if (mfid == 0x50 ) {
435
+ if (cpid >= 0x15 && cpid <= 0x16 ) {
436
+ matched = true;
437
+ }
438
+ }
439
+ return matched ;
440
+ }
441
+
442
+ bool bootloader_execute_flash_command (uint8_t command , uint32_t mosi_data , uint8_t mosi_len , uint8_t miso_len )
443
+ {
444
+ bool ret ;
445
+ spi_cmd_t cmd ;
446
+
447
+ cmd .cmd = command ;
448
+ cmd .cmd_len = 1 ;
449
+ cmd .addr = NULL ;
450
+ cmd .addr_len = 0 ;
451
+ cmd .dummy_bits = 0 ;
452
+ cmd .data = NULL ;
453
+ cmd .data_len = 0 ;
454
+
455
+ ret = spi_user_cmd_raw (& g_rom_flashchip , SPI_TX , & cmd );
456
+ if (!ret ) {
457
+ ESP_LOGE (TAG , "failed to write cmd=%02x" , command );
458
+ }
459
+
460
+ return ret ;
461
+ }
462
+
463
+ uint32_t bootloader_flash_read_sfdp (uint32_t sfdp_addr , unsigned int miso_byte_num )
464
+ {
465
+ bool ret ;
466
+ spi_cmd_t cmd ;
467
+ uint32_t data = 0 ;
468
+ uint32_t addr = sfdp_addr << 8 ;
469
+
470
+ cmd .cmd = CMD_RDSFDP ;
471
+ cmd .cmd_len = 1 ;
472
+ cmd .addr = & addr ;
473
+ cmd .addr_len = 3 ;
474
+ cmd .dummy_bits = 8 ;
475
+ cmd .data = & data ;
476
+ cmd .data_len = miso_byte_num ;
477
+
478
+ ret = spi_user_cmd_raw (& g_rom_flashchip , SPI_RX , & cmd );
479
+ if (!ret ) {
480
+ ESP_LOGE (TAG , "failed to read sfdp" );
481
+ }
482
+
483
+ return data ;
484
+ }
485
+
486
+ esp_err_t bootloader_flash_xmc_startup (void )
487
+ {
488
+ extern void ets_rom_delay_us (uint16_t us );
489
+
490
+ uint32_t id = bootloader_read_flash_id ();
491
+
492
+ // If the RDID value is a valid XMC one, may skip the flow
493
+ const bool fast_check = true;
494
+ if (fast_check && is_xmc_chip_strict (id )) {
495
+ ESP_LOGD (TAG , "XMC chip detected by RDID (%08X), skip." , id );
496
+ return ESP_OK ;
497
+ }
498
+
499
+ // Check the Manufacturer ID in SFDP registers (JEDEC standard). If not XMC chip, no need to run the flow
500
+ const int sfdp_mfid_addr = 0x10 ;
501
+ uint8_t mf_id = (bootloader_flash_read_sfdp (sfdp_mfid_addr , 1 ) & 0xff );
502
+ if (mf_id != XMC_VENDOR_ID ) {
503
+ ESP_LOGD (TAG , "non-XMC chip detected by SFDP Read (%02X), skip." , mf_id );
504
+ return ESP_OK ;
505
+ }
506
+
507
+ ESP_LOGI (TAG , "XM25QHxxC startup flow" );
508
+ // Enter DPD
509
+ bootloader_execute_flash_command (0xB9 , 0 , 0 , 0 );
510
+ // Enter UDPD
511
+ bootloader_execute_flash_command (0x79 , 0 , 0 , 0 );
512
+ // Exit UDPD
513
+ bootloader_execute_flash_command (0xFF , 0 , 0 , 0 );
514
+ // Delay tXUDPD
515
+ ets_rom_delay_us (2000 );
516
+ // Release Power-down
517
+ bootloader_execute_flash_command (0xAB , 0 , 0 , 0 );
518
+ ets_rom_delay_us (20 );
519
+ // Read flash ID and check again
520
+ id = bootloader_read_flash_id ();
521
+ if (!is_xmc_chip_strict (id )) {
522
+ ESP_LOGE (TAG , "XMC flash startup fail" );
523
+ return ESP_FAIL ;
524
+ }
525
+
526
+ return ESP_OK ;
527
+ }
528
+ #else
529
+ static bool is_xmc_chip (uint32_t rdid )
530
+ {
531
+ uint32_t vendor_id = (rdid >> 16 ) & 0xff ;
532
+
533
+ return vendor_id == XMC_VENDOR_ID ;
534
+ }
535
+
536
+ esp_err_t bootloader_flash_xmc_startup (void )
537
+ {
538
+ uint32_t id = bootloader_read_flash_id ();
539
+
540
+ if (is_xmc_chip (id )) {
541
+ ESP_LOGE (TAG , "XMC chip detected(%08X) while support disable." , id );
542
+ return ESP_FAIL ;
543
+ } else {
544
+ ESP_LOGI (TAG , "flash chip is %08X" , id );
545
+ }
546
+
547
+ return ESP_OK ;
548
+ }
549
+ #endif
550
+ #endif
551
+
409
552
#endif
0 commit comments