mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-12-13 00:41:43 +08:00
fix: FM25Q16B fails to run due to FM25Q16A patch
This commit is contained in:
@@ -43,7 +43,9 @@
|
||||
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)
|
||||
static bool FLASH_PATCH_TEXT_ATTR double_check_fm25q16a(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, const 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;
|
||||
@@ -234,13 +236,6 @@ static void FLASH_PATCH_TEXT_ATTR fm_cam_read_pre(void)
|
||||
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);
|
||||
// patch_delay(1);
|
||||
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;
|
||||
@@ -250,6 +245,30 @@ static bool FLASH_PATCH_TEXT_ATTR fm_flash_wait_idle()
|
||||
return true;
|
||||
}
|
||||
|
||||
static void FLASH_PATCH_TEXT_ATTR fm_soft_reset()
|
||||
{
|
||||
fm_send_spi_cmd(0x66, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
// patch_delay(1);
|
||||
fm_send_spi_cmd(0x99, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
fm_flash_wait_idle();
|
||||
}
|
||||
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR uid_cmd[4] = {0x00, 0x03, 0xc0, 0x40};
|
||||
static const uint8_t FLASH_PATCH_RODATA_ATTR uid_data[4] = {0x00, 0x01, 0x00, 0x8F};
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR fm_set_uid_flag(void)
|
||||
{
|
||||
fm_soft_reset();
|
||||
fm_cam_cmd_start();
|
||||
fm_send_spi_cmd(0x32, 8, 0, 0, uid_cmd, 4 * 8, NULL, 0, 0);
|
||||
fm_cam_cmd_end();
|
||||
fm_send_spi_cmd(0x06, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
fm_send_spi_cmd(0x02, 8, 0, 0, uid_data, 4 * 8, 0, 0, 0);
|
||||
fm_flash_wait_idle();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR fm_erase_sector(uint32_t addr)
|
||||
{
|
||||
// write en
|
||||
@@ -309,7 +328,7 @@ static bool FLASH_PATCH_TEXT_ATTR fm_cam_erase_and_fix(uint8_t (*buf)[32])
|
||||
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];
|
||||
uint32_t* p = (uint32_t*)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]);
|
||||
@@ -383,6 +402,7 @@ static bool FLASH_PATCH_TEXT_ATTR fm_cam_erase_and_fix(uint8_t (*buf)[32])
|
||||
}
|
||||
}
|
||||
|
||||
fm_set_uid_flag();
|
||||
INFO(FLASH_PATCH_STR("CAM prog done !!!\n"));
|
||||
return true;
|
||||
}
|
||||
@@ -440,40 +460,62 @@ static bool FLASH_PATCH_TEXT_ATTR esp_fm_check_uid()
|
||||
static bool FLASH_PATCH_TEXT_ATTR fm_cam_check_buf_valid(uint8_t (*buf)[32])
|
||||
{
|
||||
bool res = false;
|
||||
// cmd 1.
|
||||
fm_cam_read_pre();
|
||||
uint8_t count = 3;
|
||||
|
||||
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"));
|
||||
while (!res && count--) {
|
||||
// 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_cam_check_uid(void)
|
||||
{
|
||||
bool res = false;
|
||||
uint8_t count = 3;
|
||||
uint8_t uid[8];
|
||||
|
||||
while (!res && count--) {
|
||||
fm_send_spi_cmd(0x4B, 8, 0, 0, 0, 0, &uid[0], 8*8, 4*8);
|
||||
DEBUG(FLASH_PATCH_STR("uid 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n"), uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]);
|
||||
if ((((uid[1]&0xf0) == 0x0) && ((uid[0]&0x70) == 0))
|
||||
|| (((uid[1]&0xf0) != 0x0))) {
|
||||
res = true;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -481,6 +523,14 @@ static bool FLASH_PATCH_TEXT_ATTR fm_fix_cam()
|
||||
{
|
||||
uint8_t check_buf[20][32];
|
||||
|
||||
if (fm_cam_check_uid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!double_check_fm25q16a()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fm_cam_check_buf_valid(check_buf) == false) {
|
||||
ERROR(FLASH_PATCH_STR("Cam buf not valid\n"));
|
||||
return esp_fm_check_uid();
|
||||
@@ -489,6 +539,7 @@ static bool FLASH_PATCH_TEXT_ATTR fm_fix_cam()
|
||||
|
||||
if ((check_buf[3][0] & 0x08) == 0x08) {
|
||||
INFO(FLASH_PATCH_STR("Bit3 == 1, already fixed....\n"));
|
||||
fm_set_uid_flag();
|
||||
fm_soft_reset();
|
||||
} else {
|
||||
check_buf[3][0] |= 0x08;
|
||||
@@ -515,25 +566,83 @@ static uint32_t FLASH_PATCH_TEXT_ATTR fm_flash_id(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR double_check_fm25q16a(void)
|
||||
{
|
||||
uint32_t addr = 0x10;
|
||||
uint8_t value[6];
|
||||
fm_send_spi_cmd(0x9f, 8, 0, 0, 0, 0, NULL, 0, 0);
|
||||
|
||||
fm_cam_cmd_start();
|
||||
fm_send_spi_cmd(0x90, 8, addr, 3 * 8, 0, 0, value, sizeof(value) * 8, 0);
|
||||
fm_cam_cmd_end();
|
||||
DEBUG(FLASH_PATCH_STR("fm25q16a confirm: "));
|
||||
for (uint loop = 0; loop < sizeof(value); loop++) {
|
||||
DEBUG(FLASH_PATCH_STR(" 0x%02x"), value[loop]);
|
||||
if (value[loop] != 0xA1) {
|
||||
DEBUG(FLASH_PATCH_STR("\r\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
DEBUG(FLASH_PATCH_STR("\r\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool FLASH_PATCH_TEXT_ATTR is_fm25q16a(void)
|
||||
{
|
||||
uint8_t status = 0x0;
|
||||
uint8_t count = 3;
|
||||
uint8_t value = 0;
|
||||
|
||||
while (((status&0x20) == 0x0) && count--) {
|
||||
fm_send_spi_cmd(0x50, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
value = 0x80;
|
||||
fm_send_spi_cmd(0x01, 1*8, 0, 0, &value, 1*8, NULL, 0, 0);
|
||||
fm_send_spi_cmd(0x50, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
value = 0x03;
|
||||
fm_send_spi_cmd(0x31, 1*8, 0, 0, &value, 1*8, NULL, 0, 0);
|
||||
fm_send_spi_cmd(0x06, 1*8, 0, 0, NULL, 0, NULL, 0, 0);
|
||||
value = 0x02;
|
||||
fm_send_spi_cmd(0x31, 1*8, 0, 0, &value, 1*8, NULL, 0, 0);
|
||||
|
||||
fm_flash_wait_idle();
|
||||
fm_send_spi_cmd(0x35, 1*8, 0x0, 0, NULL, 0, &status, 1*8, 0);
|
||||
|
||||
fm_soft_reset();
|
||||
}
|
||||
|
||||
if ((status&0x20) == 0) {
|
||||
DEBUG(FLASH_PATCH_STR("It's FM25Q16A\n"));
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG(FLASH_PATCH_STR("It's FM25Q16B\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
int FLASH_PATCH_TEXT_ATTR fm25q16a_apply_patch_0()
|
||||
{
|
||||
bool res = false;
|
||||
bool res = true;
|
||||
|
||||
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();
|
||||
fm_soft_reset();
|
||||
INFO(DRAM_STR("Found FM25Q16A or FM25Q16B\n"));
|
||||
if(is_fm25q16a()) {
|
||||
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();
|
||||
|
||||
@@ -541,7 +650,8 @@ int FLASH_PATCH_TEXT_ATTR fm25q16a_apply_patch_0()
|
||||
|
||||
if (res != true) {
|
||||
fm_printf(FLASH_PATCH_STR("fix fail\n"));
|
||||
return 1;
|
||||
// we should keep running
|
||||
return 0;
|
||||
}
|
||||
|
||||
fm_printf(FLASH_PATCH_STR("fix done\n"));
|
||||
|
||||
Reference in New Issue
Block a user