Improvements in EspClass (#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.
This commit is contained in:
Martin Sloup 2017-02-23 01:23:27 +01:00 committed by Me No Dev
parent 1d759380a6
commit 00c1a65612
2 changed files with 41 additions and 32 deletions

View File

@ -23,9 +23,22 @@
#include "esp_deep_sleep.h" #include "esp_deep_sleep.h"
#include "esp_spi_flash.h" #include "esp_spi_flash.h"
#include <memory> #include <memory>
#include <soc/soc.h>
#include <soc/efuse_reg.h>
//#define DEBUG_SERIAL Serial /* Main header of binary image */
typedef struct {
uint8_t magic;
uint8_t segment_count;
uint8_t spi_mode; /* flash read mode (esp_image_spi_mode_t as uint8_t) */
uint8_t spi_speed: 4; /* flash frequency (esp_image_spi_freq_t as uint8_t) */
uint8_t spi_size: 4; /* flash chip size (esp_image_flash_size_t as uint8_t) */
uint32_t entry_addr;
uint8_t encrypt_flag; /* encrypt flag */
uint8_t extra_header[15]; /* ESP32 additional header, unused by second bootloader */
} esp_image_header_t;
#define ESP_IMAGE_HEADER_MAGIC 0xE9
/** /**
* User-defined Literals * User-defined Literals
@ -104,6 +117,11 @@ uint32_t EspClass::getFreeHeap(void)
return esp_get_free_heap_size(); return esp_get_free_heap_size();
} }
uint8_t EspClass::getChipRevision(void)
{
return (REG_READ(EFUSE_BLK0_RDATA3_REG) >> EFUSE_RD_CHIP_VER_RESERVE_S) && EFUSE_RD_CHIP_VER_RESERVE_V;
}
const char * EspClass::getSdkVersion(void) const char * EspClass::getSdkVersion(void)
{ {
return esp_get_idf_version(); return esp_get_idf_version();
@ -111,57 +129,44 @@ const char * EspClass::getSdkVersion(void)
uint32_t EspClass::getFlashChipSize(void) uint32_t EspClass::getFlashChipSize(void)
{ {
uint32_t data; esp_image_header_t fhdr;
uint8_t * bytes = (uint8_t *) &data; if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
// read first 4 byte (magic byte + flash config) return 0;
if(flashRead(0x0000, &data, 4) == ESP_OK) {
return magicFlashChipSize((bytes[3] & 0xf0) >> 4);
} }
return 0; return magicFlashChipSize(fhdr.spi_size);
} }
uint32_t EspClass::getFlashChipSpeed(void) uint32_t EspClass::getFlashChipSpeed(void)
{ {
uint32_t data; esp_image_header_t fhdr;
uint8_t * bytes = (uint8_t *) &data; if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
// read first 4 byte (magic byte + flash config) return 0;
if(flashRead(0x0000, &data, 4) == ESP_OK) {
return magicFlashChipSpeed(bytes[3] & 0x0F);
} }
return 0; return magicFlashChipSpeed(fhdr.spi_speed);
} }
FlashMode_t EspClass::getFlashChipMode(void) FlashMode_t EspClass::getFlashChipMode(void)
{ {
FlashMode_t mode = FM_UNKNOWN; esp_image_header_t fhdr;
uint32_t data; if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
uint8_t * bytes = (uint8_t *) &data; return FM_UNKNOWN;
// read first 4 byte (magic byte + flash config)
if(flashRead(0x0000, &data, 4) == ESP_OK) {
mode = magicFlashChipMode(bytes[2]);
} }
return mode; return magicFlashChipMode(fhdr.spi_mode);
} }
uint32_t EspClass::magicFlashChipSize(uint8_t byte) uint32_t EspClass::magicFlashChipSize(uint8_t byte)
{ {
switch(byte & 0x0F) { switch(byte & 0x0F) {
case 0x0: // 4 Mbit (512KB) case 0x0: // 8 MBit (1MB)
return (512_kB);
case 0x1: // 2 MBit (256KB)
return (256_kB);
case 0x2: // 8 MBit (1MB)
return (1_MB); return (1_MB);
case 0x3: // 16 MBit (2MB) case 0x1: // 16 MBit (2MB)
return (2_MB); return (2_MB);
case 0x4: // 32 MBit (4MB) case 0x2: // 32 MBit (4MB)
return (4_MB); return (4_MB);
case 0x5: // 64 MBit (8MB) case 0x3: // 64 MBit (8MB)
return (8_MB); return (8_MB);
case 0x6: // 128 MBit (16MB) case 0x4: // 128 MBit (16MB)
return (16_MB); return (16_MB);
case 0x7: // 256 MBit (32MB)
return (32_MB);
default: // fail? default: // fail?
return 0; return 0;
} }
@ -186,7 +191,7 @@ uint32_t EspClass::magicFlashChipSpeed(uint8_t byte)
FlashMode_t EspClass::magicFlashChipMode(uint8_t byte) FlashMode_t EspClass::magicFlashChipMode(uint8_t byte)
{ {
FlashMode_t mode = (FlashMode_t) byte; FlashMode_t mode = (FlashMode_t) byte;
if(mode > FM_DOUT) { if(mode > FM_SLOW_READ) {
mode = FM_UNKNOWN; mode = FM_UNKNOWN;
} }
return mode; return mode;
@ -197,6 +202,7 @@ bool EspClass::flashEraseSector(uint32_t sector)
return spi_flash_erase_sector(sector) == ESP_OK; return spi_flash_erase_sector(sector) == ESP_OK;
} }
// Warning: These functions do not work with encrypted flash
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size)
{ {
return spi_flash_write(offset, (uint32_t*) data, size) == ESP_OK; return spi_flash_write(offset, (uint32_t*) data, size) == ESP_OK;

View File

@ -45,6 +45,8 @@ typedef enum {
FM_QOUT = 0x01, FM_QOUT = 0x01,
FM_DIO = 0x02, FM_DIO = 0x02,
FM_DOUT = 0x03, FM_DOUT = 0x03,
FM_FAST_READ = 0x04,
FM_SLOW_READ = 0x05,
FM_UNKNOWN = 0xff FM_UNKNOWN = 0xff
} FlashMode_t; } FlashMode_t;
@ -55,6 +57,7 @@ public:
~EspClass() {} ~EspClass() {}
void restart(); void restart();
uint32_t getFreeHeap(); uint32_t getFreeHeap();
uint8_t getChipRevision();
uint8_t getCpuFreqMHz(){ return CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; } uint8_t getCpuFreqMHz(){ return CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; }
uint32_t getCycleCount(); uint32_t getCycleCount();
const char * getSdkVersion(); const char * getSdkVersion();