Skip to content

Commit 00c1a65

Browse files
arcaome-no-dev
authored andcommitted
Improvements in EspClass (espressif#222)
* Improvements in EspClass - fixed not working functions for flash chip size, speed and mode - added function to retrieve chip revision from eFuse - flashRead / flashWrite supports encrypted flash * Rename getCpuRevision function to getChipRevision * Revert: flashRead / flashWrite supports encrypted flash Reading and writing to encrypted flash has to be aligned to 16-bytes. Also NAND way of writing (i.e. flipping 1s to 0s) will not work with spi_flash_write_encrypted. Note: spi_flash_read_encrypted will always try to decrypt data, even if it wasn't encrypted in the first place.
1 parent 1d75938 commit 00c1a65

File tree

2 files changed

+43
-34
lines changed

2 files changed

+43
-34
lines changed

cores/esp32/Esp.cpp

+40-34
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,22 @@
2323
#include "esp_deep_sleep.h"
2424
#include "esp_spi_flash.h"
2525
#include <memory>
26-
27-
//#define DEBUG_SERIAL Serial
28-
26+
#include <soc/soc.h>
27+
#include <soc/efuse_reg.h>
28+
29+
/* Main header of binary image */
30+
typedef struct {
31+
uint8_t magic;
32+
uint8_t segment_count;
33+
uint8_t spi_mode; /* flash read mode (esp_image_spi_mode_t as uint8_t) */
34+
uint8_t spi_speed: 4; /* flash frequency (esp_image_spi_freq_t as uint8_t) */
35+
uint8_t spi_size: 4; /* flash chip size (esp_image_flash_size_t as uint8_t) */
36+
uint32_t entry_addr;
37+
uint8_t encrypt_flag; /* encrypt flag */
38+
uint8_t extra_header[15]; /* ESP32 additional header, unused by second bootloader */
39+
} esp_image_header_t;
40+
41+
#define ESP_IMAGE_HEADER_MAGIC 0xE9
2942

3043
/**
3144
* User-defined Literals
@@ -104,64 +117,56 @@ uint32_t EspClass::getFreeHeap(void)
104117
return esp_get_free_heap_size();
105118
}
106119

120+
uint8_t EspClass::getChipRevision(void)
121+
{
122+
return (REG_READ(EFUSE_BLK0_RDATA3_REG) >> EFUSE_RD_CHIP_VER_RESERVE_S) && EFUSE_RD_CHIP_VER_RESERVE_V;
123+
}
124+
107125
const char * EspClass::getSdkVersion(void)
108126
{
109127
return esp_get_idf_version();
110128
}
111129

112130
uint32_t EspClass::getFlashChipSize(void)
113131
{
114-
uint32_t data;
115-
uint8_t * bytes = (uint8_t *) &data;
116-
// read first 4 byte (magic byte + flash config)
117-
if(flashRead(0x0000, &data, 4) == ESP_OK) {
118-
return magicFlashChipSize((bytes[3] & 0xf0) >> 4);
132+
esp_image_header_t fhdr;
133+
if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
134+
return 0;
119135
}
120-
return 0;
136+
return magicFlashChipSize(fhdr.spi_size);
121137
}
122138

123139
uint32_t EspClass::getFlashChipSpeed(void)
124140
{
125-
uint32_t data;
126-
uint8_t * bytes = (uint8_t *) &data;
127-
// read first 4 byte (magic byte + flash config)
128-
if(flashRead(0x0000, &data, 4) == ESP_OK) {
129-
return magicFlashChipSpeed(bytes[3] & 0x0F);
141+
esp_image_header_t fhdr;
142+
if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
143+
return 0;
130144
}
131-
return 0;
145+
return magicFlashChipSpeed(fhdr.spi_speed);
132146
}
133147

134148
FlashMode_t EspClass::getFlashChipMode(void)
135149
{
136-
FlashMode_t mode = FM_UNKNOWN;
137-
uint32_t data;
138-
uint8_t * bytes = (uint8_t *) &data;
139-
// read first 4 byte (magic byte + flash config)
140-
if(flashRead(0x0000, &data, 4) == ESP_OK) {
141-
mode = magicFlashChipMode(bytes[2]);
150+
esp_image_header_t fhdr;
151+
if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
152+
return FM_UNKNOWN;
142153
}
143-
return mode;
154+
return magicFlashChipMode(fhdr.spi_mode);
144155
}
145156

146157
uint32_t EspClass::magicFlashChipSize(uint8_t byte)
147158
{
148159
switch(byte & 0x0F) {
149-
case 0x0: // 4 Mbit (512KB)
150-
return (512_kB);
151-
case 0x1: // 2 MBit (256KB)
152-
return (256_kB);
153-
case 0x2: // 8 MBit (1MB)
160+
case 0x0: // 8 MBit (1MB)
154161
return (1_MB);
155-
case 0x3: // 16 MBit (2MB)
162+
case 0x1: // 16 MBit (2MB)
156163
return (2_MB);
157-
case 0x4: // 32 MBit (4MB)
164+
case 0x2: // 32 MBit (4MB)
158165
return (4_MB);
159-
case 0x5: // 64 MBit (8MB)
166+
case 0x3: // 64 MBit (8MB)
160167
return (8_MB);
161-
case 0x6: // 128 MBit (16MB)
168+
case 0x4: // 128 MBit (16MB)
162169
return (16_MB);
163-
case 0x7: // 256 MBit (32MB)
164-
return (32_MB);
165170
default: // fail?
166171
return 0;
167172
}
@@ -186,7 +191,7 @@ uint32_t EspClass::magicFlashChipSpeed(uint8_t byte)
186191
FlashMode_t EspClass::magicFlashChipMode(uint8_t byte)
187192
{
188193
FlashMode_t mode = (FlashMode_t) byte;
189-
if(mode > FM_DOUT) {
194+
if(mode > FM_SLOW_READ) {
190195
mode = FM_UNKNOWN;
191196
}
192197
return mode;
@@ -197,6 +202,7 @@ bool EspClass::flashEraseSector(uint32_t sector)
197202
return spi_flash_erase_sector(sector) == ESP_OK;
198203
}
199204

205+
// Warning: These functions do not work with encrypted flash
200206
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size)
201207
{
202208
return spi_flash_write(offset, (uint32_t*) data, size) == ESP_OK;

cores/esp32/Esp.h

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ typedef enum {
4545
FM_QOUT = 0x01,
4646
FM_DIO = 0x02,
4747
FM_DOUT = 0x03,
48+
FM_FAST_READ = 0x04,
49+
FM_SLOW_READ = 0x05,
4850
FM_UNKNOWN = 0xff
4951
} FlashMode_t;
5052

@@ -55,6 +57,7 @@ class EspClass
5557
~EspClass() {}
5658
void restart();
5759
uint32_t getFreeHeap();
60+
uint8_t getChipRevision();
5861
uint8_t getCpuFreqMHz(){ return CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; }
5962
uint32_t getCycleCount();
6063
const char * getSdkVersion();

0 commit comments

Comments
 (0)