2022-02-21 16:09:24 -05:00
/*
2023-07-17 05:59:28 -04:00
* SPDX - FileCopyrightText : 2015 - 2023 Espressif Systems ( Shanghai ) CO LTD
2022-02-21 16:09:24 -05:00
*
* SPDX - License - Identifier : Apache - 2.0
*/
2018-07-04 19:01:03 -04:00
# include <stdio.h>
2022-01-12 01:53:47 -05:00
# include "esp_random.h"
2018-07-04 19:01:03 -04:00
# include "esp_log.h"
2023-09-07 09:59:47 -04:00
# include "Partition.h"
2018-07-04 19:01:03 -04:00
# include "WL_Flash.h"
# include <stdlib.h>
# include "crc32.h"
# include <string.h>
2018-06-07 06:32:37 -04:00
# include <stddef.h>
2023-10-17 10:13:32 -04:00
# include <inttypes.h>
2018-07-04 19:01:03 -04:00
static const char * TAG = " wl_flash " ;
# ifndef WL_CFG_CRC_CONST
# define WL_CFG_CRC_CONST UINT32_MAX
2020-11-10 02:40:01 -05:00
# endif // WL_CFG_CRC_CONST
2018-07-04 19:01:03 -04:00
# define WL_RESULT_CHECK(result) \
if ( result ! = ESP_OK ) { \
2023-10-17 10:13:32 -04:00
ESP_LOGE ( TAG , " %s(%d): result = 0x%08 " PRIx32 , __FUNCTION__ , __LINE__ , ( uint32_t ) result ) ; \
2018-07-04 19:01:03 -04:00
return ( result ) ; \
}
# ifndef _MSC_VER // MSVS has different format for this define
static_assert ( sizeof ( wl_state_t ) % 32 = = 0 , " wl_state_t structure size must be multiple of flash encryption unit size " ) ;
# endif // _MSC_VER
WL_Flash : : WL_Flash ( )
{
}
WL_Flash : : ~ WL_Flash ( )
{
free ( this - > temp_buff ) ;
}
2023-09-07 09:59:47 -04:00
esp_err_t WL_Flash : : config ( wl_config_t * cfg , Partition * partition )
2018-07-04 19:01:03 -04:00
{
2023-10-17 10:13:32 -04:00
ESP_LOGV ( TAG , " %s partition_start_addr=0x%08 " PRIx32 " , wl_partition_size=0x%08 " PRIx32 " , wl_page_size=0x%08 " PRIx32 " , flash_sector_size=0x%08 " PRIx32 " , wl_update_rate=0x%08 " PRIx32 " , wl_pos_update_record_size=0x%08 " PRIx32 " , version=0x%08 " PRIx32 " , wl_temp_buff_size=0x%08 " PRIx32 , __func__ ,
2023-03-30 10:15:43 -04:00
( uint32_t ) cfg - > wl_partition_start_addr ,
cfg - > wl_partition_size ,
cfg - > wl_page_size ,
cfg - > flash_sector_size ,
cfg - > wl_update_rate ,
cfg - > wl_pos_update_record_size ,
2018-07-04 19:01:03 -04:00
cfg - > version ,
2023-03-30 10:15:43 -04:00
( uint32_t ) cfg - > wl_temp_buff_size ) ;
2018-07-04 19:01:03 -04:00
2023-03-30 10:15:43 -04:00
cfg - > crc32 = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( const unsigned char * ) cfg , offsetof ( wl_config_t , crc32 ) ) ;
2018-07-04 19:01:03 -04:00
esp_err_t result = ESP_OK ;
memcpy ( & this - > cfg , cfg , sizeof ( wl_config_t ) ) ;
2023-03-30 10:15:43 -04:00
if ( this - > cfg . wl_temp_buff_size < this - > cfg . wl_pos_update_record_size ) {
this - > cfg . wl_temp_buff_size = this - > cfg . wl_pos_update_record_size ;
2018-06-12 04:06:13 -04:00
}
2018-07-04 19:01:03 -04:00
this - > configured = false ;
if ( cfg = = NULL ) {
result = ESP_ERR_INVALID_ARG ;
}
2023-09-07 09:59:47 -04:00
this - > partition = partition ;
if ( partition = = NULL ) {
2018-07-04 19:01:03 -04:00
result = ESP_ERR_INVALID_ARG ;
}
2023-03-30 10:15:43 -04:00
if ( ( this - > cfg . flash_sector_size % this - > cfg . wl_temp_buff_size ) ! = 0 ) {
2018-07-04 19:01:03 -04:00
result = ESP_ERR_INVALID_ARG ;
}
2023-03-30 10:15:43 -04:00
if ( this - > cfg . wl_page_size < this - > cfg . flash_sector_size ) {
2018-07-04 19:01:03 -04:00
result = ESP_ERR_INVALID_ARG ;
}
WL_RESULT_CHECK ( result ) ;
2023-03-30 10:15:43 -04:00
this - > state_size = this - > cfg . flash_sector_size ;
if ( this - > state_size < ( sizeof ( wl_state_t ) + ( this - > cfg . wl_partition_size / this - > cfg . flash_sector_size ) * this - > cfg . wl_pos_update_record_size ) ) {
this - > state_size = ( ( sizeof ( wl_state_t ) + ( this - > cfg . wl_partition_size / this - > cfg . flash_sector_size ) * this - > cfg . wl_pos_update_record_size ) + this - > cfg . flash_sector_size - 1 ) / this - > cfg . flash_sector_size ;
this - > state_size = this - > state_size * this - > cfg . flash_sector_size ;
2018-07-04 19:01:03 -04:00
}
2023-03-30 10:15:43 -04:00
this - > cfg_size = ( sizeof ( wl_config_t ) + this - > cfg . flash_sector_size - 1 ) / this - > cfg . flash_sector_size ;
this - > cfg_size = cfg_size * this - > cfg . flash_sector_size ;
2018-07-04 19:01:03 -04:00
2023-03-30 10:15:43 -04:00
this - > addr_cfg = this - > cfg . wl_partition_start_addr + this - > cfg . wl_partition_size - this - > cfg_size ;
this - > addr_state1 = this - > cfg . wl_partition_start_addr + this - > cfg . wl_partition_size - this - > state_size * 2 - this - > cfg_size ; // allocate data at the end of memory
this - > addr_state2 = this - > cfg . wl_partition_start_addr + this - > cfg . wl_partition_size - this - > state_size * 1 - this - > cfg_size ; // allocate data at the end of memory
2018-07-04 19:01:03 -04:00
2023-03-30 10:15:43 -04:00
ptrdiff_t flash_sz = ( ( this - > cfg . wl_partition_size - this - > state_size * 2 - this - > cfg_size ) / this - > cfg . wl_page_size - 1 ) * this - > cfg . wl_page_size ; // -1 remove dummy block
this - > flash_size = ( ( this - > cfg . wl_partition_size - this - > state_size * 2 - this - > cfg_size ) / this - > cfg . wl_page_size - 1 ) * this - > cfg . wl_page_size ; // -1 remove dummy block
2018-07-04 19:01:03 -04:00
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - config result: state_size=0x%08 " PRIx32 " , cfg_size=0x%08 " PRIx32 " , addr_cfg=0x%08 " PRIx32 " , addr_state1=0x%08 " PRIx32 " , addr_state2=0x%08 " PRIx32 " , flash_size=0x%08 " PRIx32 , __func__ ,
2018-07-27 02:54:23 -04:00
( uint32_t ) this - > state_size ,
( uint32_t ) this - > cfg_size ,
( uint32_t ) this - > addr_cfg ,
( uint32_t ) this - > addr_state1 ,
( uint32_t ) this - > addr_state2 ,
( uint32_t ) this - > flash_size
) ;
2018-06-07 02:58:06 -04:00
if ( flash_sz < = 0 ) {
2018-07-27 02:54:23 -04:00
result = ESP_ERR_INVALID_ARG ;
2018-06-07 02:58:06 -04:00
}
WL_RESULT_CHECK ( result ) ;
2018-07-04 19:01:03 -04:00
2023-03-30 10:15:43 -04:00
this - > temp_buff = ( uint8_t * ) malloc ( this - > cfg . wl_temp_buff_size ) ;
2018-06-07 02:58:06 -04:00
if ( this - > temp_buff = = NULL ) {
result = ESP_ERR_NO_MEM ;
}
WL_RESULT_CHECK ( result ) ;
2018-07-04 19:01:03 -04:00
this - > configured = true ;
return ESP_OK ;
}
esp_err_t WL_Flash : : init ( )
{
esp_err_t result = ESP_OK ;
if ( this - > configured = = false ) {
ESP_LOGW ( TAG , " WL_Flash: not configured, call config() first " ) ;
return ESP_ERR_INVALID_STATE ;
}
// If flow will be interrupted by error, then this flag will be false
this - > initialized = false ;
// Init states if it is first time...
2023-09-07 09:59:47 -04:00
this - > partition - > read ( this - > addr_state1 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
wl_state_t sa_copy ;
wl_state_t * state_copy = & sa_copy ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state2 , state_copy , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2018-10-25 08:31:28 -04:00
int check_size = WL_STATE_CRC_LEN_V2 ;
2018-07-04 19:01:03 -04:00
// Chech CRC and recover state
uint32_t crc1 = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) & this - > state , check_size ) ;
uint32_t crc2 = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) state_copy , check_size ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - config ID=% " PRIu32 " , stored ID=% " PRIu32 " , wl_sec_erase_cycle_count=% " PRIu32 " , wl_block_size=% " PRIu32 " , wl_max_sec_erase_cycle_count=% " PRIu32 " , wl_dummy_sec_pos=% " PRIu32 " , wl_dummy_sec_move_count=0x%8.8 " PRIX32 ,
2018-07-04 19:01:03 -04:00
__func__ ,
this - > cfg . version ,
this - > state . version ,
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count ,
this - > state . wl_block_size ,
this - > state . wl_max_sec_erase_cycle_count ,
this - > state . wl_dummy_sec_pos ,
this - > state . wl_dummy_sec_move_count ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s starts: crc1= 0x%08 " PRIx32 " , crc2 = 0x%08 " PRIx32 " , this->state.crc= 0x%08 " PRIx32 " , state_copy->crc= 0x%08 " PRIx32 " , version=% " PRIu32 " , read_version=% " PRIu32 , __func__ , crc1 , crc2 , this - > state . crc32 , state_copy - > crc32 , this - > cfg . version , this - > state . version ) ;
2023-03-30 10:15:43 -04:00
if ( ( crc1 = = this - > state . crc32 ) & & ( crc2 = = state_copy - > crc32 ) ) {
2018-07-04 19:01:03 -04:00
// The state is OK. Check the ID
if ( this - > state . version ! = this - > cfg . version ) {
result = this - > initSections ( ) ;
WL_RESULT_CHECK ( result ) ;
result = this - > recoverPos ( ) ;
WL_RESULT_CHECK ( result ) ;
} else {
if ( crc1 ! = crc2 ) { // we did not update second structure.
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state2 , this - > state_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state2 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-03-30 10:15:43 -04:00
for ( size_t i = 0 ; i < ( ( this - > cfg . wl_partition_size / this - > cfg . flash_sector_size ) ) ; i + + ) {
2018-06-07 06:32:37 -04:00
bool pos_bits ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state1 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2018-06-07 02:58:06 -04:00
pos_bits = this - > OkBuffSet ( i ) ;
if ( pos_bits = = true ) {
//this->fillOkBuff(i);
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state2 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
}
}
}
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s: crc1=0x%08 " PRIx32 " , crc2 = 0x%08 " PRIx32 " , result= 0x%08 " PRIx32 , __func__ , crc1 , crc2 , ( uint32_t ) result ) ;
2018-07-04 19:01:03 -04:00
result = this - > recoverPos ( ) ;
WL_RESULT_CHECK ( result ) ;
}
2023-03-30 10:15:43 -04:00
} else if ( ( crc1 ! = this - > state . crc32 ) & & ( crc2 ! = state_copy - > crc32 ) ) { // This is just new flash or new version
2018-06-07 02:58:06 -04:00
// Check if this is new version or just new instance of WL
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s: try to update version - crc1= 0x%08 " PRIx32 " , crc2 = 0x%08 " PRIx32 " , result= 0x%08 " PRIx32 , __func__ , ( uint32_t ) crc1 , ( uint32_t ) crc2 , ( uint32_t ) result ) ;
2018-06-07 02:58:06 -04:00
result = this - > updateVersion ( ) ;
if ( result = = ESP_FAIL ) {
2018-06-07 06:32:37 -04:00
ESP_LOGD ( TAG , " %s: init flash sections " , __func__ ) ;
2018-06-07 02:58:06 -04:00
result = this - > initSections ( ) ;
WL_RESULT_CHECK ( result ) ;
}
2018-07-04 19:01:03 -04:00
result = this - > recoverPos ( ) ;
WL_RESULT_CHECK ( result ) ;
} else {
// recover broken state
2023-03-30 10:15:43 -04:00
if ( crc1 = = this - > state . crc32 ) { // we have to recover state 2
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state2 , this - > state_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state2 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-03-30 10:15:43 -04:00
for ( size_t i = 0 ; i < ( ( this - > cfg . wl_partition_size / this - > cfg . flash_sector_size ) ) ; i + + ) {
2018-06-07 06:32:37 -04:00
bool pos_bits ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state1 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2018-06-07 02:58:06 -04:00
pos_bits = this - > OkBuffSet ( i ) ;
if ( pos_bits = = true ) {
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state2 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
}
}
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state2 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
} else { // we have to recover state 1
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state1 , this - > state_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state1 , state_copy , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-03-30 10:15:43 -04:00
for ( size_t i = 0 ; i < ( ( this - > cfg . wl_partition_size / this - > cfg . flash_sector_size ) ) ; i + + ) {
2018-06-07 06:32:37 -04:00
bool pos_bits ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state2 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-06-07 02:58:06 -04:00
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2018-06-07 02:58:06 -04:00
pos_bits = this - > OkBuffSet ( i ) ;
if ( pos_bits = = true ) {
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state1 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
}
}
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state1 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-03-30 10:15:43 -04:00
this - > state . wl_dummy_sec_pos = this - > state . wl_part_max_sec_pos - 1 ;
2018-07-04 19:01:03 -04:00
}
// done. We have recovered the state
// If we have a new configuration, we will overwrite it
if ( this - > state . version ! = this - > cfg . version ) {
result = this - > initSections ( ) ;
WL_RESULT_CHECK ( result ) ;
}
}
if ( result ! = ESP_OK ) {
this - > initialized = false ;
2023-10-17 10:13:32 -04:00
ESP_LOGE ( TAG , " %s: returned 0x%08 " PRIx32 , __func__ , ( uint32_t ) result ) ;
2018-07-04 19:01:03 -04:00
return result ;
}
this - > initialized = true ;
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - wl_dummy_sec_move_count= 0x%08 " PRIx32 , __func__ , ( uint32_t ) this - > state . wl_dummy_sec_move_count ) ;
2018-07-04 19:01:03 -04:00
return ESP_OK ;
}
esp_err_t WL_Flash : : recoverPos ( )
{
esp_err_t result = ESP_OK ;
size_t position = 0 ;
2018-07-27 02:54:23 -04:00
ESP_LOGV ( TAG , " %s start " , __func__ ) ;
2023-03-30 10:15:43 -04:00
for ( size_t i = 0 ; i < this - > state . wl_part_max_sec_pos ; i + + ) {
2018-06-07 06:32:37 -04:00
bool pos_bits ;
2018-07-04 19:01:03 -04:00
position = i ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state1 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-06-07 02:58:06 -04:00
pos_bits = this - > OkBuffSet ( i ) ;
WL_RESULT_CHECK ( result ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGV ( TAG , " %s - check pos: result=0x%08 " PRIx32 " , position= % " PRIu32 " , pos_bits= 0x%08 " PRIx32 , __func__ , ( uint32_t ) result , ( uint32_t ) position , ( uint32_t ) pos_bits ) ;
2018-06-07 02:58:06 -04:00
if ( pos_bits = = false ) {
2018-07-04 19:01:03 -04:00
break ; // we have found position
}
}
2018-06-07 02:58:06 -04:00
2023-03-30 10:15:43 -04:00
this - > state . wl_dummy_sec_pos = position ;
if ( this - > state . wl_dummy_sec_pos = = this - > state . wl_part_max_sec_pos ) {
this - > state . wl_dummy_sec_pos - - ;
2018-07-04 19:01:03 -04:00
}
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - this->state.wl_dummy_sec_pos= 0x%08 " PRIx32 " , position= 0x%08 " PRIx32 " , result= 0x%08 " PRIx32 " , wl_part_max_sec_pos= 0x%08 " PRIx32 , __func__ , ( uint32_t ) this - > state . wl_dummy_sec_pos , ( uint32_t ) position , ( uint32_t ) result , ( uint32_t ) this - > state . wl_part_max_sec_pos ) ;
2018-06-07 06:32:37 -04:00
ESP_LOGV ( TAG , " %s done " , __func__ ) ;
2018-07-04 19:01:03 -04:00
return result ;
}
esp_err_t WL_Flash : : initSections ( )
{
esp_err_t result = ESP_OK ;
2023-03-30 10:15:43 -04:00
this - > state . wl_dummy_sec_pos = 0 ;
this - > state . wl_sec_erase_cycle_count = 0 ;
this - > state . wl_dummy_sec_move_count = 0 ;
2018-07-04 19:01:03 -04:00
// max count
2023-03-30 10:15:43 -04:00
this - > state . wl_max_sec_erase_cycle_count = this - > flash_size / this - > state_size * this - > cfg . wl_update_rate ;
if ( this - > cfg . wl_update_rate ! = 0 ) {
this - > state . wl_max_sec_erase_cycle_count = this - > cfg . wl_update_rate ;
2018-07-04 19:01:03 -04:00
}
this - > state . version = this - > cfg . version ;
2023-03-30 10:15:43 -04:00
this - > state . wl_block_size = this - > cfg . wl_page_size ;
this - > state . wl_device_id = esp_random ( ) ;
2018-06-07 06:32:37 -04:00
memset ( this - > state . reserved , 0 , sizeof ( this - > state . reserved ) ) ;
2018-07-04 19:01:03 -04:00
2023-03-30 10:15:43 -04:00
this - > state . wl_part_max_sec_pos = 1 + this - > flash_size / this - > cfg . wl_page_size ;
2018-07-04 19:01:03 -04:00
2023-03-30 10:15:43 -04:00
this - > state . crc32 = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) & this - > state , WL_STATE_CRC_LEN_V2 ) ;
2018-07-04 19:01:03 -04:00
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state1 , this - > state_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state1 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
// write state copy
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state2 , this - > state_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state2 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_cfg , this - > cfg_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_cfg , & this - > cfg , sizeof ( wl_config_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - this->state->wl_max_sec_erase_cycle_count= 0x%08 " PRIx32 " , this->state->wl_part_max_sec_pos= 0x%08 " PRIx32 , __func__ , this - > state . wl_max_sec_erase_cycle_count , this - > state . wl_part_max_sec_pos ) ;
ESP_LOGD ( TAG , " %s - result= 0x%08x " , __func__ , result ) ;
2018-07-04 19:01:03 -04:00
return result ;
}
2018-06-07 02:58:06 -04:00
esp_err_t WL_Flash : : updateVersion ( )
{
esp_err_t result = ESP_OK ;
result = this - > updateV1_V2 ( ) ;
2018-07-27 02:54:23 -04:00
if ( result = = ESP_OK ) {
return result ;
}
2018-06-07 02:58:06 -04:00
// check next version
2018-07-27 02:54:23 -04:00
return result ;
2018-06-07 02:58:06 -04:00
}
esp_err_t WL_Flash : : updateV1_V2 ( )
{
esp_err_t result = ESP_OK ;
// Check crc for old version and old version
ESP_LOGV ( TAG , " %s start " , __func__ ) ;
2018-10-25 08:31:28 -04:00
int check_size = WL_STATE_CRC_LEN_V1 ;
2018-06-07 02:58:06 -04:00
// Chech CRC and recover state
uint32_t crc1 = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) & this - > state , check_size ) ;
2018-07-09 01:59:50 -04:00
wl_state_t sa_copy ;
wl_state_t * state_copy = & sa_copy ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state2 , state_copy , sizeof ( wl_state_t ) ) ;
2018-07-09 01:59:50 -04:00
WL_RESULT_CHECK ( result ) ;
uint32_t crc2 = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) state_copy , check_size ) ;
2018-07-27 02:54:23 -04:00
2023-03-30 10:15:43 -04:00
// For V1 crc in place of wl_device_id and version
uint32_t v1_crc1 = this - > state . wl_device_id ;
uint32_t v1_crc2 = state_copy - > wl_device_id ;
2018-07-27 02:54:23 -04:00
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - process crc1=0x%08 " PRIx32 " , crc2=0x%08 " PRIx32 " , v1_crc1=0x%08 " PRIx32 " , v1_crc2=0x%08 " PRIx32 " , version=% " PRIu32 , __func__ , crc1 , crc2 , v1_crc1 , v1_crc2 , this - > state . version ) ;
2018-06-07 02:58:06 -04:00
2018-07-27 02:54:23 -04:00
if ( ( crc1 = = v1_crc1 ) & & ( crc2 = = v1_crc2 ) & & ( v1_crc1 = = v1_crc2 ) & & ( this - > state . version = = 1 ) & & ( state_copy - > version = = 1 ) ) {
2018-06-07 02:58:06 -04:00
// Here we have to update all internal structures
2023-10-17 10:13:32 -04:00
ESP_LOGI ( TAG , " %s Update from V1 to V2, crc=0x%08 " PRIx32 " , " , __func__ , crc1 ) ;
2018-06-07 02:58:06 -04:00
uint32_t pos = 0 ;
2023-03-30 10:15:43 -04:00
for ( size_t i = 0 ; i < this - > state . wl_part_max_sec_pos ; i + + ) {
2018-06-07 06:32:37 -04:00
uint8_t pos_bits ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > addr_state1 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , & pos_bits , 1 ) ;
2018-06-07 02:58:06 -04:00
WL_RESULT_CHECK ( result ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGV ( TAG , " %s- result= 0x%08 " PRIx32 " , pos= % " PRIu32 " , pos_bits= 0x%08 " PRIx32 , __func__ , ( uint32_t ) result , ( uint32_t ) pos , ( uint32_t ) pos_bits ) ;
2018-06-07 02:58:06 -04:00
pos = i ;
if ( pos_bits = = 0xff ) {
2018-07-27 02:54:23 -04:00
break ; // we have found position
2018-06-07 02:58:06 -04:00
}
}
2023-10-17 10:13:32 -04:00
ESP_LOGI ( TAG , " %s wl_part_max_sec_pos=% " PRIu32 " , pos=% " PRIu32 " , state.ver=% " PRIu32 " , state2.ver=% " PRIu32 , __func__ , ( uint32_t ) this - > state . wl_part_max_sec_pos , ( uint32_t ) pos , ( uint32_t ) this - > state . version , ( uint32_t ) state_copy - > version ) ;
2023-03-30 10:15:43 -04:00
if ( pos = = this - > state . wl_part_max_sec_pos ) {
2018-06-07 02:58:06 -04:00
pos - - ;
}
WL_RESULT_CHECK ( result ) ;
this - > state . version = 2 ;
2023-03-30 10:15:43 -04:00
this - > state . wl_dummy_sec_pos = 0 ;
this - > state . wl_device_id = esp_random ( ) ;
2018-06-12 04:06:13 -04:00
memset ( this - > state . reserved , 0 , sizeof ( this - > state . reserved ) ) ;
2023-03-30 10:15:43 -04:00
this - > state . crc32 = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) & this - > state , WL_STATE_CRC_LEN_V2 ) ;
2018-06-07 02:58:06 -04:00
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state1 , this - > state_size ) ;
2018-06-07 02:58:06 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state1 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-06-07 02:58:06 -04:00
WL_RESULT_CHECK ( result ) ;
2023-03-30 10:15:43 -04:00
memset ( this - > temp_buff , 0 , this - > cfg . wl_pos_update_record_size ) ;
2018-07-27 02:54:23 -04:00
for ( uint32_t i = 0 ; i < = pos ; i + + ) {
2018-06-07 02:58:06 -04:00
this - > fillOkBuff ( i ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state1 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-06-07 02:58:06 -04:00
WL_RESULT_CHECK ( result ) ;
}
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state2 , this - > state_size ) ;
2018-06-07 02:58:06 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state2 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-06-07 02:58:06 -04:00
WL_RESULT_CHECK ( result ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - wl_dummy_sec_move_count= 0x%08 " PRIx32 " , pos= 0x%08 " PRIx32 , __func__ , this - > state . wl_dummy_sec_move_count , this - > state . wl_dummy_sec_pos ) ;
2018-06-07 02:58:06 -04:00
2023-03-30 10:15:43 -04:00
memset ( this - > temp_buff , 0 , this - > cfg . wl_pos_update_record_size ) ;
2018-07-27 02:54:23 -04:00
for ( uint32_t i = 0 ; i < = pos ; i + + ) {
2018-06-07 02:58:06 -04:00
this - > fillOkBuff ( i ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state2 + sizeof ( wl_state_t ) + i * this - > cfg . wl_pos_update_record_size , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-06-07 02:58:06 -04:00
WL_RESULT_CHECK ( result ) ;
}
2023-03-30 10:15:43 -04:00
this - > state . wl_dummy_sec_pos = pos ;
2018-06-07 02:58:06 -04:00
return result ;
}
return ESP_FAIL ;
2018-07-27 02:54:23 -04:00
}
2018-06-07 02:58:06 -04:00
void WL_Flash : : fillOkBuff ( int n )
{
2018-07-27 02:54:23 -04:00
uint32_t * buff = ( uint32_t * ) this - > temp_buff ;
2018-06-07 02:58:06 -04:00
2018-07-27 02:54:23 -04:00
for ( int i = 0 ; i < 4 ; i + + ) {
2023-03-30 10:15:43 -04:00
buff [ i ] = this - > state . wl_device_id + n * 4 + i ;
2018-06-07 02:58:06 -04:00
buff [ i ] = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) & buff [ i ] , sizeof ( uint32_t ) ) ;
}
}
bool WL_Flash : : OkBuffSet ( int n )
{
bool result = true ;
2018-07-27 02:54:23 -04:00
uint32_t * data_buff = ( uint32_t * ) this - > temp_buff ;
for ( int i = 0 ; i < 4 ; i + + ) {
2023-03-30 10:15:43 -04:00
uint32_t data = this - > state . wl_device_id + n * 4 + i ;
2018-06-07 02:58:06 -04:00
uint32_t crc = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) & data , sizeof ( uint32_t ) ) ;
2018-07-27 02:54:23 -04:00
if ( crc ! = data_buff [ i ] ) {
result = false ;
}
2018-06-07 02:58:06 -04:00
}
return result ;
}
2018-07-04 19:01:03 -04:00
esp_err_t WL_Flash : : updateWL ( )
{
esp_err_t result = ESP_OK ;
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count + + ;
if ( this - > state . wl_sec_erase_cycle_count < this - > state . wl_max_sec_erase_cycle_count ) {
2018-07-04 19:01:03 -04:00
return result ;
}
// Here we have to move the block and increase the state
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count = 0 ;
2023-10-17 10:13:32 -04:00
ESP_LOGV ( TAG , " %s - wl_sec_erase_cycle_count= 0x%08 " PRIx32 " , pos= 0x%08 " PRIx32 , __func__ , this - > state . wl_sec_erase_cycle_count , this - > state . wl_dummy_sec_pos ) ;
2018-07-04 19:01:03 -04:00
// copy data to dummy block
2023-03-30 10:15:43 -04:00
size_t data_addr = this - > state . wl_dummy_sec_pos + 1 ; // next block, [pos+1] copy to [pos]
if ( data_addr > = this - > state . wl_part_max_sec_pos ) {
2018-07-04 19:01:03 -04:00
data_addr = 0 ;
}
2023-03-30 10:15:43 -04:00
data_addr = this - > cfg . wl_partition_start_addr + data_addr * this - > cfg . wl_page_size ;
this - > dummy_addr = this - > cfg . wl_partition_start_addr + this - > state . wl_dummy_sec_pos * this - > cfg . wl_page_size ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > dummy_addr , this - > cfg . wl_page_size ) ;
2018-07-04 19:01:03 -04:00
if ( result ! = ESP_OK ) {
2023-10-17 10:13:32 -04:00
ESP_LOGE ( TAG , " %s - erase wl dummy sector result= 0x%08x " , __func__ , result ) ;
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count = this - > state . wl_max_sec_erase_cycle_count - 1 ; // we will update next time
2018-07-04 19:01:03 -04:00
return result ;
}
2023-03-30 10:15:43 -04:00
size_t copy_count = this - > cfg . wl_page_size / this - > cfg . wl_temp_buff_size ;
2018-07-04 19:01:03 -04:00
for ( size_t i = 0 ; i < copy_count ; i + + ) {
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( data_addr + i * this - > cfg . wl_temp_buff_size , this - > temp_buff , this - > cfg . wl_temp_buff_size ) ;
2018-07-04 19:01:03 -04:00
if ( result ! = ESP_OK ) {
2023-10-17 10:13:32 -04:00
ESP_LOGE ( TAG , " %s - not possible to read buffer, will try next time, result= 0x%08x " , __func__ , result ) ;
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count = this - > state . wl_max_sec_erase_cycle_count - 1 ; // we will update next time
2018-07-04 19:01:03 -04:00
return result ;
}
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > dummy_addr + i * this - > cfg . wl_temp_buff_size , this - > temp_buff , this - > cfg . wl_temp_buff_size ) ;
2018-07-04 19:01:03 -04:00
if ( result ! = ESP_OK ) {
2023-10-17 10:13:32 -04:00
ESP_LOGE ( TAG , " %s - not possible to write buffer, will try next time, result= 0x%08x " , __func__ , result ) ;
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count = this - > state . wl_max_sec_erase_cycle_count - 1 ; // we will update next time
2018-07-04 19:01:03 -04:00
return result ;
}
}
// done... block moved.
// Here we will update structures...
// Update bits and save to flash:
2023-03-30 10:15:43 -04:00
uint32_t byte_pos = this - > state . wl_dummy_sec_pos * this - > cfg . wl_pos_update_record_size ;
this - > fillOkBuff ( this - > state . wl_dummy_sec_pos ) ;
2018-07-04 19:01:03 -04:00
// write state to mem. We updating only affected bits
2023-09-07 09:59:47 -04:00
result | = this - > partition - > write ( this - > addr_state1 + sizeof ( wl_state_t ) + byte_pos , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-07-04 19:01:03 -04:00
if ( result ! = ESP_OK ) {
2023-10-17 10:13:32 -04:00
ESP_LOGE ( TAG , " %s - update position 1 result= 0x%08x " , __func__ , result ) ;
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count = this - > state . wl_max_sec_erase_cycle_count - 1 ; // we will update next time
2018-07-04 19:01:03 -04:00
return result ;
}
2023-03-30 10:15:43 -04:00
this - > fillOkBuff ( this - > state . wl_dummy_sec_pos ) ;
2023-09-07 09:59:47 -04:00
result | = this - > partition - > write ( this - > addr_state2 + sizeof ( wl_state_t ) + byte_pos , this - > temp_buff , this - > cfg . wl_pos_update_record_size ) ;
2018-07-04 19:01:03 -04:00
if ( result ! = ESP_OK ) {
2023-10-17 10:13:32 -04:00
ESP_LOGE ( TAG , " %s - update position 2 result= 0x%08x " , __func__ , result ) ;
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count = this - > state . wl_max_sec_erase_cycle_count - 1 ; // we will update next time
2018-07-04 19:01:03 -04:00
return result ;
}
2023-03-30 10:15:43 -04:00
this - > state . wl_dummy_sec_pos + + ;
if ( this - > state . wl_dummy_sec_pos > = this - > state . wl_part_max_sec_pos ) {
this - > state . wl_dummy_sec_pos = 0 ;
2018-07-04 19:01:03 -04:00
// one loop more
2023-03-30 10:15:43 -04:00
this - > state . wl_dummy_sec_move_count + + ;
if ( this - > state . wl_dummy_sec_move_count > = ( this - > state . wl_part_max_sec_pos - 1 ) ) {
this - > state . wl_dummy_sec_move_count = 0 ;
2018-07-04 19:01:03 -04:00
}
// write main state
2023-03-30 10:15:43 -04:00
this - > state . crc32 = crc32 : : crc32_le ( WL_CFG_CRC_CONST , ( uint8_t * ) & this - > state , WL_STATE_CRC_LEN_V2 ) ;
2018-07-04 19:01:03 -04:00
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state1 , this - > state_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state1 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_range ( this - > addr_state2 , this - > state_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > addr_state2 , & this - > state , sizeof ( wl_state_t ) ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - wl_dummy_sec_move_count= 0x%08 " PRIx32 " , wl_dummy_sec_pos= 0x%08 " PRIx32 " , " , __func__ , this - > state . wl_dummy_sec_move_count , this - > state . wl_dummy_sec_pos ) ;
2018-07-04 19:01:03 -04:00
}
// Save structures to the flash... and check result
if ( result = = ESP_OK ) {
2023-10-17 10:13:32 -04:00
ESP_LOGV ( TAG , " %s - result= 0x%08x " , __func__ , result ) ;
2018-07-04 19:01:03 -04:00
} else {
2023-10-17 10:13:32 -04:00
ESP_LOGE ( TAG , " %s - result= 0x%08x " , __func__ , result ) ;
2018-07-04 19:01:03 -04:00
}
return result ;
}
size_t WL_Flash : : calcAddr ( size_t addr )
{
2023-03-30 10:15:43 -04:00
size_t result = ( this - > flash_size - this - > state . wl_dummy_sec_move_count * this - > cfg . wl_page_size + addr ) % this - > flash_size ;
size_t dummy_addr = this - > state . wl_dummy_sec_pos * this - > cfg . wl_page_size ;
2018-07-04 19:01:03 -04:00
if ( result < dummy_addr ) {
} else {
2023-03-30 10:15:43 -04:00
result + = this - > cfg . wl_page_size ;
2018-07-04 19:01:03 -04:00
}
2023-10-17 10:13:32 -04:00
ESP_LOGV ( TAG , " %s - addr= 0x%08 " PRIx32 " -> result= 0x%08 " PRIx32 " , dummy_addr= 0x%08 " PRIx32 , __func__ , ( uint32_t ) addr , ( uint32_t ) result , ( uint32_t ) dummy_addr ) ;
2018-07-04 19:01:03 -04:00
return result ;
}
2023-03-30 10:15:43 -04:00
size_t WL_Flash : : get_flash_size ( )
2018-07-04 19:01:03 -04:00
{
if ( ! this - > configured ) {
return 0 ;
}
return this - > flash_size ;
}
2023-03-30 10:15:43 -04:00
size_t WL_Flash : : get_sector_size ( )
2018-07-04 19:01:03 -04:00
{
if ( ! this - > configured ) {
return 0 ;
}
2023-03-30 10:15:43 -04:00
return this - > cfg . flash_sector_size ;
2018-07-04 19:01:03 -04:00
}
esp_err_t WL_Flash : : erase_sector ( size_t sector )
{
esp_err_t result = ESP_OK ;
if ( ! this - > initialized ) {
return ESP_ERR_INVALID_STATE ;
}
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - sector= 0x%08 " PRIx32 , __func__ , ( uint32_t ) sector ) ;
2018-07-04 19:01:03 -04:00
result = this - > updateWL ( ) ;
WL_RESULT_CHECK ( result ) ;
2023-03-30 10:15:43 -04:00
size_t virt_addr = this - > calcAddr ( sector * this - > cfg . flash_sector_size ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > erase_sector ( ( this - > cfg . wl_partition_start_addr + virt_addr ) / this - > cfg . flash_sector_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
return result ;
}
2023-03-30 10:15:43 -04:00
2018-07-04 19:01:03 -04:00
esp_err_t WL_Flash : : erase_range ( size_t start_address , size_t size )
{
esp_err_t result = ESP_OK ;
if ( ! this - > initialized ) {
return ESP_ERR_INVALID_STATE ;
}
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - start_address= 0x%08 " PRIx32 " , size= 0x%08 " PRIx32 , __func__ , ( uint32_t ) start_address , ( uint32_t ) size ) ;
2023-03-30 10:15:43 -04:00
size_t erase_count = ( size + this - > cfg . flash_sector_size - 1 ) / this - > cfg . flash_sector_size ;
size_t start_sector = start_address / this - > cfg . flash_sector_size ;
2018-07-04 19:01:03 -04:00
for ( size_t i = 0 ; i < erase_count ; i + + ) {
result = this - > erase_sector ( start_sector + i ) ;
WL_RESULT_CHECK ( result ) ;
}
2023-10-17 10:13:32 -04:00
ESP_LOGV ( TAG , " %s - result= 0x%08x " , __func__ , result ) ;
2018-07-04 19:01:03 -04:00
return result ;
}
esp_err_t WL_Flash : : write ( size_t dest_addr , const void * src , size_t size )
{
esp_err_t result = ESP_OK ;
if ( ! this - > initialized ) {
return ESP_ERR_INVALID_STATE ;
}
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - dest_addr= 0x%08 " PRIx32 " , size= 0x%08 " PRIx32 , __func__ , ( uint32_t ) dest_addr , ( uint32_t ) size ) ;
2023-03-30 10:15:43 -04:00
uint32_t count = ( size - 1 ) / this - > cfg . wl_page_size ;
2018-07-04 19:01:03 -04:00
for ( size_t i = 0 ; i < count ; i + + ) {
2023-03-30 10:15:43 -04:00
size_t virt_addr = this - > calcAddr ( dest_addr + i * this - > cfg . wl_page_size ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > cfg . wl_partition_start_addr + virt_addr , & ( ( uint8_t * ) src ) [ i * this - > cfg . wl_page_size ] , this - > cfg . wl_page_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
}
2023-03-30 10:15:43 -04:00
size_t virt_addr_last = this - > calcAddr ( dest_addr + count * this - > cfg . wl_page_size ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > write ( this - > cfg . wl_partition_start_addr + virt_addr_last , & ( ( uint8_t * ) src ) [ count * this - > cfg . wl_page_size ] , size - count * this - > cfg . wl_page_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
return result ;
}
esp_err_t WL_Flash : : read ( size_t src_addr , void * dest , size_t size )
{
esp_err_t result = ESP_OK ;
if ( ! this - > initialized ) {
return ESP_ERR_INVALID_STATE ;
}
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - src_addr= 0x%08 " PRIx32 " , size= 0x%08 " PRIx32 , __func__ , ( uint32_t ) src_addr , ( uint32_t ) size ) ;
2023-03-30 10:15:43 -04:00
uint32_t count = ( size - 1 ) / this - > cfg . wl_page_size ;
2018-07-04 19:01:03 -04:00
for ( size_t i = 0 ; i < count ; i + + ) {
2023-03-30 10:15:43 -04:00
size_t virt_addr = this - > calcAddr ( src_addr + i * this - > cfg . wl_page_size ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGV ( TAG , " %s - real_addr= 0x%08 " PRIx32 " , size= 0x%08 " PRIx32 , __func__ , ( uint32_t ) ( this - > cfg . wl_partition_start_addr + virt_addr ) , ( uint32_t ) size ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > cfg . wl_partition_start_addr + virt_addr , & ( ( uint8_t * ) dest ) [ i * this - > cfg . wl_page_size ] , this - > cfg . wl_page_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
}
2023-03-30 10:15:43 -04:00
size_t virt_addr_last = this - > calcAddr ( src_addr + count * this - > cfg . wl_page_size ) ;
2023-09-07 09:59:47 -04:00
result = this - > partition - > read ( this - > cfg . wl_partition_start_addr + virt_addr_last , & ( ( uint8_t * ) dest ) [ count * this - > cfg . wl_page_size ] , size - count * this - > cfg . wl_page_size ) ;
2018-07-04 19:01:03 -04:00
WL_RESULT_CHECK ( result ) ;
return result ;
}
2023-09-07 09:59:47 -04:00
Partition * WL_Flash : : get_part ( )
2018-07-04 19:01:03 -04:00
{
2023-09-07 09:59:47 -04:00
return this - > partition ;
2018-07-04 19:01:03 -04:00
}
wl_config_t * WL_Flash : : get_cfg ( )
{
return & this - > cfg ;
}
esp_err_t WL_Flash : : flush ( )
{
esp_err_t result = ESP_OK ;
2023-03-30 10:15:43 -04:00
this - > state . wl_sec_erase_cycle_count = this - > state . wl_max_sec_erase_cycle_count - 1 ;
2018-07-04 19:01:03 -04:00
result = this - > updateWL ( ) ;
2023-10-17 10:13:32 -04:00
ESP_LOGD ( TAG , " %s - result= 0x%08x, wl_dummy_sec_move_count= 0x%08 " PRIx32 , __func__ , result , this - > state . wl_dummy_sec_move_count ) ;
2018-07-04 19:01:03 -04:00
return result ;
}