mirror of https://github.com/wolfSSL/wolfBoot.git
parent
8eddbf3516
commit
98d1e7726f
|
|
@ -431,38 +431,40 @@ int spi_flash_write(uint32_t address, const void *data, int len)
|
|||
pages = ((len + (FLASH_PAGE_SIZE-1)) / FLASH_PAGE_SIZE);
|
||||
for (page = 0; page < pages; page++) {
|
||||
ret = qspi_write_enable();
|
||||
if (ret == 0) {
|
||||
xferSz = (uint32_t)remaining;
|
||||
if (xferSz > FLASH_PAGE_SIZE) {
|
||||
xferSz = FLASH_PAGE_SIZE;
|
||||
}
|
||||
|
||||
addr = address + (page * FLASH_PAGE_SIZE);
|
||||
|
||||
/* ------ Write Flash (page at a time) ------ */
|
||||
ret = qspi_transfer(QSPI_MODE_WRITE, FLASH_WRITE_CMD,
|
||||
addr, QSPI_ADDR_SZ, QSPI_DATA_MODE_SPI, /* Address */
|
||||
0, 0, QSPI_DATA_MODE_NONE, /* Alternate Bytes */
|
||||
0, /* Dummy */
|
||||
ptr, /* Destination Ptr */
|
||||
xferSz, QSPI_DATA_MODE /* Data */
|
||||
);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("QSPI Flash Sector Write: "
|
||||
"Ret %d, Cmd 0x%x, Len %d, %p -> 0x%x\n",
|
||||
ret, FLASH_WRITE_CMD, xferSz, ptr, address);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
break;
|
||||
|
||||
ret = qspi_wait_ready(); /* Wait for not busy */
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
/* write disable is automatic */
|
||||
remaining -= (int)xferSz;
|
||||
ptr += xferSz;
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
xferSz = (uint32_t)remaining;
|
||||
if (xferSz > FLASH_PAGE_SIZE) {
|
||||
xferSz = FLASH_PAGE_SIZE;
|
||||
}
|
||||
|
||||
addr = address + (page * FLASH_PAGE_SIZE);
|
||||
|
||||
/* ------ Write Flash (page at a time) ------ */
|
||||
ret = qspi_transfer(QSPI_MODE_WRITE, FLASH_WRITE_CMD,
|
||||
addr, QSPI_ADDR_SZ, QSPI_DATA_MODE_SPI, /* Address */
|
||||
0, 0, QSPI_DATA_MODE_NONE, /* Alternate Bytes */
|
||||
0, /* Dummy */
|
||||
ptr, /* Destination Ptr */
|
||||
xferSz, QSPI_DATA_MODE /* Data */
|
||||
);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("QSPI Flash Sector Write: "
|
||||
"Ret %d, Cmd 0x%x, Len %d, %p -> 0x%x\n",
|
||||
ret, FLASH_WRITE_CMD, xferSz, ptr, address);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
break;
|
||||
|
||||
ret = qspi_wait_ready(); /* Wait for not busy */
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
/* write disable is automatic */
|
||||
remaining -= (int)xferSz;
|
||||
ptr += xferSz;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#define QSPI_FLASH
|
||||
#define QSPI_FLASH_READY_TRIES 4
|
||||
|
||||
#include <check.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -13,6 +14,9 @@ static int program_call_count;
|
|||
static uint32_t program_sizes[8];
|
||||
static const uint8_t *program_ptrs[8];
|
||||
static uint32_t program_addrs[8];
|
||||
static int write_enable_call_count;
|
||||
static int write_enable_status_seq[8];
|
||||
static int current_write_enable_call;
|
||||
|
||||
void spi_init(int polarity, int phase)
|
||||
{
|
||||
|
|
@ -41,10 +45,21 @@ int qspi_transfer(uint8_t fmode, const uint8_t cmd,
|
|||
(void)dummySz;
|
||||
(void)dataMode;
|
||||
|
||||
if (cmd == WRITE_ENABLE_CMD) {
|
||||
write_enable_call_count++;
|
||||
current_write_enable_call = write_enable_call_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmd == READ_SR_CMD) {
|
||||
ck_assert_ptr_nonnull(data);
|
||||
ck_assert_uint_ge(dataSz, 1);
|
||||
data[0] = FLASH_SR_WRITE_EN;
|
||||
if (current_write_enable_call > 0 &&
|
||||
write_enable_status_seq[current_write_enable_call - 1] != 0) {
|
||||
data[0] = 0;
|
||||
} else {
|
||||
data[0] = FLASH_SR_WRITE_EN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -66,6 +81,9 @@ static void setup(void)
|
|||
memset(program_sizes, 0, sizeof(program_sizes));
|
||||
memset(program_ptrs, 0, sizeof(program_ptrs));
|
||||
memset(program_addrs, 0, sizeof(program_addrs));
|
||||
write_enable_call_count = 0;
|
||||
current_write_enable_call = 0;
|
||||
memset(write_enable_status_seq, 0, sizeof(write_enable_status_seq));
|
||||
}
|
||||
|
||||
START_TEST(test_qspi_write_splits_last_page_to_remaining_bytes)
|
||||
|
|
@ -88,6 +106,24 @@ START_TEST(test_qspi_write_splits_last_page_to_remaining_bytes)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_qspi_write_stops_after_midloop_write_enable_failure)
|
||||
{
|
||||
uint8_t buf[FLASH_PAGE_SIZE * 3];
|
||||
int ret;
|
||||
|
||||
memset(buf, 0x3C, sizeof(buf));
|
||||
write_enable_status_seq[1] = -1;
|
||||
|
||||
ret = spi_flash_write(0x2000, buf, sizeof(buf));
|
||||
|
||||
ck_assert_int_ne(ret, 0);
|
||||
ck_assert_int_eq(program_call_count, 1);
|
||||
ck_assert_uint_eq(program_sizes[0], FLASH_PAGE_SIZE);
|
||||
ck_assert_ptr_eq(program_ptrs[0], buf);
|
||||
ck_assert_uint_eq(program_addrs[0], 0x2000);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *qspi_flash_suite(void)
|
||||
{
|
||||
Suite *s;
|
||||
|
|
@ -97,6 +133,7 @@ static Suite *qspi_flash_suite(void)
|
|||
tc = tcase_create("Write");
|
||||
tcase_add_checked_fixture(tc, setup, NULL);
|
||||
tcase_add_test(tc, test_qspi_write_splits_last_page_to_remaining_bytes);
|
||||
tcase_add_test(tc, test_qspi_write_stops_after_midloop_write_enable_failure);
|
||||
suite_add_tcase(s, tc);
|
||||
return s;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue