-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(spi_flash): Add new customize flash driver framework
- Loading branch information
1 parent
8b6657b
commit 1a1fda1
Showing
9 changed files
with
298 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
if(BOOTLOADER_BUILD) | ||
idf_component_register(SRCS "bootloader_flash_driver/bootloader_flash_custom.c" | ||
PRIV_REQUIRES bootloader_support spi_flash | ||
INCLUDE_DIRS bootloader_flash_driver/include | ||
INCLUDE_DIRS "" | ||
LDFRAGMENTS linker.lf) | ||
else() | ||
idf_component_register(SRCS | ||
"app_flash_driver/esp_flash_eon/spi_flash_chip_eon.c" | ||
INCLUDE_DIRS app_flash_driver/include | ||
PRIV_REQUIRES spi_flash bootloader_support esp_common | ||
INCLUDE_DIRS "" | ||
LDFRAGMENTS linker.lf) | ||
|
||
idf_component_add_link_dependency(FROM spi_flash) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
159 changes: 159 additions & 0 deletions
159
esp_flash_nor/app_flash_driver/esp_flash_eon/spi_flash_chip_eon.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/* Custom chip driver example | ||
This example code is in the Public Domain (or CC0 licensed, at your option.) | ||
Unless required by applicable law or agreed to in writing, this | ||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
CONDITIONS OF ANY KIND, either express or implied. | ||
*/ | ||
|
||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/param.h> // For MIN/MAX | ||
#include "esp_log.h" | ||
#include "spi_flash_chip_generic.h" | ||
#include "spi_flash/spi_flash_defs.h" | ||
#include "esp_attr.h" | ||
|
||
|
||
// Not for all the vendors | ||
#define CMD_ENTER_OTP 0x3A | ||
|
||
static const char chip_name[] = "eon"; | ||
|
||
/* Driver for EON flash chip */ | ||
|
||
IRAM_ATTR esp_err_t spi_flash_chip_eon_probe(esp_flash_t *chip, uint32_t flash_id) | ||
{ | ||
/* Check manufacturer and product IDs match our desired masks, | ||
you can search in datasheet with 9FH to get manufacturer and | ||
device identification*/ | ||
const uint8_t MFG_ID = 0x1C; | ||
const uint16_t DEV_ID = 0x7000; | ||
if (flash_id >> 16 != MFG_ID || (flash_id & 0xFF00) != DEV_ID) { | ||
return ESP_ERR_NOT_FOUND; | ||
} | ||
return ESP_OK; | ||
} | ||
|
||
static IRAM_ATTR esp_err_t spi_flash_chip_eon_enter_otp_mode(esp_flash_t* chip) | ||
{ | ||
spi_flash_trans_t trans = { | ||
.command = CMD_ENTER_OTP, | ||
}; | ||
return chip->host->driver->common_command(chip->host, &trans); | ||
} | ||
|
||
static IRAM_ATTR esp_err_t spi_flash_chip_eon_exit_otp_mode(esp_flash_t* chip) | ||
{ | ||
spi_flash_trans_t trans = { | ||
.command = CMD_WRDI, | ||
}; | ||
return chip->host->driver->common_command(chip->host, &trans); | ||
} | ||
|
||
IRAM_ATTR esp_err_t spi_flash_chip_eon_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode) | ||
{ | ||
esp_err_t ret; | ||
ret = spi_flash_chip_eon_enter_otp_mode(chip); | ||
if (ret != ESP_OK) { | ||
return ret; | ||
} | ||
|
||
// On "eon" chips, this involves checking | ||
// bit 1 (QE) of RDSR2 (35h) result | ||
// (it works this way on GigaDevice & Fudan Micro chips, probably others...) | ||
const uint8_t BIT_QE = 1 << 6; | ||
uint32_t sr; | ||
ret = spi_flash_common_read_status_8b_rdsr(chip, &sr); | ||
if (ret == ESP_OK) { | ||
*out_io_mode = ((sr & BIT_QE)? SPI_FLASH_QOUT: 0); | ||
} | ||
|
||
//unconditionally exit OTP mode | ||
esp_err_t ret_exit = spi_flash_chip_eon_exit_otp_mode(chip); | ||
if (ret != ESP_OK) { | ||
return ret; | ||
} | ||
return ret_exit; | ||
} | ||
|
||
IRAM_ATTR esp_err_t spi_flash_chip_eon_set_io_mode(esp_flash_t *chip) | ||
{ | ||
if (!esp_flash_is_quad_mode(chip)) { | ||
return ESP_OK; | ||
} | ||
|
||
esp_err_t ret; | ||
ret = spi_flash_chip_eon_enter_otp_mode(chip); | ||
if (ret != ESP_OK) { | ||
return ret; | ||
} | ||
|
||
// On "eon" chips, this involves checking | ||
// bit 6 (QE) of RDSR (05h) result | ||
const uint32_t BIT_QE = 1 << 6; | ||
ret = spi_flash_common_set_io_mode(chip, | ||
spi_flash_common_write_status_8b_wrsr, | ||
spi_flash_common_read_status_8b_rdsr, | ||
BIT_QE); | ||
|
||
//unconditionally exit OTP mode | ||
esp_err_t ret_exit = spi_flash_chip_eon_exit_otp_mode(chip); | ||
if (ret != ESP_OK) { | ||
return ret; | ||
} | ||
return ret_exit; | ||
} | ||
|
||
IRAM_ATTR esp_err_t spi_flash_chip_eon_suspend_cmd_conf(esp_flash_t *chip) | ||
{ | ||
return ESP_ERR_NOT_SUPPORTED; | ||
} | ||
|
||
IRAM_ATTR spi_flash_caps_t spi_flash_chip_eon_get_caps(esp_flash_t *chip) | ||
{ | ||
spi_flash_caps_t caps_flags = 0; | ||
// 32-bit-address flash is not supported | ||
// flash-suspend is not supported | ||
// flash read unique id is not supported. | ||
return caps_flags; | ||
} | ||
|
||
// The issi chip can use the functions for generic chips except from set read mode and probe, | ||
// So we only replace these two functions. | ||
const DRAM_ATTR spi_flash_chip_t esp_flash_chip_eon = { | ||
.name = chip_name, | ||
.timeout = &spi_flash_chip_generic_timeout, | ||
.probe = spi_flash_chip_eon_probe, | ||
.reset = spi_flash_chip_generic_reset, | ||
.detect_size = spi_flash_chip_generic_detect_size, | ||
.erase_chip = spi_flash_chip_generic_erase_chip, | ||
.erase_sector = spi_flash_chip_generic_erase_sector, | ||
.erase_block = spi_flash_chip_generic_erase_block, | ||
.sector_size = 4 * 1024, | ||
.block_erase_size = 64 * 1024, | ||
|
||
.get_chip_write_protect = spi_flash_chip_generic_get_write_protect, | ||
.set_chip_write_protect = spi_flash_chip_generic_set_write_protect, | ||
|
||
.num_protectable_regions = 0, | ||
.protectable_regions = NULL, | ||
.get_protected_regions = NULL, | ||
.set_protected_regions = NULL, | ||
|
||
.read = spi_flash_chip_generic_read, | ||
.write = spi_flash_chip_generic_write, | ||
.program_page = spi_flash_chip_generic_page_program, | ||
.page_size = 256, | ||
.write_encrypted = spi_flash_chip_generic_write_encrypted, | ||
|
||
.wait_idle = spi_flash_chip_generic_wait_idle, | ||
.set_io_mode = spi_flash_chip_eon_set_io_mode, | ||
.get_io_mode = spi_flash_chip_eon_get_io_mode, | ||
|
||
.read_reg = spi_flash_chip_generic_read_reg, | ||
.yield = spi_flash_chip_generic_yield, | ||
.sus_setup = spi_flash_chip_eon_suspend_cmd_conf, | ||
.get_chip_caps = spi_flash_chip_eon_get_caps, | ||
}; |
20 changes: 20 additions & 0 deletions
20
esp_flash_nor/app_flash_driver/include/spi_flash_chip_custom.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include "esp_flash.h" | ||
#include "spi_flash_chip_driver.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* EON SPI flash chip_drv, uses all the above functions for its operations. In | ||
* default auto detection, this is used as a catchall if a more specific chip_drv | ||
* is not found. | ||
*/ | ||
extern const spi_flash_chip_t esp_flash_chip_eon; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
35 changes: 35 additions & 0 deletions
35
esp_flash_nor/bootloader_flash_driver/bootloader_flash_custom.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#include "bootloader_flash_override.h" | ||
#include "bootloader_flash_priv.h" | ||
#include "esp_rom_spiflash.h" | ||
#include "esp_attr.h" | ||
|
||
/* Array of known flash chips and data to enable Quad I/O mode | ||
Manufacturer & flash ID can be tested by running "esptool.py | ||
flash_id" | ||
If manufacturer ID matches, and flash ID ORed with flash ID mask | ||
matches, enable_qio_mode() will execute "Read Cmd", test if bit | ||
number "QIE Bit" is set, and if not set it will call "Write Cmd" | ||
with this bit set. | ||
Searching of this table stops when the first match is found. | ||
*/ | ||
|
||
IRAM_ATTR unsigned bootloader_read_status_otp_mode_8b(void) | ||
{ | ||
bootloader_execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */ | ||
esp_rom_spiflash_wait_idle(&g_rom_flashchip); | ||
uint32_t read_status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8); | ||
bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */ | ||
return read_status; | ||
} | ||
|
||
IRAM_ATTR void bootloader_write_status_otp_mode_8b(unsigned new_status) | ||
{ | ||
bootloader_execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */ | ||
esp_rom_spiflash_wait_idle(&g_rom_flashchip); | ||
bootloader_execute_flash_command(CMD_WRSR, new_status, 8, 0); | ||
esp_rom_spiflash_wait_idle(&g_rom_flashchip); | ||
bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */ | ||
} |
21 changes: 21 additions & 0 deletions
21
esp_flash_nor/bootloader_flash_driver/include/bootloader_flash_custom.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include <stdint.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief read bootloader status register in eon rule | ||
*/ | ||
unsigned bootloader_read_status_otp_mode_8b(void); | ||
|
||
/** | ||
* @brief write bootloader status register in eon rule | ||
* | ||
* @param new_status | ||
*/ | ||
void bootloader_write_status_otp_mode_8b(unsigned new_status); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[mapping:custom_flash_driver] | ||
archive: libcustom_flash_driver.a | ||
entries: | ||
spi_flash_chip_eon (noflash) |