-
Notifications
You must be signed in to change notification settings - Fork 7.6k
External flash #8479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
arduino-esp32 uses the spi flash libraries from esp-idf. If you need support for a particular chip, you should ask upstream. |
@savagerex - I remember that your project uses the ESP32-S3-Mini M0N8 with 8MB Flash, no PSRAM. One possible way to solve it, would be to use EEPROM Arduino Library within the S3 module flash. By this way the Winbond external module wouldn't be necessary anymore, but it would use the S3 module flash. Would it work for you? |
i know if i esp32 s3 of flash. but we still need external flash. because external flash(W25Q256JV) is 32M byte. ESP32 S3 of flash only have 16MB. it's not enough. we need external flash to store data. |
In that case, what is the issue that you have when using these libraries: |
I'll also need more details about how the SPI Flash chip is connected to the ESP32-S3 (connected pins). |
@SuGlider External Flash total is 32 M byte. below is the sample code. #include "SPI.h" #define SensorPowerPin 17 #define MOSI 35 #define SPI_FREQUENCY 40 * 1000000 //10 #define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */ void setup() { esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
} void taskTwo( void * parameter ) { SerialFlashFile flashFile; while(SerialFlash.createErasable("123.txt", 2000000)) //2000000 flashFile = SerialFlash.open("123.txt"); if (!flashFile) { for (;;) {
} } void loop() { } |
@savagerex I have created a "translation" from the IDF example to Arduino 2.0.9 (see below), please try it. It uses the default SPI VSPI pins. Please refer to the readme file for more information about changing it. /* Example of FAT filesystem on external Flash.
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.
This sample shows how to store files inside a FAT filesystem.
FAT filesystem is stored in a partition inside SPI flash, using the
flash wear levelling library.
*/
#include "esp_flash.h"
#include "esp_flash_spi_init.h"
#include "esp_vfs_fat.h"
static const char *TAG = "example";
// Handle of the wear levelling library instance
static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
// Mount path for the partition
const char *base_path = "/extflash";
static esp_flash_t* example_init_ext_flash(void);
static const esp_partition_t* example_add_partition(esp_flash_t* ext_flash, const char* partition_label);
static void example_list_data_partitions(void);
static bool example_mount_fatfs(const char* partition_label);
static void example_get_fatfs_usage(size_t* out_total_bytes, size_t* out_free_bytes);
void setup(){
my_app_main();
}
void loop() {
}
void my_app_main(void)
{
// Set up SPI bus and initialize the external SPI Flash chip
esp_flash_t* flash = example_init_ext_flash();
if (flash == NULL) {
return;
}
// Add the entire external flash chip as a partition
const char *partition_label = "storage";
example_add_partition(flash, partition_label);
// List the available partitions
example_list_data_partitions();
// Initialize FAT FS in the partition
if (!example_mount_fatfs(partition_label)) {
return;
}
// Print FAT FS size information
size_t bytes_total, bytes_free;
example_get_fatfs_usage(&bytes_total, &bytes_free);
ESP_LOGI(TAG, "FAT FS: %d kB total, %d kB free", bytes_total / 1024, bytes_free / 1024);
// Create a file in FAT FS
ESP_LOGI(TAG, "Opening file");
FILE *f = fopen("/extflash/hello.txt", "wb");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
fprintf(f, "Written using ESP-IDF %s\n", esp_get_idf_version());
fclose(f);
ESP_LOGI(TAG, "File written");
// Open file for reading
ESP_LOGI(TAG, "Reading file");
f = fopen("/extflash/hello.txt", "rb");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
char line[128];
fgets(line, sizeof(line), f);
fclose(f);
// strip newline
char *pos = strchr(line, '\n');
if (pos) {
*pos = '\0';
}
ESP_LOGI(TAG, "Read from file: '%s'", line);
}
static esp_flash_t* example_init_ext_flash(void)
{
const spi_bus_config_t bus_config = {
.mosi_io_num = VSPI_IOMUX_PIN_NUM_MOSI,
.miso_io_num = VSPI_IOMUX_PIN_NUM_MISO,
.sclk_io_num = VSPI_IOMUX_PIN_NUM_CLK,
.quadwp_io_num = VSPI_IOMUX_PIN_NUM_WP,
.quadhd_io_num = VSPI_IOMUX_PIN_NUM_HD,
};
const esp_flash_spi_device_config_t device_config = {
.host_id = VSPI_HOST,
.cs_io_num = VSPI_IOMUX_PIN_NUM_CS,
.io_mode = SPI_FLASH_DIO,
.speed = ESP_FLASH_40MHZ,
.cs_id = 0,
};
ESP_LOGI(TAG, "Initializing external SPI Flash");
ESP_LOGI(TAG, "Pin assignments:");
ESP_LOGI(TAG, "MOSI: %2d MISO: %2d SCLK: %2d CS: %2d",
bus_config.mosi_io_num, bus_config.miso_io_num,
bus_config.sclk_io_num, device_config.cs_io_num
);
// Initialize the SPI bus
ESP_ERROR_CHECK(spi_bus_initialize(VSPI_HOST, &bus_config, 1));
// Add device to the SPI bus
esp_flash_t* ext_flash;
ESP_ERROR_CHECK(spi_bus_add_flash_device(&ext_flash, &device_config));
// Probe the Flash chip and initialize it
esp_err_t err = esp_flash_init(ext_flash);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize external Flash: %s (0x%x)", esp_err_to_name(err), err);
return NULL;
}
// Print out the ID and size
uint32_t id;
ESP_ERROR_CHECK(esp_flash_read_id(ext_flash, &id));
ESP_LOGI(TAG, "Initialized external Flash, size=%d KB, ID=0x%x", ext_flash->size / 1024, id);
return ext_flash;
}
static const esp_partition_t* example_add_partition(esp_flash_t* ext_flash, const char* partition_label)
{
ESP_LOGI(TAG, "Adding external Flash as a partition, label=\"%s\", size=%d KB", partition_label, ext_flash->size / 1024);
const esp_partition_t* fat_partition;
ESP_ERROR_CHECK(esp_partition_register_external(ext_flash, 0, ext_flash->size, partition_label, ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, &fat_partition));
return fat_partition;
}
static void example_list_data_partitions(void)
{
ESP_LOGI(TAG, "Listing data partitions:");
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL);
for (; it != NULL; it = esp_partition_next(it)) {
const esp_partition_t *part = esp_partition_get(it);
ESP_LOGI(TAG, "- partition '%s', subtype %d, offset 0x%x, size %d kB",
part->label, part->subtype, part->address, part->size / 1024);
}
esp_partition_iterator_release(it);
}
static bool example_mount_fatfs(const char* partition_label)
{
ESP_LOGI(TAG, "Mounting FAT filesystem");
const esp_vfs_fat_mount_config_t mount_config = {
.format_if_mount_failed = true,
.max_files = 4,
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE
};
esp_err_t err = esp_vfs_fat_spiflash_mount(base_path, partition_label, &mount_config, &s_wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
return false;
}
return true;
}
static void example_get_fatfs_usage(size_t* out_total_bytes, size_t* out_free_bytes)
{
FATFS *fs;
size_t free_clusters;
int res = f_getfree("0:", &free_clusters, &fs);
assert(res == FR_OK);
size_t total_sectors = (fs->n_fatent - 2) * fs->csize;
size_t free_sectors = free_clusters * fs->csize;
// assuming the total size is < 4GiB, should be true for SPI Flash
if (out_total_bytes != NULL) {
*out_total_bytes = total_sectors * fs->ssize;
}
if (out_free_bytes != NULL) {
*out_free_bytes = free_sectors * fs->ssize;
}
} |
Note that once you have a partition labeled, you can mount it with the arduino tools by providing that partition label to the begin call. |
Question 1 flashFile.write(DataBufWrite, 120); how to modify in this sample code from IDF ??? Question 2 flashFile.read(DataBufRead, 40500); how to modify in this sample code from IDF ??? Question 3 how to delete the file ??? |
why i , Serial.println(DataBufRead[100]); below is code. #include "esp_flash.h" #define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */ static const char *TAG = "example"; // Handle of the wear levelling library instance // Mount path for the partition static esp_flash_t* example_init_ext_flash(void); uint8_t* DataBufWrite; void setup(){ DataBufWrite = (uint8_t*)ps_calloc(1000000, sizeof(uint8_t)); //6 * 27000 * 3 = 486000 esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); my_app_main(); Serial.print("bootCount = "); xTaskCreatePinnedToCore(taskTwo, "TaskTwo", 30000, NULL, 2, NULL, 1); void taskTwo( void * parameter ) {
} void loop() { void LoopFlash(void)
} void my_app_main(void)
} static esp_flash_t* example_init_ext_flash(void)
} static const esp_partition_t* example_add_partition(esp_flash_t* ext_flash, const char* partition_label) static void example_list_data_partitions(void)
} static bool example_mount_fatfs(const char* partition_label) static void example_get_fatfs_usage(size_t* out_total_bytes, size_t* out_free_bytes)
} |
@savagerex -
The same issue when writing with |
OK, Thanks |
i use ESP32 WROVER, but my flash is connect HSPI. there is the debug message. E (593) memspi: no response bootCount = 2 bootCount = 3 bootCount = 4 #include "esp_flash.h" #define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */ static const char *TAG = "example"; // Handle of the wear levelling library instance // Mount path for the partition static esp_flash_t* example_init_ext_flash(void); uint8_t* DataBufWrite; void setup() { DataBufWrite = (uint8_t*)ps_calloc(1000000, sizeof(uint8_t)); //6 * 27000 * 3 = 486000 esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); my_app_main(); Serial.print("bootCount = "); xTaskCreatePinnedToCore(taskTwo, "TaskTwo", 30000, NULL, 2, NULL, 1); void taskTwo( void * parameter ) { for (;;) { void loop() { void LoopFlash(void) for (int i = 0; i < 1000000; i++) { //fprintf(f, "Written using ESP-IDF %s\n", esp_get_idf_version()); // Open file for reading void my_app_main(void) // Add the entire external flash chip as a partition // List the available partitions // Initialize FAT FS in the partition // Print FAT FS size information // Create a file in FAT FS // Open file for reading static esp_flash_t* example_init_ext_flash(void) const esp_flash_spi_device_config_t device_config = { ESP_LOGI(TAG, "Initializing external SPI Flash"); // Initialize the SPI bus // Add device to the SPI bus // Probe the Flash chip and initialize it // Print out the ID and size return ext_flash; static const esp_partition_t* example_add_partition(esp_flash_t* ext_flash, const char* partition_label) static void example_list_data_partitions(void) for (; it != NULL; it = esp_partition_next(it)) { esp_partition_iterator_release(it); static bool example_mount_fatfs(const char* partition_label) static void example_get_fatfs_usage(size_t* out_total_bytes, size_t* out_free_bytes) // assuming the total size is < 4GiB, should be true for SPI Flash |
@savagerex - Please check the pins and connections to make sure that it is correct.
|
OK!! Thanks |
Can we consider this as solved and close this ticket? |
I tried this example successfully. I want to use the functions in the Ffat.h library when writing my own functions related to filing. However, I'm a little confused. In the example you gave, we had already installed the Fat system. Is it OK to add it back to the Ffat.h library? Or will Ffat.h only be effective on internal flash? For example, I couldn't find a way to run the listdir() function. |
Please don't hijack threads. |
Sorry for the confusion. The example works just fine. I have no problem with this. I want to ask something else. When I do not connect the Wp and Hold pins, the flash works without any problems. I want to use the io connections defined on these pins for another purpose. How can I make the code release these pins? GPIO22WP |
Hello, closing this ticket as it seems original questions have been answered. @Endorfin35 if you found some issue in the code, please open another issue or if you have just question, please refer to Gitter channel. Thanks |
Board
ESP32 S3
Device Description
External Flash - W25Q256JV
Hardware Configuration
NONE
Version
v2.0.9
IDE Name
Arduino
Operating System
Windows 11
Flash frequency
80M
PSRAM enabled
no
Upload speed
921600
Description
i use these lib, but these lib have problem.
these lib as below.
https://github.com/PaulStoffregen/SerialFlash
https://github.com/adafruit/Adafruit_SPIFlash/tree/master
Can ESP team do lib for external flash(W25Q256JV)???
Sketch
Debug Message
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
The text was updated successfully, but these errors were encountered: