From e84f47f944eb0bc54a4bd71e7f40c9e5a381450a Mon Sep 17 00:00:00 2001 From: sheinz Date: Mon, 28 Nov 2016 17:17:59 +0200 Subject: [PATCH] SPI flash refactoring. Extract common spiflash.c into core. Use spiflash.c in sysparam. Use memcpy in spiflash.c insted of hand-written version. Tests for spiflash.c --- core/include/flashchip.h | 2 + .../include/spiflash.h | 22 ++-- .../esp_spiffs_flash.c => core/spiflash.c | 96 +++++++-------- core/sysparam.c | 75 +++++------- extras/spiffs/esp_spiffs.c | 12 +- extras/spiffs/unaligned_memcpy.S | 112 ------------------ include/espressif/spi_flash.h | 10 +- tests/cases/07_sysparam.c | 7 +- tests/cases/08_spiflash.c | 51 ++++++++ 9 files changed, 140 insertions(+), 247 deletions(-) rename extras/spiffs/esp_spiffs_flash.h => core/include/spiflash.h (76%) rename extras/spiffs/esp_spiffs_flash.c => core/spiflash.c (71%) delete mode 100644 extras/spiffs/unaligned_memcpy.S create mode 100644 tests/cases/08_spiflash.c diff --git a/core/include/flashchip.h b/core/include/flashchip.h index c14d4a3..c3edbe4 100644 --- a/core/include/flashchip.h +++ b/core/include/flashchip.h @@ -36,4 +36,6 @@ typedef struct { uint32_t status_mask; } sdk_flashchip_t; +extern sdk_flashchip_t sdk_flashchip; + #endif /* _FLASHCHIP_H */ diff --git a/extras/spiffs/esp_spiffs_flash.h b/core/include/spiflash.h similarity index 76% rename from extras/spiffs/esp_spiffs_flash.h rename to core/include/spiflash.h index abfe864..f8397db 100644 --- a/extras/spiffs/esp_spiffs_flash.h +++ b/core/include/spiflash.h @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef __ESP_SPIFFS_FLASH_H__ -#define __ESP_SPIFFS_FLASH_H__ +#ifndef __SPIFLASH_H__ +#define __SPIFLASH_H__ #include +#include #include "common_macros.h" -#define ESP_SPIFFS_FLASH_OK 0 -#define ESP_SPIFFS_FLASH_ERROR 1 +#define SPI_FLASH_SECTOR_SIZE 4096 /** * Read data from SPI flash. @@ -37,9 +37,9 @@ * @param buf Buffer to read to. Doesn't have to be aligned. * @param size Size of data to read. Buffer size must be >= than data size. * - * @return ESP_SPIFFS_FLASH_OK or ESP_SPIFFS_FLASH_ERROR + * @return true if success, otherwise false */ -uint32_t IRAM esp_spiffs_flash_read(uint32_t addr, uint8_t *buf, uint32_t size); +bool IRAM spiflash_read(uint32_t addr, uint8_t *buf, uint32_t size); /** * Write data to SPI flash. @@ -48,17 +48,17 @@ uint32_t IRAM esp_spiffs_flash_read(uint32_t addr, uint8_t *buf, uint32_t size); * @param buf Buffer of data to write to flash. Doesn't have to be aligned. * @param size Size of data to write. Buffer size must be >= than data size. * - * @return ESP_SPIFFS_FLASH_OK or ESP_SPIFFS_FLASH_ERROR + * @return true if success, otherwise false */ -uint32_t IRAM esp_spiffs_flash_write(uint32_t addr, uint8_t *buf, uint32_t size); +bool IRAM spiflash_write(uint32_t addr, uint8_t *buf, uint32_t size); /** * Erase a sector. * * @param addr Address of sector to erase. Must be sector aligned. * - * @return ESP_SPIFFS_FLASH_OK or ESP_SPIFFS_FLASH_ERROR + * @return true if success, otherwise false */ -uint32_t IRAM esp_spiffs_flash_erase_sector(uint32_t addr); +bool IRAM spiflash_erase_sector(uint32_t addr); -#endif // __ESP_SPIFFS_FLASH_H__ +#endif // __SPIFLASH_H__ diff --git a/extras/spiffs/esp_spiffs_flash.c b/core/spiflash.c similarity index 71% rename from extras/spiffs/esp_spiffs_flash.c rename to core/spiflash.c index f0a6049..386d7c9 100644 --- a/extras/spiffs/esp_spiffs_flash.c +++ b/core/spiflash.c @@ -21,12 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "esp_spiffs_flash.h" -#include "flashchip.h" -#include "espressif/spi_flash.h" -#include "FreeRTOS.h" -#include "esp/rom.h" -#include "esp/spi_regs.h" +#include "include/spiflash.h" + +#include "include/flashchip.h" +#include "include/esp/rom.h" +#include "include/esp/spi_regs.h" + +#include #include /** @@ -52,25 +53,6 @@ #define SPI_READ_MAX_SIZE 60 -/** - * Copy unaligned data to 4-byte aligned destination buffer. - * - * @param words Number of 4-byte words to write. - * - * @see unaligned_memcpy.S - */ -void memcpy_unaligned_src(volatile uint32_t *dst, uint8_t *src, uint8_t words); - -/** - * Copy 4-byte aligned source data to unaligned destination buffer. - * - * @param bytes Number of byte to copy to dst. - * - * @see unaligned_memcpy.S - */ -void memcpy_unaligned_dst(uint8_t *dst, volatile uint32_t *src, uint8_t bytes); - - /** * Low level SPI flash write. Write block of data up to 64 bytes. */ @@ -86,7 +68,9 @@ static inline void IRAM spi_write_data(sdk_flashchip_t *chip, uint32_t addr, SPI(0).ADDR = (addr & 0x00FFFFFF) | (size << 24); - memcpy_unaligned_src(SPI(0).W, buf, words); + memcpy((void*)SPI(0).W, buf, words<<2); + + __asm__ volatile("memw"); SPI_write_enable(chip); @@ -97,16 +81,16 @@ static inline void IRAM spi_write_data(sdk_flashchip_t *chip, uint32_t addr, /** * Write a page of flash. Data block should not cross page boundary. */ -static uint32_t IRAM spi_write_page(sdk_flashchip_t *flashchip, uint32_t dest_addr, +static bool IRAM spi_write_page(sdk_flashchip_t *flashchip, uint32_t dest_addr, uint8_t *buf, uint32_t size) { // check if block to write doesn't cross page boundary if (flashchip->page_size < size + (dest_addr % flashchip->page_size)) { - return ESP_SPIFFS_FLASH_ERROR; + return false; } if (size < 1) { - return ESP_SPIFFS_FLASH_OK; + return true; } while (size >= SPI_WRITE_MAX_SIZE) { @@ -117,58 +101,58 @@ static uint32_t IRAM spi_write_page(sdk_flashchip_t *flashchip, uint32_t dest_ad buf += SPI_WRITE_MAX_SIZE; if (size < 1) { - return ESP_SPIFFS_FLASH_OK; + return true; } } spi_write_data(flashchip, dest_addr, buf, size); - return ESP_SPIFFS_FLASH_OK; + return true; } /** * Split block of data into pages and write pages. */ -static uint32_t IRAM spi_write(uint32_t addr, uint8_t *dst, uint32_t size) +static bool IRAM spi_write(uint32_t addr, uint8_t *dst, uint32_t size) { if (sdk_flashchip.chip_size < (addr + size)) { - return ESP_SPIFFS_FLASH_ERROR; + return false; } uint32_t write_bytes_to_page = sdk_flashchip.page_size - (addr % sdk_flashchip.page_size); // TODO: place for optimization if (size < write_bytes_to_page) { - if (spi_write_page(&sdk_flashchip, addr, dst, size)) { - return ESP_SPIFFS_FLASH_ERROR; + if (!spi_write_page(&sdk_flashchip, addr, dst, size)) { + return false; } } else { - if (spi_write_page(&sdk_flashchip, addr, dst, write_bytes_to_page)) { - return ESP_SPIFFS_FLASH_ERROR; + if (!spi_write_page(&sdk_flashchip, addr, dst, write_bytes_to_page)) { + return false; } uint32_t offset = write_bytes_to_page; uint32_t pages_to_write = (size - offset) / sdk_flashchip.page_size; for (uint8_t i = 0; i != pages_to_write; i++) { - if (spi_write_page(&sdk_flashchip, addr + offset, + if (!spi_write_page(&sdk_flashchip, addr + offset, dst + offset, sdk_flashchip.page_size)) { - return ESP_SPIFFS_FLASH_ERROR; + return false; } offset += sdk_flashchip.page_size; } - if (spi_write_page(&sdk_flashchip, addr + offset, + if (!spi_write_page(&sdk_flashchip, addr + offset, dst + offset, size - offset)) { - return ESP_SPIFFS_FLASH_ERROR; + return false; } } - return ESP_SPIFFS_FLASH_OK; + return true; } -uint32_t IRAM esp_spiffs_flash_write(uint32_t addr, uint8_t *buf, uint32_t size) +bool IRAM spiflash_write(uint32_t addr, uint8_t *buf, uint32_t size) { - uint32_t result = ESP_SPIFFS_FLASH_ERROR; + bool result = false; if (buf) { vPortEnterCritical(); @@ -197,21 +181,23 @@ static inline void IRAM read_block(sdk_flashchip_t *chip, uint32_t addr, while (SPI(0).CMD) {}; - memcpy_unaligned_dst(buf, SPI(0).W, size); + __asm__ volatile("memw"); + + memcpy(buf, (const void*)SPI(0).W, size); } /** * Read SPI flash data. Data region doesn't need to be page aligned. */ -static inline uint32_t IRAM read_data(sdk_flashchip_t *flashchip, uint32_t addr, +static inline bool IRAM read_data(sdk_flashchip_t *flashchip, uint32_t addr, uint8_t *dst, uint32_t size) { if (size < 1) { - return ESP_SPIFFS_FLASH_OK; + return true; } if ((addr + size) > flashchip->chip_size) { - return ESP_SPIFFS_FLASH_ERROR; + return false; } while (size >= SPI_READ_MAX_SIZE) { @@ -225,12 +211,12 @@ static inline uint32_t IRAM read_data(sdk_flashchip_t *flashchip, uint32_t addr, read_block(flashchip, addr, dst, size); } - return ESP_SPIFFS_FLASH_OK; + return true; } -uint32_t IRAM esp_spiffs_flash_read(uint32_t dest_addr, uint8_t *buf, uint32_t size) +bool IRAM spiflash_read(uint32_t dest_addr, uint8_t *buf, uint32_t size) { - uint32_t result = ESP_SPIFFS_FLASH_ERROR; + bool result = false; if (buf) { vPortEnterCritical(); @@ -245,14 +231,14 @@ uint32_t IRAM esp_spiffs_flash_read(uint32_t dest_addr, uint8_t *buf, uint32_t s return result; } -uint32_t IRAM esp_spiffs_flash_erase_sector(uint32_t addr) +bool IRAM spiflash_erase_sector(uint32_t addr) { if ((addr + sdk_flashchip.sector_size) > sdk_flashchip.chip_size) { - return ESP_SPIFFS_FLASH_ERROR; + return false; } if (addr & 0xFFF) { - return ESP_SPIFFS_FLASH_ERROR; + return false; } vPortEnterCritical(); @@ -269,5 +255,5 @@ uint32_t IRAM esp_spiffs_flash_erase_sector(uint32_t addr) Cache_Read_Enable(0, 0, 1); vPortExitCritical(); - return ESP_SPIFFS_FLASH_OK; + return true; } diff --git a/core/sysparam.c b/core/sysparam.c index 6cade4a..9bbc59c 100644 --- a/core/sysparam.c +++ b/core/sysparam.c @@ -8,7 +8,8 @@ #include #include #include -#include +#include "spiflash.h" +#include "flashchip.h" #include #include "FreeRTOS.h" #include "semphr.h" @@ -83,7 +84,9 @@ #define debug(level, format, ...) if (SYSPARAM_DEBUG >= (level)) { printf("%s" format "\n", "sysparam: ", ## __VA_ARGS__); } -#define CHECK_FLASH_OP(x) do { int __x = (x); if ((__x) != SPI_FLASH_RESULT_OK) { debug(1, "FLASH ERR: %d", __x); return SYSPARAM_ERR_IO; } } while (0); +#define CHECK_FLASH_OP(x) do { bool __x = (x); if (!(__x)) { \ + debug(1, "FLASH ERR: %d", __x); return SYSPARAM_ERR_IO; \ + } } while (0); /********************* Internal datatypes and structures *********************/ @@ -120,36 +123,13 @@ static struct { /***************************** Internal routines *****************************/ static sysparam_status_t _write_and_verify(uint32_t addr, const void *data, size_t data_size) { - int i; - uint32_t bounce[BOUNCE_BUFFER_WORDS]; + static uint8_t bounce[BOUNCE_BUFFER_SIZE]; - // The flash write can not cross a flash page boundary, the source needs to - // be word align, so an initial alignment write is performed if necessary. - int align = addr & 3; - if (align) { - size_t count = min(data_size, 4 - align); - // Pad the word with ones, write a word. - bounce[0] = 0xffffffff; - memcpy(((void *)bounce) + align, data, count); - CHECK_FLASH_OP(sdk_spi_flash_write(addr & ~3, bounce, 4)); - CHECK_FLASH_OP(sdk_spi_flash_read(addr & ~3, bounce, 4)); - if (memcmp(((void *)bounce) + align, data, count) != 0) { - debug(1, "Flash write (@ 0x%08x) verify failed!", addr); - return SYSPARAM_ERR_IO; - } - addr += count; - data += count; - data_size -= count; - } - - for (i = 0; i < data_size; i += BOUNCE_BUFFER_SIZE) { + for (int i = 0; i < data_size; i += BOUNCE_BUFFER_SIZE) { size_t count = min(data_size - i, BOUNCE_BUFFER_SIZE); - // Pad the last word write ones, write words. - bounce[(count - 1) >> 2] = 0xffffffff; memcpy(bounce, data + i, count); - size_t word_count = (count + 3) & ~3; - CHECK_FLASH_OP(sdk_spi_flash_write(addr + i, bounce, word_count)); - CHECK_FLASH_OP(sdk_spi_flash_read(addr + i, bounce, word_count)); + CHECK_FLASH_OP(spiflash_write(addr + i, bounce, count)); + CHECK_FLASH_OP(spiflash_read(addr + i, bounce, count)); if (memcmp(data + i, bounce, count) != 0) { debug(1, "Flash write (@ 0x%08x) verify failed!", addr); return SYSPARAM_ERR_IO; @@ -160,11 +140,10 @@ static sysparam_status_t _write_and_verify(uint32_t addr, const void *data, size /** Erase the sectors of a region */ static sysparam_status_t _format_region(uint32_t addr, uint16_t num_sectors) { - uint16_t sector = addr / sdk_flashchip.sector_size; int i; for (i = 0; i < num_sectors; i++) { - CHECK_FLASH_OP(sdk_spi_flash_erase_sector(sector + i)); + CHECK_FLASH_OP(spiflash_erase_sector(addr + (i * SPI_FLASH_SECTOR_SIZE))); } return SYSPARAM_OK; } @@ -214,7 +193,7 @@ static sysparam_status_t init_write_context(struct sysparam_context *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->addr = _sysparam_info.end_addr; debug(3, "read entry header @ 0x%08x", ctx->addr); - CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr, (void*) &ctx->entry, ENTRY_HEADER_SIZE)); + CHECK_FLASH_OP(spiflash_read(ctx->addr, (void*) &ctx->entry, ENTRY_HEADER_SIZE)); return SYSPARAM_OK; } @@ -240,7 +219,10 @@ static sysparam_status_t _find_entry(struct sysparam_context *ctx, uint16_t matc // workaround is to make sure that the next write operation // will always start with a compaction, which will leave off // the invalid data at the end and fix the issue going forward. - debug(1, "Encountered entry with invalid length (0x%04x) @ 0x%08x (region end is 0x%08x). Truncating entries.", ctx->entry.len, ctx->addr, _sysparam_info.end_addr); + debug(1, "Encountered entry with invalid length (0x%04x) @ 0x%08x (region end is 0x%08x). Truncating entries.", + ctx->entry.len, + ctx->addr, _sysparam_info.end_addr); + _sysparam_info.force_compact = true; break; } @@ -253,7 +235,7 @@ static sysparam_status_t _find_entry(struct sysparam_context *ctx, uint16_t matc } debug(3, "read entry header @ 0x%08x", ctx->addr); - CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr, (void*) &ctx->entry, ENTRY_HEADER_SIZE)); + CHECK_FLASH_OP(spiflash_read(ctx->addr, (void*) &ctx->entry, ENTRY_HEADER_SIZE)); debug(3, " idflags = 0x%04x", ctx->entry.idflags); if (ctx->entry.idflags == 0xffff) { // 0xffff is never a valid id field, so this means we've hit the @@ -299,18 +281,11 @@ static sysparam_status_t _find_entry(struct sysparam_context *ctx, uint16_t matc /** Read the payload from the current entry pointed to by `ctx` */ static inline sysparam_status_t _read_payload(struct sysparam_context *ctx, uint8_t *buffer, size_t buffer_size) { - int i; uint32_t addr = ctx->addr + ENTRY_HEADER_SIZE; size_t size = min(buffer_size, ctx->entry.len); - uint32_t bounce[BOUNCE_BUFFER_WORDS]; debug(3, "read payload (%d) @ 0x%08x", size, addr); - for (i = 0; i < size; i += BOUNCE_BUFFER_SIZE) { - size_t count = min(size - i, BOUNCE_BUFFER_SIZE); - size_t word_count = (count + 3) & ~3; - CHECK_FLASH_OP(sdk_spi_flash_read(addr + i, bounce, word_count)); - memcpy(buffer + i, bounce, count); - } + CHECK_FLASH_OP(spiflash_read(addr, buffer, buffer_size)); return SYSPARAM_OK; } @@ -323,7 +298,7 @@ static inline sysparam_status_t _compare_payload(struct sysparam_context *ctx, u int i; for (i = 0; i < size; i += BOUNCE_BUFFER_SIZE) { int len = min(size - i, BOUNCE_BUFFER_SIZE); - CHECK_FLASH_OP(sdk_spi_flash_read(addr + i, (void*)bounce, len)); + CHECK_FLASH_OP(spiflash_read(addr + i, (void*)bounce, len)); if (memcmp(value + i, bounce, len)) { // Mismatch. return SYSPARAM_NOTFOUND; @@ -425,7 +400,7 @@ static inline sysparam_status_t _delete_entry(uint32_t addr) { debug(2, "Deleting entry @ 0x%08x", addr); debug(3, "read entry header @ 0x%08x", addr); - CHECK_FLASH_OP(sdk_spi_flash_read(addr, (void*) &entry, ENTRY_HEADER_SIZE)); + CHECK_FLASH_OP(spiflash_read(addr, (uint8_t*) &entry, ENTRY_HEADER_SIZE)); // Set the ID to zero to mark it as "deleted" entry.idflags &= ~ENTRY_FLAG_ALIVE; debug(3, "write entry header @ 0x%08x", addr); @@ -453,7 +428,11 @@ static sysparam_status_t _compact_params(struct sysparam_context *ctx, int *key_ uint16_t binary_flag; uint16_t num_sectors = _sysparam_info.region_size / sdk_flashchip.sector_size; - debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", _sysparam_info.end_addr - _sysparam_info.cur_base, ctx ? ctx->compactable : 0, (ctx && ctx->unused_keys > 0) ? "+ (unused keys present)" : ""); + debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", + _sysparam_info.end_addr - _sysparam_info.cur_base, + ctx ? ctx->compactable : 0, + (ctx && ctx->unused_keys > 0) ? "+ (unused keys present)" : ""); + status = _format_region(new_base, num_sectors); if (status < 0) return status; status = sysparam_iter_start(&iter); @@ -534,7 +513,7 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) { top_addr = base_addr + sdk_flashchip.sector_size; } for (addr0 = base_addr; addr0 < top_addr; addr0 += sdk_flashchip.sector_size) { - CHECK_FLASH_OP(sdk_spi_flash_read(addr0, (void*) &header0, REGION_HEADER_SIZE)); + CHECK_FLASH_OP(spiflash_read(addr0, (void*) &header0, REGION_HEADER_SIZE)); if (header0.magic == SYSPARAM_MAGIC) { // Found a starting point... break; @@ -552,7 +531,7 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) { } else { addr1 = addr0 + num_sectors * sdk_flashchip.sector_size; } - CHECK_FLASH_OP(sdk_spi_flash_read(addr1, (void*) &header1, REGION_HEADER_SIZE)); + CHECK_FLASH_OP(spiflash_read(addr1, (uint8_t*) &header1, REGION_HEADER_SIZE)); if (header1.magic == SYSPARAM_MAGIC) { // Yay! Found the other one. Sanity-check it.. @@ -629,7 +608,7 @@ sysparam_status_t sysparam_create_area(uint32_t base_addr, uint16_t num_sectors, // we're not going to be clobbering something else important. for (addr = base_addr; addr < base_addr + region_size * 2; addr += SCAN_BUFFER_SIZE) { debug(3, "read %d words @ 0x%08x", SCAN_BUFFER_SIZE, addr); - CHECK_FLASH_OP(sdk_spi_flash_read(addr, buffer, SCAN_BUFFER_SIZE * 4)); + CHECK_FLASH_OP(spiflash_read(addr, (uint8_t*)buffer, SCAN_BUFFER_SIZE * 4)); for (i = 0; i < SCAN_BUFFER_SIZE; i++) { if (buffer[i] != 0xffffffff) { // Uh oh, not empty. diff --git a/extras/spiffs/esp_spiffs.c b/extras/spiffs/esp_spiffs.c index 96ec743..677d6a5 100644 --- a/extras/spiffs/esp_spiffs.c +++ b/extras/spiffs/esp_spiffs.c @@ -7,11 +7,10 @@ */ #include "esp_spiffs.h" #include "spiffs.h" -#include +#include #include #include #include -#include "esp_spiffs_flash.h" spiffs fs; @@ -34,7 +33,7 @@ static fs_buf_t cache_buf = {0}; static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst) { - if (esp_spiffs_flash_read(addr, dst, size) == ESP_SPIFFS_FLASH_ERROR) { + if (!spiflash_read(addr, dst, size)) { return SPIFFS_ERR_INTERNAL; } @@ -43,7 +42,7 @@ static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst) static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) { - if (esp_spiffs_flash_write(addr, src, size) == ESP_SPIFFS_FLASH_ERROR) { + if (!spiflash_write(addr, src, size)) { return SPIFFS_ERR_INTERNAL; } @@ -52,11 +51,10 @@ static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) static s32_t esp_spiffs_erase(u32_t addr, u32_t size) { - uint32_t sectors = size / SPI_FLASH_SEC_SIZE; + uint32_t sectors = size / SPI_FLASH_SECTOR_SIZE; for (uint32_t i = 0; i < sectors; i++) { - if (esp_spiffs_flash_erase_sector(addr + (SPI_FLASH_SEC_SIZE * i)) - == ESP_SPIFFS_FLASH_ERROR) { + if (!spiflash_erase_sector(addr + (SPI_FLASH_SECTOR_SIZE * i))) { return SPIFFS_ERR_INTERNAL; } } diff --git a/extras/spiffs/unaligned_memcpy.S b/extras/spiffs/unaligned_memcpy.S deleted file mode 100644 index b96c92c..0000000 --- a/extras/spiffs/unaligned_memcpy.S +++ /dev/null @@ -1,112 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2016 sheinz (https://github.com/sheinz) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - .text - .section .iram1.text, "x" - .literal_position - -/** - * Copy unaligned data to 4-byte aligned buffer. - */ - .align 4 - .global memcpy_unaligned_src - .type memcpy_unaligned_src, @function -memcpy_unaligned_src: -/* a2: dst, a3: src, a4: size */ - ssa8l a3 - srli a3, a3, 2 - slli a3, a3, 2 - beqz a4, u_src_end - l32i a6, a3, 0 -u_src_loop: - l32i a7, a3, 4 - src a8, a7, a6 - memw - s32i a8, a2, 0 - mov a6, a7 - addi a3, a3, 4 - addi a2, a2, 4 - addi a4, a4, -1 - bnez a4, u_src_loop -u_src_end: - movi a2, 0 - ret.n - - -/** - * Copy data from 4-byte aligned source to unaligned destination buffer. - */ - .align 4 - .global memcpy_unaligned_dst - .type memcpy_unaligned_dst, @function -memcpy_unaligned_dst: -/* a2: dst, a3: src, a4: size */ - beqz.n a4, u_dst_end - extui a5, a4, 0, 2 - beqz.n a5, aligned_dst_loop -u_dst_loop: - /* Load data word */ - memw - l32i.n a5, a3, 0 - - /* Save byte number 0 */ - s8i a5, a2, 0 - addi.n a4, a4, -1 - beqz a4, u_dst_end - addi.n a2, a2, 1 - - /* Shift and save byte number 1 */ - srli a5, a5, 8 - s8i a5, a2, 0 - addi.n a4, a4, -1 - beqz a4, u_dst_end - addi.n a2, a2, 1 - - /* Shift and save byte number 2 */ - srli a5, a5, 8 - s8i a5, a2, 0 - addi.n a4, a4, -1 - beqz a4, u_dst_end - addi.n a2, a2, 1 - - /* Shift and save byte number 3 */ - srli a5, a5, 8 - s8i a5, a2, 0 - addi.n a4, a4, -1 - addi.n a2, a2, 1 - - /* Next word */ - addi.n a3, a3, 4 - bnez.n a4, u_dst_loop - ret.n -aligned_dst_loop: - memw - l32i a5, a3, 0 - s32i a5, a2, 0 - addi.n a3, a3, 4 - addi.n a2, a2, 4 - addi.n a4, a4, -4 - bnez.n a4, aligned_dst_loop -u_dst_end: ret.n - diff --git a/include/espressif/spi_flash.h b/include/espressif/spi_flash.h index 61f8ae9..1c6a3b1 100644 --- a/include/espressif/spi_flash.h +++ b/include/espressif/spi_flash.h @@ -1,6 +1,6 @@ -/* +/* * copyright (c) Espressif System 2010 - * + * */ #ifndef __SPI_FLASH_H__ @@ -46,12 +46,6 @@ sdk_SpiFlashOpResult sdk_spi_flash_write(uint32_t des_addr, uint32_t *src, uint3 */ sdk_SpiFlashOpResult sdk_spi_flash_read(uint32_t src_addr, uint32_t *des, uint32_t size); -/* SDK uses this structure internally to account for flash size. - - See flashchip.h for more info. -*/ -extern sdk_flashchip_t sdk_flashchip; - #ifdef __cplusplus } #endif diff --git a/tests/cases/07_sysparam.c b/tests/cases/07_sysparam.c index dbc4301..c1a4697 100644 --- a/tests/cases/07_sysparam.c +++ b/tests/cases/07_sysparam.c @@ -252,7 +252,7 @@ static void clear_test_values(test_data_t *data) } -static void test_task(void *pvParameters) +static void a_07_sysparam_load_test(void) { test_data_t test_data; init_sysparam(); @@ -276,11 +276,6 @@ static void test_task(void *pvParameters) TEST_PASS(); } -static void a_07_sysparam_load_test(void) -{ - xTaskCreate(test_task, "test_task", 256, NULL, 2, NULL); -} - static void a_07_sysparam_basic_test(void) { sysparam_status_t status; diff --git a/tests/cases/08_spiflash.c b/tests/cases/08_spiflash.c new file mode 100644 index 0000000..67b2783 --- /dev/null +++ b/tests/cases/08_spiflash.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +DEFINE_SOLO_TESTCASE(08_spiflash_unaligned) + +/** + * Test unaligned access to spi flash. + */ +static void a_08_spiflash_unaligned(void) +{ + const int test_addr = 0x100000 - (4096 * 8); + const char test_str[] = "test_string"; + const int buf_size = 256; + uint8_t buf[buf_size]; + + TEST_ASSERT_TRUE(spiflash_erase_sector(test_addr)); + TEST_ASSERT_TRUE(spiflash_erase_sector(test_addr + 4096)); + + TEST_ASSERT_TRUE( + spiflash_write(test_addr, (uint8_t*)test_str, sizeof(test_str))); + + TEST_ASSERT_TRUE(spiflash_read(test_addr, buf, buf_size)); + + TEST_ASSERT_EQUAL_STRING(test_str, buf); + + TEST_ASSERT_TRUE( + spiflash_write(test_addr + 31, (uint8_t*)test_str, sizeof(test_str))); + TEST_ASSERT_TRUE(spiflash_read(test_addr + 31, buf, buf_size)); + TEST_ASSERT_EQUAL_STRING(test_str, buf); + + TEST_ASSERT_TRUE( + spiflash_write(test_addr + 101, (uint8_t*)test_str, sizeof(test_str))); + TEST_ASSERT_TRUE(spiflash_read(test_addr + 101, buf + 1, buf_size - 1)); + TEST_ASSERT_EQUAL_STRING(test_str, buf + 1); + + TEST_ASSERT_TRUE( + spiflash_write(test_addr + 201, (uint8_t*)test_str + 1, sizeof(test_str) - 1)); + TEST_ASSERT_TRUE(spiflash_read(test_addr + 201, buf + 1, buf_size - 1)); + TEST_ASSERT_EQUAL_STRING(test_str + 1, buf + 1); + + TEST_PASS(); +}