mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-12-15 01:48:20 +08:00
feat: Add fm25q16a patch
This commit is contained in:
@@ -94,6 +94,15 @@ SECTIONS
|
||||
_iram_end = ABSOLUTE(.);
|
||||
} > iram0_0_seg
|
||||
|
||||
.patch.text :
|
||||
{
|
||||
. = ALIGN (4);
|
||||
_iram_patch_text_start = ABSOLUTE(.);
|
||||
*(.flash.patch.literal .flash.patch.text)
|
||||
_iram_patch_text_end = ABSOLUTE(.);
|
||||
_iram_text_end = ABSOLUTE(.);
|
||||
} > iram0_0_seg
|
||||
|
||||
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
|
||||
"IRAM0 segment data does not fit.")
|
||||
|
||||
@@ -155,6 +164,15 @@ SECTIONS
|
||||
_bss_end = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
|
||||
.patch.bss :
|
||||
{
|
||||
. = ALIGN (4);
|
||||
_iram_patch_bss_start = ABSOLUTE(.);
|
||||
*(.flash.patch.bss)
|
||||
_iram_patch_bss_end = ABSOLUTE(.);
|
||||
*(.flash.patch.rodata)
|
||||
} > dram0_0_seg
|
||||
|
||||
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
|
||||
"DRAM segment data does not fit.")
|
||||
|
||||
|
||||
@@ -93,10 +93,6 @@ static void user_init_entry(void *param)
|
||||
esp_set_cpu_freq(ESP_CPU_FREQ_160M);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ENABLE_TH25Q16HB_PATCH_0
|
||||
assert(th25q16hb_apply_patch_0() == 0);
|
||||
#endif
|
||||
|
||||
app_main();
|
||||
|
||||
vTaskDelete(NULL);
|
||||
@@ -109,6 +105,7 @@ void call_start_cpu(size_t start_addr)
|
||||
|
||||
extern int _bss_start, _bss_end;
|
||||
extern int _iram_bss_start, _iram_bss_end;
|
||||
extern int _iram_patch_bss_start, _iram_patch_bss_end;
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_FAST_BOOT
|
||||
REG_SET_BIT(DPORT_CTL_REG, DPORT_CTL_DOUBLE_CLK);
|
||||
@@ -155,6 +152,18 @@ void call_start_cpu(size_t start_addr)
|
||||
for (p = &_iram_bss_start; p < &_iram_bss_end; p++)
|
||||
*p = 0;
|
||||
|
||||
|
||||
for (p = &_iram_patch_bss_start; p < &_iram_patch_bss_end; p++)
|
||||
*p = 0;
|
||||
|
||||
#ifdef CONFIG_ENABLE_TH25Q16HB_PATCH_0
|
||||
assert(th25q16hb_apply_patch_0() == 0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ENABLE_FM25Q16A_PATCH_0
|
||||
assert(fm25q16a_apply_patch_0() == 0);
|
||||
#endif
|
||||
|
||||
__asm__ __volatile__(
|
||||
"rsil a2, 2\n"
|
||||
"movi a1, _chip_interrupt_tmp\n"
|
||||
|
||||
@@ -5,8 +5,16 @@ if(BOOTLOADER_BUILD)
|
||||
set(srcs "${srcs}" "port/port.c")
|
||||
set(priv_requires "bootloader_support")
|
||||
else()
|
||||
if(CONFIG_ENABLE_TH25Q16HB_PATCH_0)
|
||||
list(APPEND srcs "src/patch/th25q16hb.c")
|
||||
|
||||
if (CONFIG_ENABLE_SPI_FLASH_PATCH)
|
||||
list(APPEND srcs "src/patch/common.c")
|
||||
if(CONFIG_ENABLE_TH25Q16HB_PATCH_0)
|
||||
list(APPEND srcs "src/patch/th25q16hb.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ENABLE_FM25Q16A_PATCH_0)
|
||||
list(APPEND srcs "src/patch/fm25q16a.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(priv_requires "esp8266" "freertos" "bootloader_support")
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
menu "SPI Flash"
|
||||
|
||||
menu "Patch"
|
||||
config ENABLE_SPI_FLASH_PATCH
|
||||
bool "Enable TH25Q16HB Patch 0"
|
||||
default n
|
||||
|
||||
config ENABLE_TH25Q16HB_PATCH_0
|
||||
bool "Enable TH25Q16HB Patch 0"
|
||||
depends on ENABLE_SPI_FLASH_PATCH
|
||||
default n
|
||||
help
|
||||
WARNING: If you don't use TH25Q16HB, you must not enable this option.
|
||||
Although you use TH25Q16HB, you should ask your flash manufacturer
|
||||
if your flash need use this patch.
|
||||
|
||||
config ENABLE_FM25Q16A_PATCH_0
|
||||
bool "Enable FM25Q16A Patch 0"
|
||||
depends on ENABLE_SPI_FLASH_PATCH
|
||||
default n
|
||||
help
|
||||
WARNING: If you don't use FM25Q16A, you must not enable this option.
|
||||
Although you use FM25Q16A, you should ask your flash manufacturer
|
||||
if your flash need use this patch.
|
||||
endmenu
|
||||
endmenu
|
||||
|
||||
@@ -16,7 +16,14 @@ ifdef IS_BOOTLOADER_BUILD
|
||||
COMPONENT_SRCDIRS += port
|
||||
COMPONENT_OBJS += port/port.o
|
||||
else
|
||||
ifdef CONFIG_ENABLE_TH25Q16HB_PATCH_0
|
||||
ifdef CONFIG_ENABLE_SPI_FLASH_PATCH
|
||||
COMPONENT_SRCDIRS += src/patch
|
||||
ifdef CONFIG_ENABLE_TH25Q16HB_PATCH_0
|
||||
COMPONENT_SRCDIRS += src/patch/th25q16hb.c
|
||||
endif
|
||||
|
||||
ifdef CONFIG_ENABLE_FM25Q16A_PATCH_0
|
||||
COMPONENT_SRCDIRS += src/patch/fm25q16a.c"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -213,6 +213,10 @@ int esp_patition_copy_ota1_to_ota0(const void *partition_info);
|
||||
int th25q16hb_apply_patch_0(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ENABLE_FM25Q16A_PATCH_0
|
||||
int fm25q16a_apply_patch_0();
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
218
components/spi_flash/src/patch/common.c
Normal file
218
components/spi_flash/src/patch/common.c
Normal file
@@ -0,0 +1,218 @@
|
||||
// Copyright 2023 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "spi_flash.h"
|
||||
#include "priv/esp_spi_flash_raw.h"
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#include "esp8266/eagle_soc.h"
|
||||
#include "esp8266/pin_mux_register.h"
|
||||
#include "esp8266/spi_register.h"
|
||||
#include "esp8266/spi_struct.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#include "spi_flash_patch.h"
|
||||
|
||||
#define SPI_FLASH SPI0
|
||||
#define SPI_BLOCK_SIZE 32
|
||||
#define ADDR_SHIFT_BITS 8
|
||||
|
||||
extern void Cache_Read_Disable_2(void);
|
||||
extern void Cache_Read_Enable_2();
|
||||
extern void vPortEnterCritical(void);
|
||||
extern void vPortExitCritical(void);
|
||||
|
||||
void FLASH_PATCH_TEXT_ATTR patch_delay(int ms)
|
||||
{
|
||||
for (volatile int i = 0; i < ms; i++) {
|
||||
for (volatile int j = 0; j < 7800; j++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FLASH_PATCH_TEXT_ATTR spi_enter(spi_state_t *state)
|
||||
{
|
||||
vPortEnterCritical();
|
||||
Cache_Read_Disable_2();
|
||||
|
||||
Wait_SPI_Idle(&g_rom_flashchip);
|
||||
|
||||
state->io_mux_reg = READ_PERI_REG(PERIPHS_IO_MUX_CONF_U);
|
||||
state->spi_clk_reg = SPI_FLASH.clock.val;
|
||||
state->spi_ctrl_reg = SPI_FLASH.ctrl.val;
|
||||
state->spi_user_reg = SPI_FLASH.user.val;
|
||||
|
||||
SPI_FLASH.user.usr_command = 1;
|
||||
SPI_FLASH.user.flash_mode = 0;
|
||||
SPI_FLASH.user.usr_miso_highpart = 0;
|
||||
|
||||
CLEAR_PERI_REG_MASK(PERIPHS_IO_MUX_CONF_U, SPI0_CLK_EQU_SYS_CLK);
|
||||
|
||||
SPI_FLASH.user.cs_setup = 1;
|
||||
SPI_FLASH.user.cs_hold = 1;
|
||||
SPI_FLASH.user.usr_mosi = 1;
|
||||
|
||||
SPI_FLASH.user.usr_command = 1;
|
||||
SPI_FLASH.user.flash_mode = 0;
|
||||
|
||||
SPI_FLASH.ctrl.fread_qio = 0;
|
||||
SPI_FLASH.ctrl.fread_dio = 0;
|
||||
SPI_FLASH.ctrl.fread_quad = 0;
|
||||
SPI_FLASH.ctrl.fread_dual = 0;
|
||||
|
||||
SPI_FLASH.clock.val = 0;
|
||||
SPI_FLASH.clock.clkcnt_l = 3;
|
||||
SPI_FLASH.clock.clkcnt_h = 1;
|
||||
SPI_FLASH.clock.clkcnt_n = 3;
|
||||
|
||||
SPI_FLASH.ctrl.fastrd_mode = 1;
|
||||
|
||||
while (SPI_FLASH.cmd.usr) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void FLASH_PATCH_TEXT_ATTR spi_exit(spi_state_t *state)
|
||||
{
|
||||
while (SPI_FLASH.cmd.usr) {
|
||||
;
|
||||
}
|
||||
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX_CONF_U, state->io_mux_reg);
|
||||
|
||||
SPI_FLASH.ctrl.val = state->spi_ctrl_reg;
|
||||
SPI_FLASH.clock.val = state->spi_clk_reg;
|
||||
SPI_FLASH.user.val = state->spi_user_reg;
|
||||
|
||||
Cache_Read_Enable_2();
|
||||
vPortExitCritical();
|
||||
}
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR spi_trans_block(bool write_mode,
|
||||
uint32_t cmd,
|
||||
uint32_t cmd_bits,
|
||||
uint32_t addr,
|
||||
uint32_t addr_bits,
|
||||
uint8_t *data,
|
||||
uint32_t data_bytes,
|
||||
uint32_t dummy_bits)
|
||||
{
|
||||
if ((uint32_t)data & 0x3) {
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: data=%p\n"), data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd_bits) {
|
||||
SPI_FLASH.user.usr_command = 1;
|
||||
SPI_FLASH.user2.usr_command_value = cmd;
|
||||
SPI_FLASH.user2.usr_command_bitlen = cmd_bits - 1;
|
||||
} else {
|
||||
SPI_FLASH.user.usr_command = 0;
|
||||
SPI_FLASH.user2.usr_command_bitlen = 0;
|
||||
}
|
||||
|
||||
if (addr_bits) {
|
||||
SPI_FLASH.user.usr_addr = 1;
|
||||
SPI_FLASH.addr = addr << ADDR_SHIFT_BITS;
|
||||
SPI_FLASH.user1.usr_addr_bitlen = addr_bits - 1;
|
||||
} else {
|
||||
SPI_FLASH.user.usr_addr = 0;
|
||||
SPI_FLASH.user1.usr_addr_bitlen = 0;
|
||||
}
|
||||
|
||||
if (dummy_bits) {
|
||||
SPI_FLASH.user.usr_dummy = 1;
|
||||
SPI_FLASH.user1.usr_dummy_cyclelen = dummy_bits - 1;
|
||||
} else {
|
||||
SPI_FLASH.user.usr_dummy = 0;
|
||||
SPI_FLASH.user1.usr_dummy_cyclelen = 0;
|
||||
}
|
||||
|
||||
if (data_bytes) {
|
||||
if (write_mode) {
|
||||
int words = (data_bytes + 3) / 4;
|
||||
uint32_t *p = (uint32_t *)data;
|
||||
|
||||
SPI_FLASH.user.usr_mosi = 1;
|
||||
SPI_FLASH.user.usr_miso = 0;
|
||||
SPI_FLASH.user1.usr_mosi_bitlen = data_bytes * 8 - 1;
|
||||
SPI_FLASH.user1.usr_miso_bitlen = 0;
|
||||
for (int i = 0; i < words; i++) {
|
||||
SPI_FLASH.data_buf[i] = p[i];
|
||||
}
|
||||
} else {
|
||||
int words = (data_bytes + 3) / 4;
|
||||
|
||||
SPI_FLASH.user.usr_mosi = 0;
|
||||
SPI_FLASH.user.usr_miso = 1;
|
||||
SPI_FLASH.user1.usr_miso_bitlen = data_bytes * 8 - 1;
|
||||
SPI_FLASH.user1.usr_mosi_bitlen = 0;
|
||||
|
||||
for (int i = 0; i < words; i++) {
|
||||
SPI_FLASH.data_buf[i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SPI_FLASH.user.usr_mosi = 0;
|
||||
SPI_FLASH.user1.usr_mosi_bitlen = 0;
|
||||
SPI_FLASH.user.usr_miso = 0;
|
||||
SPI_FLASH.user1.usr_miso_bitlen = 0;
|
||||
}
|
||||
|
||||
SPI_FLASH.cmd.usr = 1;
|
||||
while (SPI_FLASH.cmd.usr) {
|
||||
;
|
||||
}
|
||||
|
||||
if (!write_mode && data_bytes) {
|
||||
int words = (data_bytes + 3) / 4;
|
||||
uint32_t *p = (uint32_t *)data;
|
||||
|
||||
for (int i = 0; i < words; i++) {
|
||||
p[i] = SPI_FLASH.data_buf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FLASH_PATCH_TEXT_ATTR spi_trans(bool write_mode,
|
||||
uint32_t cmd,
|
||||
uint32_t cmd_bits,
|
||||
uint32_t addr,
|
||||
uint32_t addr_bits,
|
||||
uint8_t *data,
|
||||
uint32_t data_bytes,
|
||||
uint32_t dummy_bits)
|
||||
|
||||
{
|
||||
if (!data_bytes || data_bytes <= SPI_BLOCK_SIZE) {
|
||||
return spi_trans_block(write_mode, cmd, cmd_bits, addr,
|
||||
addr_bits, data, data_bytes, dummy_bits);
|
||||
}
|
||||
|
||||
for (int i = 0; i < data_bytes; i += SPI_BLOCK_SIZE) {
|
||||
uint32_t n = MIN(SPI_BLOCK_SIZE, data_bytes - i);
|
||||
|
||||
spi_trans_block(write_mode, cmd, cmd_bits, addr + i,
|
||||
addr_bits, data + i, n, dummy_bits);
|
||||
}
|
||||
}
|
||||
549
components/spi_flash/src/patch/fm25q16a.c
Normal file
549
components/spi_flash/src/patch/fm25q16a.c
Normal file
@@ -0,0 +1,549 @@
|
||||
// Copyright 2023 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "spi_flash.h"
|
||||
#include "priv/esp_spi_flash_raw.h"
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#include "esp8266/eagle_soc.h"
|
||||
#include "esp8266/pin_mux_register.h"
|
||||
#include "esp8266/spi_register.h"
|
||||
#include "esp8266/spi_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "spi_flash_patch.h"
|
||||
|
||||
#define DEBUG(fmt,...) fm_printf(fmt, ##__VA_ARGS__)
|
||||
#define INFO(fmt,...) fm_printf(fmt, ##__VA_ARGS__)
|
||||
#define ERROR(fmt,...) fm_printf(fmt, ##__VA_ARGS__)
|
||||
|
||||
#ifndef IRAM_FUNC_ATTR
|
||||
#define IRAM_FUNC_ATTR
|
||||
#endif
|
||||
|
||||
#define fm_printf ROM_PRINTF
|
||||
|
||||
extern bool IRAM_FUNC_ATTR spi_user_cmd(spi_cmd_dir_t mode, spi_cmd_t *p_cmd);
|
||||
extern uint32_t IRAM_FUNC_ATTR spi_flash_get_id(void);
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_send_spi_cmd(uint8_t cmd, uint8_t cmd_len, uint32_t addr, uint8_t addr_len, void* mosi_data, int mosi_len, void* miso_data, int miso_len, uint8_t dummy_bits)
|
||||
{
|
||||
bool write_mode = false;
|
||||
uint32_t data_bytes = 0;
|
||||
|
||||
if (mosi_len > 0) {
|
||||
write_mode = true;
|
||||
data_bytes = mosi_len / 8;
|
||||
} else if (miso_len > 0) {
|
||||
write_mode = false;
|
||||
data_bytes = miso_len / 8;
|
||||
}
|
||||
uint32_t data[(data_bytes+3)/4];
|
||||
if (write_mode && mosi_data) {
|
||||
memcpy(data, mosi_data, data_bytes);
|
||||
}
|
||||
|
||||
spi_trans(write_mode, cmd, cmd_len, addr, addr_len, (uint8_t *)data, data_bytes, dummy_bits);
|
||||
|
||||
if (!write_mode && miso_data) {
|
||||
memcpy(miso_data, data, data_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_cmd_start()
|
||||
{
|
||||
fm_send_spi_cmd(0x66, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
fm_send_spi_cmd(0x3C, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
fm_send_spi_cmd(0xC3, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_cmd_end()
|
||||
{
|
||||
fm_send_spi_cmd(0xff, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_pre_cmd_generic(uint8_t (*send_list)[5], int lines)
|
||||
{
|
||||
int i;
|
||||
fm_cam_cmd_start();
|
||||
for(i = 0; i < lines; i++) {
|
||||
fm_send_spi_cmd(0x0, 0, 0, 0, &send_list[i][0], 5*8, NULL, 0, 0);
|
||||
}
|
||||
|
||||
fm_cam_cmd_end();
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR read_after_erase_pre_send_list[7][5] = {
|
||||
{0x32,0x00,0x03,0xc0,0x88},
|
||||
{0x32,0x00,0x00,0x80,0x01},
|
||||
{0x32,0x00,0x00,0x84,0x47},
|
||||
{0x32,0x00,0x00,0x88,0x47},
|
||||
{0x32,0x00,0x00,0x8c,0x04},
|
||||
{0x32,0x00,0x00,0x90,0x19},
|
||||
{0x32,0x00,0x00,0x94,0x03},
|
||||
};
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_read_after_erase_pre(void)
|
||||
{
|
||||
// cmd NO.7 in the doc
|
||||
uint8_t send_list[7][5];
|
||||
|
||||
memcpy(send_list, read_after_erase_pre_send_list, 7 * 5);
|
||||
|
||||
fm_cam_pre_cmd_generic(send_list, sizeof(send_list) / sizeof(send_list[0]));
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR step_prog_pre_send_list[8][5] = {
|
||||
{0x32,0x00,0x03,0xc0,0x88},
|
||||
{0x32,0x00,0x00,0x64,0xb7},
|
||||
{0x32,0x00,0x00,0x80,0x13},
|
||||
{0x32,0x00,0x00,0x84,0x4f},
|
||||
{0x32,0x00,0x00,0x88,0x78},
|
||||
{0x32,0x00,0x00,0x8c,0x10},
|
||||
{0x32,0x00,0x00,0x90,0x40},
|
||||
{0x32,0x00,0x00,0x94,0xff},
|
||||
};
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_step_prog_pre(void)
|
||||
{
|
||||
// cmd NO.6 in the doc
|
||||
uint8_t send_list[8][5];
|
||||
|
||||
memcpy(send_list, step_prog_pre_send_list, 8 * 5);
|
||||
|
||||
fm_cam_pre_cmd_generic(send_list, sizeof(send_list) / sizeof(send_list[0]));
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR step_erase_pre_send_list[8][5] = {
|
||||
{0x32,0x00,0x00,0x64,0x77},
|
||||
{0x32,0x00,0x03,0xc0,0x88},
|
||||
{0x32,0x00,0x00,0x80,0x01},
|
||||
{0x32,0x00,0x00,0x84,0x46},
|
||||
{0x32,0x00,0x00,0x88,0x7e},
|
||||
{0x32,0x00,0x00,0x8c,0x06},
|
||||
{0x32,0x00,0x00,0x90,0x31},
|
||||
{0x32,0x00,0x00,0x94,0x01},
|
||||
};
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_step_erase_pre(void)
|
||||
{
|
||||
// cmd NO.5 in the doc
|
||||
uint8_t send_list[8][5];
|
||||
|
||||
memcpy(send_list, step_erase_pre_send_list, 8 * 5);
|
||||
|
||||
fm_cam_pre_cmd_generic(send_list, sizeof(send_list) / sizeof(send_list[0]));
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR preprog_pre_send_list[8][5] = {
|
||||
{0x32,0x00,0x03,0xc0,0x88},
|
||||
{0x32,0x00,0x00,0x64,0xf1},
|
||||
{0x32,0x00,0x00,0x80,0x53},
|
||||
{0x32,0x00,0x00,0x84,0x5c},
|
||||
{0x32,0x00,0x00,0x88,0x7c},
|
||||
{0x32,0x00,0x00,0x8c,0x04},
|
||||
{0x32,0x00,0x00,0x90,0x1f},
|
||||
{0x32,0x00,0x00,0x94,0xff},
|
||||
};
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_preprog_pre(void)
|
||||
{
|
||||
// cmd NO.4 in the doc
|
||||
uint8_t send_list[8][5];
|
||||
|
||||
memcpy(send_list, preprog_pre_send_list, 8 * 5);
|
||||
|
||||
fm_cam_pre_cmd_generic(send_list, sizeof(send_list) / sizeof(send_list[0]));
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR prog_pre_send_list[7][5] = {
|
||||
{0x32,0x00,0x03,0xc0,0x88},
|
||||
{0x32,0x00,0x00,0x80,0x53},
|
||||
{0x32,0x00,0x00,0x84,0x7c},
|
||||
{0x32,0x00,0x00,0x88,0x7f},
|
||||
{0x32,0x00,0x00,0x8c,0x10},
|
||||
{0x32,0x00,0x00,0x90,0xff},
|
||||
{0x32,0x00,0x00,0x94,0xff},
|
||||
};
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_prog_pre(void)
|
||||
{
|
||||
// cmd NO.3 in the doc
|
||||
uint8_t send_list[7][5];
|
||||
|
||||
memcpy(send_list, prog_pre_send_list, 7 * 5);
|
||||
|
||||
fm_cam_pre_cmd_generic(send_list, sizeof(send_list) / sizeof(send_list[0]));
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR uid_pre_send_list[7][5] = {
|
||||
{0x32,0x00,0x03,0xc0,0x48},
|
||||
{0x32,0x00,0x00,0x80,0x00},
|
||||
{0x32,0x00,0x00,0x84,0x47},
|
||||
{0x32,0x00,0x00,0x88,0x47},
|
||||
{0x32,0x00,0x00,0x8c,0x04},
|
||||
{0x32,0x00,0x00,0x90,0x19},
|
||||
{0x32,0x00,0x00,0x94,0x03},
|
||||
};
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_uid_pre(void)
|
||||
{
|
||||
// cmd NO.2 in the doc
|
||||
uint8_t send_list[7][5];
|
||||
|
||||
memcpy(send_list, uid_pre_send_list, 7 * 5);
|
||||
|
||||
fm_cam_pre_cmd_generic(send_list, sizeof(send_list) / sizeof(send_list[0]));
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR read_pre_send_list[7][5] = {
|
||||
{0x32,0x00,0x03,0xc0,0x88},
|
||||
{0x32,0x00,0x00,0x80,0x00},
|
||||
{0x32,0x00,0x00,0x84,0x47},
|
||||
{0x32,0x00,0x00,0x88,0x47},
|
||||
{0x32,0x00,0x00,0x8c,0x04},
|
||||
{0x32,0x00,0x00,0x90,0x19},
|
||||
{0x32,0x00,0x00,0x94,0x03},
|
||||
};
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_cam_read_pre(void)
|
||||
{
|
||||
// cmd NO.1 in the doc
|
||||
uint8_t send_list[7][5];
|
||||
|
||||
memcpy(send_list, read_pre_send_list, 7 * 5);
|
||||
|
||||
// fm_cam_pre_cmd_generic(send_list, sizeof(send_list) / sizeof(send_list[0]));
|
||||
fm_cam_pre_cmd_generic(send_list, 7);
|
||||
}
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_soft_reset()
|
||||
{
|
||||
fm_send_spi_cmd(0x66, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
// ets_delay_us(100);
|
||||
fm_send_spi_cmd(0x99, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR fm_flash_wait_idle()
|
||||
{
|
||||
uint8_t status = 0x1;
|
||||
while ((status&0x1) == 0x1) {
|
||||
fm_send_spi_cmd(0x05, 1*8, 0, 0, NULL, 0, &status, 1*8, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR fm_erase_sector(uint32_t addr)
|
||||
{
|
||||
// write en
|
||||
fm_send_spi_cmd(0x06, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
fm_send_spi_cmd(0x20, 1*8, addr, 24, 0, 0, 0, 0, 0);
|
||||
return fm_flash_wait_idle();
|
||||
}
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR fm_cam_erase_and_fix(uint8_t (*buf)[32])
|
||||
{
|
||||
INFO(FLASH_PATCH_STR("Start erase and program cam buf\n"));
|
||||
// cmd 4.
|
||||
fm_cam_preprog_pre();
|
||||
if (!fm_erase_sector(0x0)) {
|
||||
ERROR(FLASH_PATCH_STR("ERR in ERASE %d\n"), __LINE__);
|
||||
return false;
|
||||
}
|
||||
int retry = 40;
|
||||
while (retry > 0) {
|
||||
WDT_FEED();
|
||||
// cmd 5.
|
||||
fm_cam_step_erase_pre();
|
||||
if (!fm_erase_sector(0x0)) {
|
||||
ERROR(FLASH_PATCH_STR("ERR in ERASE %d\n"), __LINE__);
|
||||
return false;
|
||||
}
|
||||
// cmd 6.
|
||||
fm_cam_step_prog_pre();
|
||||
if (!fm_erase_sector(0x0)) {
|
||||
ERROR(FLASH_PATCH_STR("ERR in ERASE %d\n"), __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
INFO(FLASH_PATCH_STR("Start programming 5 page\n"));
|
||||
fm_cam_prog_pre();
|
||||
int line = 0;
|
||||
for (line = 0; line < 5; line++) {
|
||||
// write en
|
||||
fm_send_spi_cmd(0x06, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
// prog
|
||||
fm_send_spi_cmd(0x02, 8, 0x20*line, 24, &buf[line][0], 32*8, 0, 0, 0);
|
||||
fm_flash_wait_idle();
|
||||
WDT_FEED();
|
||||
// for (uint32_t loop = 0; loop < 32; loop++) {
|
||||
// DEBUG(FLASH_PATCH_STR("%02x "), buf[line][loop]);
|
||||
// }
|
||||
// INFO(FLASH_PATCH_STR("\n"));
|
||||
}
|
||||
INFO(FLASH_PATCH_STR("Programming Done\n"));
|
||||
|
||||
// cmd 7.
|
||||
fm_cam_read_after_erase_pre();
|
||||
int found_error = false;
|
||||
for (line = 0; line < 5; line++) {
|
||||
uint32_t cam_rd[8];
|
||||
fm_send_spi_cmd(0x03, 8, 0x20 * line, 24, 0, 0, cam_rd, 32*8, 0);
|
||||
int idx = 0;
|
||||
for (idx = 0;idx < 8; idx++) {
|
||||
uint32_t* p = buf[line];
|
||||
if (cam_rd[idx] != p[idx]) {
|
||||
found_error = true;
|
||||
ERROR(FLASH_PATCH_STR("erase check error, retry...%d, %d, 0x%08x\n"), retry, idx, cam_rd[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
retry -= 1;
|
||||
}
|
||||
|
||||
if (!found_error) {
|
||||
for (line = 5; line < 20; line++) {
|
||||
uint32_t cam_rd[8];
|
||||
fm_send_spi_cmd(0x03, 8, 0x20 * line, 24, 0, 0, cam_rd, 32*8, 0);
|
||||
int idx = 0;
|
||||
for (idx = 0;idx < 8; idx++) {
|
||||
if (cam_rd[idx] != 0x000000ff) {
|
||||
found_error = true;
|
||||
ERROR(FLASH_PATCH_STR("erase check error, retry...%d, %d, 0x%08x\n"), retry, idx, cam_rd[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
retry -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found_error) {
|
||||
INFO(FLASH_PATCH_STR("Erase Pass !!!\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (retry <= 0) {
|
||||
ERROR(FLASH_PATCH_STR("Erase fail !!!\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// cmd 3.
|
||||
INFO(FLASH_PATCH_STR("Start programming\n"));
|
||||
fm_cam_prog_pre();
|
||||
int line = 0;
|
||||
for (line = 5; line < 20; line++) {
|
||||
// write en
|
||||
fm_send_spi_cmd(0x06, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
// prog
|
||||
fm_send_spi_cmd(0x02, 8, 0x20*line, 24, &buf[line][0], 32*8, 0, 0, 0);
|
||||
fm_flash_wait_idle();
|
||||
WDT_FEED();
|
||||
for (uint32_t loop = 0; loop < 32; loop++) {
|
||||
DEBUG(FLASH_PATCH_STR("%02x "), buf[line][loop]);
|
||||
}
|
||||
INFO(FLASH_PATCH_STR("\n"));
|
||||
}
|
||||
|
||||
// read buffer
|
||||
INFO(FLASH_PATCH_STR("Prog done, read and check"));
|
||||
fm_cam_read_pre();
|
||||
for (line = 0;line < 20; line++) {
|
||||
WDT_FEED();
|
||||
uint8_t cam_check[32];
|
||||
fm_send_spi_cmd(0x03, 8, 0x20*line, 24, 0, 0, cam_check, 32*8, 0);
|
||||
int j = 0;
|
||||
for (j = 0; j < 32; j++) {
|
||||
DEBUG(FLASH_PATCH_STR("%02x "), cam_check[j]);
|
||||
if ((j + 1) % 16 == 0) {
|
||||
DEBUG(FLASH_PATCH_STR("\n"));
|
||||
}
|
||||
}
|
||||
if (memcmp(cam_check, buf[line], 32) != 0) {
|
||||
ERROR(FLASH_PATCH_STR("CAM BUF[%d] check error\n"), line);
|
||||
ets_delay_us(50000);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
INFO(FLASH_PATCH_STR("CAM prog done !!!\n"));
|
||||
return true;
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR cam_buf_default_rodata[20][32] = {
|
||||
{0x55, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x53, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x53, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x23, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0xe3, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x23, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
};
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR esp_fm_check_uid()
|
||||
{
|
||||
uint8_t cam_buf_default[20][32];
|
||||
|
||||
memcpy(cam_buf_default, cam_buf_default_rodata, 20*32);
|
||||
|
||||
// cmd 2.
|
||||
fm_cam_uid_pre();
|
||||
uint8_t uid[6];
|
||||
fm_send_spi_cmd(0x03, 1*8, 0x25, 3*8, NULL, 0, uid, 6*8, 0);
|
||||
if(uid[0] == ~uid[1] && uid[2] == ~uid[3] && uid[4] == ~uid[5]) {
|
||||
INFO(FLASH_PATCH_STR("UID check correct, update buf\n"));
|
||||
cam_buf_default[3][12] = uid[0] & 0xff;
|
||||
cam_buf_default[5][0] = uid[2] & 0xff;
|
||||
cam_buf_default[6][0] = uid[2] & 0xff;
|
||||
cam_buf_default[7][0] = uid[4] & 0xff;
|
||||
cam_buf_default[9][0] = uid[4] & 0xff;
|
||||
} else {
|
||||
INFO(FLASH_PATCH_STR("UID check error, use default buf\n"));
|
||||
}
|
||||
WDT_FEED();
|
||||
bool res = fm_cam_erase_and_fix(cam_buf_default);
|
||||
WDT_FEED();
|
||||
fm_soft_reset();
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR fm_cam_check_buf_valid(uint8_t (*buf)[32])
|
||||
{
|
||||
bool res = false;
|
||||
// cmd 1.
|
||||
fm_cam_read_pre();
|
||||
|
||||
int i = 0, j = 0;
|
||||
for (i = 0; i < 20; i++) {
|
||||
// read buf
|
||||
fm_send_spi_cmd(0x03, 8, 0x20 * i, 24, 0, 0, &buf[i][0], 32*8, 0);
|
||||
for (j = 0; j < 32; j++) {
|
||||
DEBUG(FLASH_PATCH_STR("%02x "), buf[i][j]);
|
||||
if ((j + 1) % 16 == 0) {
|
||||
DEBUG(FLASH_PATCH_STR("\n"));
|
||||
INFO(FLASH_PATCH_STR("\r"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buf[0][0] == 0x55 && buf[0][4] == 0xaa \
|
||||
&& buf[4][0] == 0x00 \
|
||||
&& buf[10][0] == 0x1 && buf[10][20] == 0xff\
|
||||
&& buf[11][0] == 0x1 && buf[11][20] == 0xff\
|
||||
&& buf[12][0] == 0x1 && buf[12][20] == 0xff\
|
||||
&& buf[13][0] == 0x1 && buf[13][20] == 0xff\
|
||||
&& buf[14][0] == 0x1 && buf[14][20] == 0xff\
|
||||
&& buf[15][0] == 0x1 && buf[15][20] == 0xff\
|
||||
&& buf[16][0] == 0x1 && buf[16][20] == 0xff\
|
||||
&& buf[17][0] == 0x1 && buf[17][20] == 0xff
|
||||
) {
|
||||
INFO(FLASH_PATCH_STR("CAM buffer check valid !!!\n"));
|
||||
res = true;
|
||||
} else {
|
||||
INFO(FLASH_PATCH_STR("CAM buffer check IN-Valid !!!\n"));
|
||||
res = false;
|
||||
}
|
||||
// while(1);
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR fm_fix_cam()
|
||||
{
|
||||
uint8_t check_buf[20][32];
|
||||
|
||||
if (fm_cam_check_buf_valid(check_buf) == false) {
|
||||
ERROR(FLASH_PATCH_STR("Cam buf not valid\n"));
|
||||
return esp_fm_check_uid();
|
||||
} else {
|
||||
INFO(FLASH_PATCH_STR("Cam buf valid\n"));
|
||||
|
||||
if ((check_buf[3][0] & 0x08) == 0x08) {
|
||||
INFO(FLASH_PATCH_STR("Bit3 == 1, already fixed....\n"));
|
||||
fm_soft_reset();
|
||||
} else {
|
||||
check_buf[3][0] |= 0x08;
|
||||
bool res = fm_cam_erase_and_fix(check_buf);
|
||||
fm_soft_reset();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t FLASH_PATCH_TEXT_ATTR fm_flash_id(void)
|
||||
{
|
||||
uint32_t data[6];
|
||||
uint8_t* id = (uint8_t*)data;
|
||||
#if 1
|
||||
fm_send_spi_cmd(0x9f, 8, 0, 0, 0, 0, id, 24*8, 0);
|
||||
return (id[0]<<16 | id[1]<<8 | id[2]);
|
||||
#else
|
||||
uint32_t flash_id = spi_flash_get_id();
|
||||
memcpy(id, &flash_id, 3);
|
||||
return (id[0]<<16 | id[1]<<8 | id[2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FLASH_PATCH_TEXT_ATTR fm25q16a_apply_patch_0()
|
||||
{
|
||||
bool res = false;
|
||||
|
||||
spi_state_t state;
|
||||
spi_enter(&state);
|
||||
uint32_t flash_id = fm_flash_id();
|
||||
DEBUG(FLASH_PATCH_STR("Flash id: 0x%x\n"), flash_id);
|
||||
|
||||
WDT_FEED();
|
||||
if (flash_id == 0xa14015) {
|
||||
INFO(DRAM_STR("Found FM25Q16A, check CAM buf\n"));
|
||||
res = fm_fix_cam();
|
||||
} else if ((flash_id&0xffffff) == 0x0 || (flash_id&0xffffff) == 0xffffff) {
|
||||
INFO(FLASH_PATCH_STR("Found ID error, recover default CAM buf\n"));
|
||||
res = esp_fm_check_uid();
|
||||
} else {
|
||||
INFO(FLASH_PATCH_STR("Normal flash, continue...\n"));
|
||||
res = true;
|
||||
}
|
||||
WDT_FEED();
|
||||
|
||||
spi_exit(&state);
|
||||
|
||||
if (res != true) {
|
||||
fm_printf(FLASH_PATCH_STR("fix fail\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
fm_printf(FLASH_PATCH_STR("fix done\n"));
|
||||
return 0;
|
||||
}
|
||||
58
components/spi_flash/src/patch/spi_flash_patch.h
Normal file
58
components/spi_flash/src/patch/spi_flash_patch.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2024-2026 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _SPI_FLASH_PATCH_H
|
||||
#define _SPI_FLASH_PATCH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FLASH_PATCH_TEXT_ATTR __attribute__((section(".flash.patch.text")))
|
||||
#define FLASH_PATCH_RODATA_ATTR __attribute__((section(".flash.patch.rodata")))
|
||||
#define FLASH_PATCH_BSS_ATTR __attribute__((section(".flash.patch.bss")))
|
||||
|
||||
#define FLASH_PATCH_STR(str) (__extension__({static const FLASH_PATCH_RODATA_ATTR char __c[] = (str); (const char *)&__c;}))
|
||||
|
||||
#if 1
|
||||
typedef int (*__ets_printf_t)(const char *fmt, ...);
|
||||
#define ROM_PRINTF(_fmt, ...) ((__ets_printf_t)(0x400024cc))(_fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define ROM_PRINTF(_fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct spi_state {
|
||||
uint32_t io_mux_reg;
|
||||
uint32_t spi_clk_reg;
|
||||
uint32_t spi_ctrl_reg;
|
||||
uint32_t spi_user_reg;
|
||||
} spi_state_t;
|
||||
|
||||
void spi_enter(spi_state_t *state);
|
||||
void spi_exit(spi_state_t *state);
|
||||
|
||||
void spi_trans(bool write_mode, uint32_t cmd, uint32_t cmd_bits, uint32_t addr, uint32_t addr_bits, uint8_t *data,
|
||||
uint32_t data_bytes, uint32_t dummy_bits);
|
||||
void patch_delay(int ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SPI_FLASH_H */
|
||||
@@ -28,279 +28,55 @@
|
||||
#include "esp8266/spi_register.h"
|
||||
#include "esp8266/spi_struct.h"
|
||||
|
||||
#define SPI_FLASH SPI0
|
||||
#define SPI_BLOCK_SIZE 32
|
||||
#define ADDR_SHIFT_BITS 8
|
||||
#include "spi_flash_patch.h"
|
||||
|
||||
#if 0
|
||||
typedef int (*__ets_printf_t)(const char *fmt, ...);
|
||||
#define ROM_PRINTF(_fmt, ...) ((__ets_printf_t)(0x400024cc))(_fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define ROM_PRINTF(_fmt, ...)
|
||||
#endif
|
||||
#define SPI_BLOCK_SIZE 32
|
||||
|
||||
void spi_trans(bool write_mode, uint32_t cmd, uint32_t cmd_bits, uint32_t addr, uint32_t addr_bits, uint8_t *data,
|
||||
uint32_t data_bytes, uint32_t dummy_bits);
|
||||
void patch_delay(int ms);
|
||||
|
||||
#define TOCHAR(_v) #_v
|
||||
#define PRINT_STEP(_s) ROM_PRINTF("Step %d\n", (_s));
|
||||
#define JUMP_TO_STEP(_s) { ROM_PRINTF("Jump to " TOCHAR(_s) "\n"); goto _s; }
|
||||
#define GOTO_FAILED(_s) { ROM_PRINTF("ERROR: " TOCHAR(_s) " failed\n"); ret = -EIO; JUMP_TO_STEP(step17); }
|
||||
#define PRINT_STEP(_s) ROM_PRINTF(FLASH_PATCH_STR("Step %d\n"), (_s));
|
||||
#define JUMP_TO_STEP(_s) { ROM_PRINTF(FLASH_PATCH_STR("%d line Jump to " TOCHAR(_s) "\n"), __LINE__); goto _s; }
|
||||
#define GOTO_FAILED(_s) { ROM_PRINTF(FLASH_PATCH_STR("ERROR: " TOCHAR(_s) " failed\n")); ret = -EIO; JUMP_TO_STEP(step17); }
|
||||
|
||||
#define write_u8_dummy(_c, _a, _d8,_d) {uint32_t __data = _d8; spi_trans(1, (_c), 8, (_a), 24, (uint8_t *)&__data, 1, (_d));}
|
||||
#define write_u8(_c, _a, _d8) write_u8_dummy((_c), (_a), (_d8), 0)
|
||||
|
||||
extern void Cache_Read_Disable_2(void);
|
||||
extern void Cache_Read_Enable_2();
|
||||
extern void vPortEnterCritical(void);
|
||||
extern void vPortExitCritical(void);
|
||||
extern uint32_t spi_flash_get_id(void);
|
||||
|
||||
static void delay(int ms)
|
||||
{
|
||||
for (volatile int i = 0; i < ms; i++) {
|
||||
for (volatile int j = 0; j < 7800; j++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
static uint8_t FLASH_PATCH_BSS_ATTR buffer1024[1024];
|
||||
|
||||
#if 0
|
||||
static void dump_hex(const uint8_t *ptr, int n)
|
||||
{
|
||||
const uint8_t *s1 = ptr;
|
||||
const int line_bytes = 16;
|
||||
|
||||
ROM_PRINTF("\nHex:\n");
|
||||
for (int i = 0; i < n ; i += line_bytes)
|
||||
{
|
||||
int m = MIN(n - i, line_bytes);
|
||||
|
||||
ROM_PRINTF("\t");
|
||||
for (int j = 0; j < m; j++)
|
||||
{
|
||||
ROM_PRINTF("%02x ", s1[i + j]);
|
||||
}
|
||||
|
||||
ROM_PRINTF("\n");
|
||||
}
|
||||
|
||||
ROM_PRINTF("\n");
|
||||
}
|
||||
|
||||
static void dump_hex_compare(const uint8_t *s1, const uint8_t *s2, int n)
|
||||
{
|
||||
const int line_bytes = 16;
|
||||
|
||||
ROM_PRINTF("\nHex:\n");
|
||||
for (int i = 0; i < n ; i += line_bytes)
|
||||
{
|
||||
int m = MIN(n - i, line_bytes);
|
||||
|
||||
ROM_PRINTF("\t");
|
||||
for (int j = 0; j < m; j++)
|
||||
{
|
||||
ROM_PRINTF("%02x:%02x ", s1[i + j], s2[i + j]);
|
||||
}
|
||||
|
||||
ROM_PRINTF("\n");
|
||||
}
|
||||
|
||||
ROM_PRINTF("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct spi_state {
|
||||
uint32_t io_mux_reg;
|
||||
uint32_t spi_clk_reg;
|
||||
uint32_t spi_ctrl_reg;
|
||||
uint32_t spi_user_reg;
|
||||
} spi_state_t;
|
||||
|
||||
static void spi_enter(spi_state_t *state)
|
||||
{
|
||||
vPortEnterCritical();
|
||||
Cache_Read_Disable_2();
|
||||
|
||||
Wait_SPI_Idle(&g_rom_flashchip);
|
||||
|
||||
state->io_mux_reg = READ_PERI_REG(PERIPHS_IO_MUX_CONF_U);
|
||||
state->spi_clk_reg = SPI_FLASH.clock.val;
|
||||
state->spi_ctrl_reg = SPI_FLASH.ctrl.val;
|
||||
state->spi_user_reg = SPI_FLASH.user.val;
|
||||
|
||||
SPI_FLASH.user.usr_command = 1;
|
||||
SPI_FLASH.user.flash_mode = 0;
|
||||
SPI_FLASH.user.usr_miso_highpart = 0;
|
||||
|
||||
CLEAR_PERI_REG_MASK(PERIPHS_IO_MUX_CONF_U, SPI0_CLK_EQU_SYS_CLK);
|
||||
|
||||
SPI_FLASH.user.cs_setup = 1;
|
||||
SPI_FLASH.user.cs_hold = 1;
|
||||
SPI_FLASH.user.usr_mosi = 1;
|
||||
|
||||
SPI_FLASH.user.usr_command = 1;
|
||||
SPI_FLASH.user.flash_mode = 0;
|
||||
|
||||
SPI_FLASH.ctrl.fread_qio = 0;
|
||||
SPI_FLASH.ctrl.fread_dio = 0;
|
||||
SPI_FLASH.ctrl.fread_quad = 0;
|
||||
SPI_FLASH.ctrl.fread_dual = 0;
|
||||
|
||||
SPI_FLASH.clock.val = 0;
|
||||
SPI_FLASH.clock.clkcnt_l = 3;
|
||||
SPI_FLASH.clock.clkcnt_h = 1;
|
||||
SPI_FLASH.clock.clkcnt_n = 3;
|
||||
|
||||
SPI_FLASH.ctrl.fastrd_mode = 1;
|
||||
|
||||
while (SPI_FLASH.cmd.usr) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_exit(spi_state_t *state)
|
||||
{
|
||||
while (SPI_FLASH.cmd.usr) {
|
||||
;
|
||||
}
|
||||
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX_CONF_U, state->io_mux_reg);
|
||||
|
||||
SPI_FLASH.ctrl.val = state->spi_ctrl_reg;
|
||||
SPI_FLASH.clock.val = state->spi_clk_reg;
|
||||
SPI_FLASH.user.val = state->spi_user_reg;
|
||||
|
||||
Cache_Read_Enable_2();
|
||||
vPortExitCritical();
|
||||
}
|
||||
|
||||
static void spi_trans_block(bool write_mode,
|
||||
uint32_t cmd,
|
||||
uint32_t cmd_bits,
|
||||
uint32_t addr,
|
||||
uint32_t addr_bits,
|
||||
uint8_t *data,
|
||||
uint32_t data_bytes,
|
||||
uint32_t dummy_bits)
|
||||
{
|
||||
if ((uint32_t)data & 0x3) {
|
||||
ROM_PRINTF("ERROR: data=%p\n", data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd_bits) {
|
||||
SPI_FLASH.user.usr_command = 1;
|
||||
SPI_FLASH.user2.usr_command_value = cmd;
|
||||
SPI_FLASH.user2.usr_command_bitlen = cmd_bits - 1;
|
||||
} else {
|
||||
SPI_FLASH.user.usr_command = 0;
|
||||
}
|
||||
|
||||
if (addr_bits) {
|
||||
SPI_FLASH.user.usr_addr = 1;
|
||||
SPI_FLASH.addr = addr << ADDR_SHIFT_BITS;
|
||||
SPI_FLASH.user1.usr_addr_bitlen = addr_bits - 1;
|
||||
} else {
|
||||
SPI_FLASH.user.usr_addr = 0;
|
||||
}
|
||||
|
||||
if (dummy_bits) {
|
||||
SPI_FLASH.user.usr_dummy = 1;
|
||||
SPI_FLASH.user1.usr_dummy_cyclelen = dummy_bits - 1;
|
||||
} else {
|
||||
SPI_FLASH.user.usr_dummy = 0;
|
||||
}
|
||||
|
||||
if (write_mode && data_bytes) {
|
||||
int words = (data_bytes + 3) / 4;
|
||||
uint32_t *p = (uint32_t *)data;
|
||||
|
||||
SPI_FLASH.user.usr_mosi = 1;
|
||||
SPI_FLASH.user.usr_miso = 0;
|
||||
SPI_FLASH.user1.usr_mosi_bitlen = data_bytes * 8 - 1;
|
||||
|
||||
for (int i = 0; i < words; i++) {
|
||||
SPI_FLASH.data_buf[i] = p[i];
|
||||
}
|
||||
} else if (!write_mode && data_bytes) {
|
||||
int words = (data_bytes + 3) / 4;
|
||||
|
||||
SPI_FLASH.user.usr_mosi = 0;
|
||||
SPI_FLASH.user.usr_miso = 1;
|
||||
SPI_FLASH.user1.usr_miso_bitlen = data_bytes * 8 - 1;
|
||||
|
||||
for (int i = 0; i < words; i++) {
|
||||
SPI_FLASH.data_buf[i] = 0;
|
||||
}
|
||||
} else {
|
||||
SPI_FLASH.user.usr_mosi = 0;
|
||||
SPI_FLASH.user.usr_miso = 0;
|
||||
}
|
||||
|
||||
SPI_FLASH.cmd.usr = 1;
|
||||
while (SPI_FLASH.cmd.usr) {
|
||||
;
|
||||
}
|
||||
|
||||
if (!write_mode && data_bytes) {
|
||||
int words = (data_bytes + 3) / 4;
|
||||
uint32_t *p = (uint32_t *)data;
|
||||
|
||||
for (int i = 0; i < words; i++) {
|
||||
p[i] = SPI_FLASH.data_buf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_trans(bool write_mode,
|
||||
uint32_t cmd,
|
||||
uint32_t cmd_bits,
|
||||
uint32_t addr,
|
||||
uint32_t addr_bits,
|
||||
uint8_t *data,
|
||||
uint32_t data_bytes,
|
||||
uint32_t dummy_bits)
|
||||
|
||||
{
|
||||
if (!data_bytes || data_bytes <= SPI_BLOCK_SIZE) {
|
||||
return spi_trans_block(write_mode, cmd, cmd_bits, addr,
|
||||
addr_bits, data, data_bytes, dummy_bits);
|
||||
}
|
||||
|
||||
for (int i = 0; i < data_bytes; i += SPI_BLOCK_SIZE) {
|
||||
uint32_t n = MIN(SPI_BLOCK_SIZE, data_bytes - i);
|
||||
|
||||
spi_trans_block(write_mode, cmd, cmd_bits, addr + i,
|
||||
addr_bits, data + i, n, dummy_bits);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_cmd(uint32_t cmd)
|
||||
static void FLASH_PATCH_TEXT_ATTR write_cmd(uint32_t cmd)
|
||||
{
|
||||
spi_trans(1, cmd, 8, 0, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
static void write_buffer(uint32_t addr, uint8_t *buffer, int size)
|
||||
static void FLASH_PATCH_TEXT_ATTR write_buffer(uint32_t addr, uint8_t *buffer, int size)
|
||||
{
|
||||
for (int i = 0; i < size; i += SPI_BLOCK_SIZE) {
|
||||
int n = MIN(size - i, SPI_BLOCK_SIZE);
|
||||
|
||||
write_cmd(0x6);
|
||||
spi_trans(1, 0x42, 8, addr + i, 24, buffer + i, n, 0);
|
||||
delay(3);
|
||||
patch_delay(3);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_buffer(uint32_t addr, uint8_t *buffer, int n)
|
||||
static void FLASH_PATCH_TEXT_ATTR read_buffer(uint32_t addr, uint8_t *buffer, int n)
|
||||
{
|
||||
spi_trans(0, 0x48, 8, addr, 24, buffer, n, 8);
|
||||
}
|
||||
|
||||
static void erase_sector(uint32_t addr)
|
||||
static void FLASH_PATCH_TEXT_ATTR erase_sector(uint32_t addr)
|
||||
{
|
||||
write_cmd(0x6);
|
||||
spi_trans(1, 0x44, 8, addr, 24, NULL, 0, 0);
|
||||
delay(8);
|
||||
patch_delay(8);
|
||||
}
|
||||
|
||||
int th25q16hb_apply_patch_0(void)
|
||||
int FLASH_PATCH_TEXT_ATTR th25q16hb_apply_patch_0(void)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t flash_id;
|
||||
@@ -309,19 +85,13 @@ int th25q16hb_apply_patch_0(void)
|
||||
uint8_t *buffer256_0;
|
||||
uint8_t *buffer256_1;
|
||||
uint8_t *buffer256_2;
|
||||
uint8_t *buffer1024;
|
||||
|
||||
flash_id = spi_flash_get_id();
|
||||
if (flash_id != 0x1560eb) {
|
||||
ROM_PRINTF("WARN: id=0x%x, is not TH25Q16HB\n", flash_id);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("WARN: id=0x%x, is not TH25Q16HB\n"), flash_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer1024 = heap_caps_malloc(1024, MALLOC_CAP_8BIT);
|
||||
if (!buffer1024) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
buffer256_0 = buffer1024;
|
||||
buffer256_1 = buffer1024 + 256;
|
||||
buffer256_2 = buffer1024 + 512;
|
||||
@@ -351,7 +121,7 @@ int th25q16hb_apply_patch_0(void)
|
||||
if (buffer256_0[0] == 0xff &&
|
||||
buffer256_0[1] == 0xff &&
|
||||
buffer256_0[2] == 0xff) {
|
||||
ROM_PRINTF("INFO: check done 0\n");
|
||||
ROM_PRINTF(FLASH_PATCH_STR("INFO: check done 0\n"));
|
||||
} else if (buffer256_0[0] == 0x55 &&
|
||||
buffer256_0[1] == 0xff &&
|
||||
buffer256_0[2] == 0xff) {
|
||||
@@ -365,20 +135,20 @@ int th25q16hb_apply_patch_0(void)
|
||||
buffer256_0[2] == 0x55) {
|
||||
JUMP_TO_STEP(step17);
|
||||
} else {
|
||||
ROM_PRINTF("ERROR: 0xbed=0x%x 0xbee=0x%x 0xbef=0x%x\n",
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: 0xbed=0x%x 0xbee=0x%x 0xbef=0x%x\n"),
|
||||
buffer256_0[0], buffer256_0[1], buffer256_0[2]);
|
||||
GOTO_FAILED(5-1);
|
||||
}
|
||||
|
||||
JUMP_TO_STEP(step17);
|
||||
// Step 5-2
|
||||
read_buffer(0x50d, buffer256_0, 1);
|
||||
buffer256_0[0] &= 0x7f;
|
||||
if (buffer256_0[0] == 0x7c) {
|
||||
JUMP_TO_STEP(step17);
|
||||
} else if (buffer256_0[0] == 0x3c) {
|
||||
ROM_PRINTF("INFO: check done 1\n");
|
||||
ROM_PRINTF(FLASH_PATCH_STR("INFO: check done 1\n"));
|
||||
} else {
|
||||
ROM_PRINTF("ERROR: 0x50d=0x%x\n", buffer256_0[0]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: 0x50d=0x%x\n"), buffer256_0[0]);
|
||||
GOTO_FAILED(5-2);
|
||||
}
|
||||
|
||||
@@ -392,7 +162,7 @@ int th25q16hb_apply_patch_0(void)
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
if (buffer1024[i] != 0xff) {
|
||||
check_done = false;
|
||||
ROM_PRINTF("ERROR: buffer1024[%d]=0x%x\n", i, buffer1024[i]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: buffer1024[%d]=0x%x\n"), i, buffer1024[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -465,7 +235,7 @@ int th25q16hb_apply_patch_0(void)
|
||||
read_buffer(0x0, buffer256_0, 1);
|
||||
read_buffer(0x23, buffer256_1, 1);
|
||||
if (buffer256_0[0] != 0x13 || buffer256_1[0] != 0x14) {
|
||||
ROM_PRINTF("ERROR: 0x0=0x%x 0x23=0x%x\n", buffer256_0[0], buffer256_1[0]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: 0x0=0x%x 0x23=0x%x\n"), buffer256_0[0], buffer256_1[0]);
|
||||
GOTO_FAILED(8);
|
||||
}
|
||||
|
||||
@@ -473,7 +243,7 @@ int th25q16hb_apply_patch_0(void)
|
||||
PRINT_STEP(9);
|
||||
read_buffer(0x140, buffer256_0, 2);
|
||||
if (buffer256_0[0] != 0 || buffer256_0[1] != 0xff) {
|
||||
ROM_PRINTF("ERROR: 0x140=0x%x 0x141=0x%x\n", buffer256_0[0], buffer256_0[1]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: 0x140=0x%x 0x141=0x%x\n"), buffer256_0[0], buffer256_0[1]);
|
||||
GOTO_FAILED(9-1);
|
||||
}
|
||||
|
||||
@@ -507,7 +277,7 @@ step10:
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
if (buffer1024[i] != 0xff) {
|
||||
check_done = false;
|
||||
ROM_PRINTF("ERROR: buffer1024[%d]=0x%x\n", i, buffer1024[i]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: buffer1024[%d]=0x%x\n"), i, buffer1024[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -585,7 +355,7 @@ step10:
|
||||
read_buffer(0x400, buffer256_0, 1);
|
||||
read_buffer(0x423, buffer256_1, 1);
|
||||
if (buffer256_0[0] != 0x13 || buffer256_1[0] != 0x14) {
|
||||
ROM_PRINTF("ERROR: 0x400=0x%x 0x423=0x%x\n", buffer256_0[0], buffer256_1[0]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: 0x400=0x%x 0x423=0x%x\n"), buffer256_0[0], buffer256_1[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -597,7 +367,7 @@ step10:
|
||||
for (count = 0; count < 3; count++) {
|
||||
read_buffer(0x540, buffer256_0, 2);
|
||||
if (buffer256_0[0] != 0 || buffer256_0[1] != 0xff) {
|
||||
ROM_PRINTF("ERROR: 0x540=0x%x 0x541=0x%x\n", buffer256_0[0], buffer256_0[1]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: 0x540=0x%x 0x541=0x%x\n"), buffer256_0[0], buffer256_0[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -610,7 +380,7 @@ step10:
|
||||
read_buffer(0x50d, buffer256_0, 1);
|
||||
buffer256_0[0] &= 0x7f;
|
||||
if (buffer256_0[0] != 0x7c) {
|
||||
ROM_PRINTF("ERROR: 0x50d=0x%x\n", buffer256_0[0]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: 0x50d=0x%x\n"), buffer256_0[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -652,7 +422,7 @@ step14:
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
if (buffer1024[i] != 0xff) {
|
||||
check_done = false;
|
||||
ROM_PRINTF("ERROR: buffer1024[%d]=0x%x\n", i, buffer1024[i]);
|
||||
ROM_PRINTF(FLASH_PATCH_STR("ERROR: buffer1024[%d]=0x%x\n"), i, buffer1024[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -699,10 +469,8 @@ step17:
|
||||
|
||||
spi_exit(&state);
|
||||
|
||||
heap_caps_free(buffer1024);
|
||||
|
||||
if (!ret) {
|
||||
ROM_PRINTF("INFO: Patch for TH25Q16HB is done\n");
|
||||
ROM_PRINTF(FLASH_PATCH_STR("INFO: Patch for TH25Q16HB is done\n"));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user