From 26053c0a94e1dd9ca60fc7dcefdd82a4d74db02d Mon Sep 17 00:00:00 2001 From: armink Date: Sun, 28 Aug 2016 22:49:07 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E3=80=90=E6=9B=B4=E6=96=B0=E3=80=91?= =?UTF-8?q?=E5=A4=96=E9=83=A8=20SPI=20Flash=20Demo=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=20SFUD=20=E5=BA=93=E8=87=B3=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: armink --- .../components/sfud/inc/sfud.h | 9 + .../components/sfud/inc/sfud_def.h | 4 +- .../components/sfud/src/sfud.c | 884 ------------------ .../components/sfud/src/sfud_sfdp.c | 371 -------- 4 files changed, 11 insertions(+), 1257 deletions(-) delete mode 100644 demo/env/stm32f10x/non_os_spi_flash/components/sfud/src/sfud.c delete mode 100644 demo/env/stm32f10x/non_os_spi_flash/components/sfud/src/sfud_sfdp.c diff --git a/demo/env/stm32f10x/non_os_spi_flash/components/sfud/inc/sfud.h b/demo/env/stm32f10x/non_os_spi_flash/components/sfud/inc/sfud.h index 4bc5f59..ed4932d 100644 --- a/demo/env/stm32f10x/non_os_spi_flash/components/sfud/inc/sfud.h +++ b/demo/env/stm32f10x/non_os_spi_flash/components/sfud/inc/sfud.h @@ -106,6 +106,15 @@ sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const u */ sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data); +/** + * erase all flash data + * + * @param flash flash device + * + * @return result + */ +sfud_err sfud_chip_erase(const sfud_flash *flash); + /** * read flash register status * diff --git a/demo/env/stm32f10x/non_os_spi_flash/components/sfud/inc/sfud_def.h b/demo/env/stm32f10x/non_os_spi_flash/components/sfud/inc/sfud_def.h index 14c081e..343554c 100644 --- a/demo/env/stm32f10x/non_os_spi_flash/components/sfud/inc/sfud_def.h +++ b/demo/env/stm32f10x/non_os_spi_flash/components/sfud/inc/sfud_def.h @@ -53,7 +53,7 @@ extern "C" { #define SFUD_ASSERT(EXPR) \ if (!(EXPR)) \ { \ - SFUD_DEBUG("(%s) has assert failed at %s.\n", #EXPR, __FUNCTION__); \ + SFUD_DEBUG("(%s) has assert failed at %s.", #EXPR, __FUNCTION__); \ while (1); \ } #else @@ -73,7 +73,7 @@ if (!(EXPR)) \ else {if (__delay_temp) {__delay_temp();} retry --;} /* software version number */ -#define SFUD_SW_VERSION "0.07.13" +#define SFUD_SW_VERSION "0.08.25" /* * all defined supported command */ diff --git a/demo/env/stm32f10x/non_os_spi_flash/components/sfud/src/sfud.c b/demo/env/stm32f10x/non_os_spi_flash/components/sfud/src/sfud.c deleted file mode 100644 index 8e85e16..0000000 --- a/demo/env/stm32f10x/non_os_spi_flash/components/sfud/src/sfud.c +++ /dev/null @@ -1,884 +0,0 @@ -/* - * This file is part of the Serial Flash Universal Driver Library. - * - * Copyright (c) 2016, Armink, - * - * 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. - * - * Function: serial flash operate functions by SFUD lib. - * Created on: 2016-04-23 - */ - -#include "../inc/sfud.h" -#include - -/* send dummy data for read data */ -#define DUMMY_DATA 0xFF - -#ifndef SFUD_FLASH_DEVICE_TABLE -#error "Please configure the flash device information table in (in sfud_cfg.h)." -#endif - -#if !defined(SFUD_USING_SFDP) && !defined(SFUD_USING_FLASH_INFO_TABLE) -#error "Please configure SFUD_USING_SFDP or SFUD_USING_FLASH_INFO_TABLE at least one kind of mode (in sfud_cfg.h)." -#endif - -/* user configured flash device information table */ -static sfud_flash flash_table[] = SFUD_FLASH_DEVICE_TABLE; -/* supported manufacturer information table */ -static const sfud_mf mf_table[] = SFUD_MF_TABLE; - -#ifdef SFUD_USING_FLASH_INFO_TABLE -/* supported flash chip information table */ -static const sfud_flash_chip flash_chip_table[] = SFUD_FLASH_CHIP_TABLE; -#endif - -static sfud_err software_init(const sfud_flash *flash); -static sfud_err hardware_init(sfud_flash *flash); -static sfud_err chip_erase(const sfud_flash *flash); -static sfud_err page256_or_1_byte_write(const sfud_flash *flash, uint32_t addr, size_t size, uint16_t write_gran, - const uint8_t *data); -static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data); -static sfud_err wait_busy(const sfud_flash *flash); -static sfud_err reset(const sfud_flash *flash); -static sfud_err read_jedec_id(sfud_flash *flash); -static sfud_err set_write_enabled(const sfud_flash *flash, bool enabled); -static sfud_err set_4_byte_address_mode(sfud_flash *flash, bool enabled); -static void make_adress_byte_array(const sfud_flash *flash, uint32_t addr, uint8_t *array); - -/* ../port/sfup_port.c */ -extern void sfud_log_debug(const char *file, const long line, const char *format, ...); -extern void sfud_log_info(const char *format, ...); - -/** - * SFUD library initialize. - * - * @return result - */ -sfud_err sfud_init(void) { - sfud_err cur_flash_result = SFUD_SUCCESS, all_flash_result = SFUD_SUCCESS; - sfud_flash *flash; - - SFUD_DEBUG("Start initialize Serial Flash Universal Driver(SFUD) V%s.", SFUD_SW_VERSION); - /* initialize all flash device in flash device table */ - for (size_t i = 0; i < sizeof(flash_table) / sizeof(sfud_flash); i++) { - cur_flash_result = SFUD_SUCCESS; - flash = &flash_table[i]; - /* initialize flash device index of flash device information table */ - flash->index = i; - /* hardware initialize */ - cur_flash_result = hardware_init(flash); - if (cur_flash_result == SFUD_SUCCESS) { - cur_flash_result = software_init(flash); - } - if (cur_flash_result == SFUD_SUCCESS) { - flash->init_ok = true; - SFUD_INFO("%s flash device is initialize success.", flash->name); - } else { - all_flash_result = cur_flash_result; - flash->init_ok = false; - SFUD_INFO("Error: %s flash device is initialize fail.", flash->name); - } - } - - return all_flash_result; -} - -/** - * get flash device total number on flash device information table @see flash_table - * - * @return flash device total number - */ -size_t sfud_get_device_num(void) { - return sizeof(flash_table) / sizeof(sfud_flash); -} - -/** - * get flash device information table @see flash_table - * - * @return flash device table pointer - */ -const sfud_flash *sfud_get_device_table(void) { - return flash_table; -} - -/** - * hardware initialize - */ -static sfud_err hardware_init(sfud_flash *flash) { - extern sfud_err sfud_spi_port_init(sfud_flash *flash); - - sfud_err result = SFUD_SUCCESS; - - SFUD_ASSERT(flash); - - result = sfud_spi_port_init(flash); - if (result != SFUD_SUCCESS) { - return result; - } - - /* SPI write read function must be initialize */ - SFUD_ASSERT(flash->spi.wr); - /* if the user don't configure flash chip information then using SFDP parameter or static flash parameter table */ - if (flash->chip.capacity == 0 || flash->chip.write_mode == 0 || flash->chip.erase_gran == 0 - || flash->chip.erase_gran_cmd == 0) { - /* read JEDEC ID include manufacturer ID, memory type ID and flash capacity ID */ - result = read_jedec_id(flash); - if (result != SFUD_SUCCESS) { - return result; - } - -#ifdef SFUD_USING_SFDP - extern bool sfud_read_sfdp(sfud_flash *flash); - /* read SFDP parameters */ - if (sfud_read_sfdp(flash)) { - flash->chip.name = NULL; - flash->chip.capacity = flash->sfdp.capacity; - /* only 1 byte or 256 bytes write mode for SFDP */ - if (flash->sfdp.write_gran == 1) { - flash->chip.write_mode = SFUD_WM_BYTE; - } else { - flash->chip.write_mode = SFUD_WM_PAGE_256B; - } - /* find the the smallest erase sector size for eraser. then will use this size for erase granularity */ - flash->chip.erase_gran = flash->sfdp.eraser[0].size; - flash->chip.erase_gran_cmd = flash->sfdp.eraser[0].cmd; - for (size_t i = 1; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) { - if (flash->sfdp.eraser[i].size != 0 && flash->chip.erase_gran > flash->sfdp.eraser[i].size) { - flash->chip.erase_gran = flash->sfdp.eraser[i].size; - flash->chip.erase_gran_cmd = flash->sfdp.eraser[i].cmd; - } - } - } else { -#endif - -#ifdef SFUD_USING_FLASH_INFO_TABLE - /* read SFDP parameters failed then using SFUD library provided static parameter */ - for (size_t i = 0; i < sizeof(flash_chip_table) / sizeof(sfud_flash_chip); i++) { - if ((flash_chip_table[i].mf_id == flash->chip.mf_id) - && (flash_chip_table[i].type_id == flash->chip.type_id) - && (flash_chip_table[i].capacity_id == flash->chip.capacity_id)) { - flash->chip.name = flash_chip_table[i].name; - flash->chip.capacity = flash_chip_table[i].capacity; - flash->chip.write_mode = flash_chip_table[i].write_mode; - flash->chip.erase_gran = flash_chip_table[i].erase_gran; - flash->chip.erase_gran_cmd = flash_chip_table[i].erase_gran_cmd; - break; - } - } -#endif - -#ifdef SFUD_USING_SFDP - } -#endif - - } - - if (flash->chip.capacity == 0 || flash->chip.write_mode == 0 || flash->chip.erase_gran == 0 - || flash->chip.erase_gran_cmd == 0) { - SFUD_INFO("Warning: This flash device is not found or not support."); - return SFUD_ERR_NOT_FOUND; - } else { - const char *flash_mf_name = NULL; - /* find the manufacturer information */ - for (size_t i = 0; i < sizeof(mf_table) / sizeof(sfud_mf); i++) { - if (mf_table[i].id == flash->chip.mf_id) { - flash_mf_name = mf_table[i].name; - break; - } - } - /* print manufacturer and flash chip name */ - if (flash_mf_name && flash->chip.name) { - SFUD_INFO("Find a %s %s flash chip. Size is %ld bytes.", flash_mf_name, flash->chip.name, - flash->chip.capacity); - } else if (flash_mf_name) { - SFUD_INFO("Find a %s flash chip. Size is %ld bytes.", flash_mf_name, flash->chip.capacity); - } - } - - /* reset flash device */ - result = reset(flash); - if (result != SFUD_SUCCESS) { - return result; - } - - /* I found when the flash read mode is supported AAI mode. The flash all blocks is protected, - * so need change the flash status to unprotected before write and erase operate. */ - if (flash->chip.write_mode & SFUD_WM_AAI) { - result = sfud_write_status(flash, true, 0x00); - if (result != SFUD_SUCCESS) { - return result; - } - } - - /* if the flash is large than 16MB (256Mb) then enter in 4-Byte addressing mode */ - if (flash->chip.capacity > (1 << 24)) { - result = set_4_byte_address_mode(flash, true); - } else { - flash->addr_in_4_byte = false; - } - - return result; -} - -/** - * software initialize - * - * @param flash flash device - * - * @return result - */ -static sfud_err software_init(const sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - - SFUD_ASSERT(flash); - - return result; -} - -/** - * read flash data - * - * @param flash flash device - * @param addr start address - * @param size read size - * @param data read data pointer - * - * @return result - */ -sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[5], cmd_size; - - SFUD_ASSERT(flash); - SFUD_ASSERT(data); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* check the flash address bound */ - if (addr + size > flash->chip.capacity) { - SFUD_INFO("Error: Flash address is out of bound."); - return SFUD_ERR_ADDR_OUT_OF_BOUND; - } - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - result = wait_busy(flash); - - if (result == SFUD_SUCCESS) { - cmd_data[0] = SFUD_CMD_READ_DATA; - make_adress_byte_array(flash, addr, &cmd_data[1]); - cmd_size = flash->addr_in_4_byte ? 5 : 4; - result = spi->wr(spi, cmd_data, cmd_size, data, size); - } - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - - -/** - * erase all flash data - * - * @param flash flash device - * - * @return result - */ -static sfud_err chip_erase(const sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[4]; - - SFUD_ASSERT(flash); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - goto exit; - } - - cmd_data[0] = SFUD_CMD_ERASE_CHIP; - /* dual-buffer write, like AT45DB series flash chip erase operate is different for other flash */ - if (flash->chip.write_mode & SFUD_WM_DUAL_BUFFER) { - cmd_data[1] = 0x94; - cmd_data[2] = 0x80; - cmd_data[3] = 0x9A; - result = spi->wr(spi, cmd_data, 4, NULL, 0); - } else { - result = spi->wr(spi, cmd_data, 1, NULL, 0); - } - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Flash chip erase SPI communicate error."); - goto exit; - } - result = wait_busy(flash); - - exit: - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * erase flash data - * - * @note It will erase align by erase granularity. - * - * @param flash flash device - * @param addr start address - * @param size erase size - * - * @return result - */ -sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size) { - extern size_t sfud_sfdp_get_suitable_eraser(const sfud_flash *flash, size_t erase_size); - - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[5], cmd_size, cur_erase_cmd; - size_t eraser_index, cur_erase_size; - - SFUD_ASSERT(flash); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* check the flash address bound */ - if (addr + size > flash->chip.capacity) { - SFUD_INFO("Error: Flash address is out of bound."); - return SFUD_ERR_ADDR_OUT_OF_BOUND; - } - - if (addr == 0 && size == flash->chip.capacity) { - return chip_erase(flash); - } - - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - /* loop erase operate. erase unit is erase granularity */ - while (size) { - /* if this flash is support SFDP parameter, then used SFDP parameter supplies eraser */ -#ifdef SFUD_USING_SFDP - if (flash->sfdp.available) { - /* get the suitable eraser for erase process from SFDP parameter */ - eraser_index = sfud_sfdp_get_suitable_eraser(flash, size); - cur_erase_cmd = flash->sfdp.eraser[eraser_index].cmd; - cur_erase_size = flash->sfdp.eraser[eraser_index].size; - } else { -#else - { -#endif - cur_erase_cmd = flash->chip.erase_gran_cmd; - cur_erase_size = flash->chip.erase_gran; - } - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - break; - } - - cmd_data[0] = cur_erase_cmd; - make_adress_byte_array(flash, addr, &cmd_data[1]); - cmd_size = flash->addr_in_4_byte ? 5 : 4; - result = spi->wr(spi, cmd_data, cmd_size, NULL, 0); - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Flash erase SPI communicate error."); - break; - } - result = wait_busy(flash); - if (result != SFUD_SUCCESS) { - break; - } - /* make erase align and calculate next erase address */ - if (addr % cur_erase_size != 0) { - if (size > cur_erase_size - (addr % cur_erase_size)) { - size -= cur_erase_size - (addr % cur_erase_size); - addr += cur_erase_size - (addr % cur_erase_size); - } else { - break; - } - } else { - if (size > cur_erase_size) { - size -= cur_erase_size; - addr += cur_erase_size; - } else { - break; - } - } - } - - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * write flash data (no erase operate) for write 1 to 256 bytes per page mode or byte write mode - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param write_gran write granularity bytes, only support 1 or 256 - * @param data write data - * - * @return result - */ -static sfud_err page256_or_1_byte_write(const sfud_flash *flash, uint32_t addr, size_t size, uint16_t write_gran, - const uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[5 + SFUD_WRITE_MAX_PAGE_SIZE], cmd_size; - size_t data_size; - - SFUD_ASSERT(flash); - /* only support 1 or 256 */ - SFUD_ASSERT(write_gran == 1 || write_gran == 256); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* check the flash address bound */ - if (addr + size > flash->chip.capacity) { - SFUD_INFO("Error: Flash address is out of bound."); - return SFUD_ERR_ADDR_OUT_OF_BOUND; - } - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - /* loop write operate. write unit is write granularity */ - while (size) { - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - break; - } - cmd_data[0] = SFUD_CMD_PAGE_PROGRAM; - make_adress_byte_array(flash, addr, &cmd_data[1]); - cmd_size = flash->addr_in_4_byte ? 5 : 4; - - /* make write align and calculate next write address */ - if (addr % write_gran != 0) { - if (size > write_gran - (addr % write_gran)) { - data_size = write_gran - (addr % write_gran); - } else { - data_size = size; - } - } else { - if (size > write_gran) { - data_size = write_gran; - } else { - data_size = size; - } - } - size -= data_size; - addr += data_size; - - memcpy(&cmd_data[cmd_size], data, data_size); - - result = spi->wr(spi, cmd_data, cmd_size + data_size, NULL, 0); - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Flash write SPI communicate error."); - break; - } - result = wait_busy(flash); - if (result != SFUD_SUCCESS) { - break; - } - data += data_size; - } - - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * write flash data (no erase operate) for auto address increment mode - * - * If the address is odd number, it will place one 0xFF before the start of data for protect the old data. - * If the latest remain size is 1, it will append one 0xFF at the end of data for protect the old data. - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param data write data - * - * @return result - */ -static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[6], cmd_size; - const size_t data_size = 2; - bool first_write = true; - - SFUD_ASSERT(flash); - SFUD_ASSERT(size >= 2); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* check the flash address bound */ - if (addr + size > flash->chip.capacity) { - SFUD_INFO("Error: Flash address is out of bound."); - return SFUD_ERR_ADDR_OUT_OF_BOUND; - } - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - goto exit; - } - /* loop write operate. write unit is write granularity */ - cmd_data[0] = SFUD_CMD_AAI_WORD_PROGRAM; - while (size) { - if (first_write) { - make_adress_byte_array(flash, addr, &cmd_data[1]); - cmd_size = flash->addr_in_4_byte ? 5 : 4; - if (addr % 2 == 0) { - cmd_data[cmd_size] = *data; - cmd_data[cmd_size + 1] = *(data + 1); - } else { - cmd_data[cmd_size] = 0xFF; - cmd_data[cmd_size + 1] = *data; - size++; - data--; - } - first_write = false; - } else { - cmd_size = 1; - if (size != 1) { - cmd_data[1] = *data; - cmd_data[2] = *(data + 1); - } else { - cmd_data[1] = *data; - cmd_data[2] = 0xFF; - size++; - } - } - - result = spi->wr(spi, cmd_data, cmd_size + data_size, NULL, 0); - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Flash write SPI communicate error."); - goto exit; - } - - result = wait_busy(flash); - if (result != SFUD_SUCCESS) { - goto exit; - } - - size -= 2; - data += data_size; - } - /* set the flash write disable */ - result = set_write_enabled(flash, false); - - exit: - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * write flash data (no erase operate) - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param data write data - * - * @return result - */ -sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - - if (flash->chip.write_mode & SFUD_WM_PAGE_256B) { - result = page256_or_1_byte_write(flash, addr, size, 256, data); - } else if (flash->chip.write_mode & SFUD_WM_AAI) { - result = aai_write(flash, addr, size, data); - } else if (flash->chip.write_mode & SFUD_WM_DUAL_BUFFER) { - //TODO dual-buffer write mode - } - - return result; -} - -/** - * erase and write flash data - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param data write data - * - * @return result - */ -sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - - result = sfud_erase(flash, addr, size); - - if (result == SFUD_SUCCESS) { - result = sfud_write(flash, addr, size, data); - } - - return result; -} - -static sfud_err reset(const sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[2]; - - SFUD_ASSERT(flash); - - cmd_data[0] = SFUD_CMD_ENABLE_RESET; - cmd_data[1] = SFUD_CMD_RESET; - result = spi->wr(spi, cmd_data, 2, NULL, 0); - - if (result == SFUD_SUCCESS) { - result = wait_busy(flash); - } - - if (result == SFUD_SUCCESS) { - SFUD_DEBUG("Flash device reset success."); - } else { - SFUD_INFO("Error: Flash device reset failed."); - } - - return result; -} - -static sfud_err read_jedec_id(sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[1], recv_data[3]; - - SFUD_ASSERT(flash); - - cmd_data[0] = SFUD_CMD_JEDEC_ID; - result = spi->wr(spi, cmd_data, sizeof(cmd_data), recv_data, sizeof(recv_data)); - if (result == SFUD_SUCCESS) { - flash->chip.mf_id = recv_data[0]; - flash->chip.type_id = recv_data[1]; - flash->chip.capacity_id = recv_data[2]; - SFUD_DEBUG("The flash device manufacturer ID is 0x%02X, memory type ID is 0x%02X, capacity ID is 0x%02X.", - flash->chip.mf_id, flash->chip.type_id, flash->chip.capacity_id); - } else { - SFUD_INFO("Error: Read flash device JEDEC ID error."); - } - - return result; -} - -/** - * set the flash write enable or write disable - * - * @param flash flash device - * @param enabled true: enable false: disable - * - * @return result - */ -static sfud_err set_write_enabled(const sfud_flash *flash, bool enabled) { - sfud_err result = SFUD_SUCCESS; - uint8_t cmd, register_status; - - SFUD_ASSERT(flash); - - if (enabled) { - cmd = SFUD_CMD_WRITE_ENABLE; - } else { - cmd = SFUD_CMD_WRITE_DISABLE; - } - - result = flash->spi.wr(&flash->spi, &cmd, 1, NULL, 0); - - if (result == SFUD_SUCCESS) { - result = sfud_read_status(flash, ®ister_status); - } - - if (result == SFUD_SUCCESS) { - if (enabled && (register_status & SFUD_STATUS_REGISTER_WEL) == 0) { - SFUD_INFO("Error: Can't enable write status."); - return SFUD_ERR_WRITE; - } else if (!enabled && (register_status & SFUD_STATUS_REGISTER_WEL) == 1) { - SFUD_INFO("Error: Can't disable write status."); - return SFUD_ERR_WRITE; - } - } - - return result; -} - -/** - * enable or disable 4-Byte addressing for flash - * - * @note The 4-Byte addressing just supported for the flash capacity which is large then 16MB (256Mb). - * - * @param flash flash device - * @param enabled true: enable false: disable - * - * @return result - */ -static sfud_err set_4_byte_address_mode(sfud_flash *flash, bool enabled) { - sfud_err result = SFUD_SUCCESS; - uint8_t cmd; - - SFUD_ASSERT(flash); - - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - return result; - } - - if (enabled) { - cmd = SFUD_CMD_ENTER_4B_ADDRESS_MODE; - } else { - cmd = SFUD_CMD_EXIT_4B_ADDRESS_MODE; - } - - result = flash->spi.wr(&flash->spi, &cmd, 1, NULL, 0); - - if (result == SFUD_SUCCESS) { - flash->addr_in_4_byte = enabled ? true : false; - SFUD_DEBUG("%s 4-Byte addressing mode success.", enabled ? "Enter" : "Exit"); - } else { - SFUD_INFO("Error: %s 4-Byte addressing mode failed.", enabled ? "Enter" : "Exit"); - } - - return result; -} - -/** - * read flash register status - * - * @param flash flash device - * @param status register status - * - * @return result - */ -sfud_err sfud_read_status(const sfud_flash *flash, uint8_t *status) { - uint8_t cmd = SFUD_CMD_READ_STATUS_REGISTER; - - SFUD_ASSERT(flash); - SFUD_ASSERT(status); - - return flash->spi.wr(&flash->spi, &cmd, 1, status, 1); -} - -static sfud_err wait_busy(const sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - uint8_t status; - size_t retry_times = flash->retry.times; - - SFUD_ASSERT(flash); - - while (true) { - result = sfud_read_status(flash, &status); - if (result == SFUD_SUCCESS && ((status & SFUD_STATUS_REGISTER_BUSY)) == 0) { - break; - } - /* retry counts */ - SFUD_RETRY_PROCESS(flash->retry.delay, retry_times, result); - } - - if (result != SFUD_SUCCESS || ((status & SFUD_STATUS_REGISTER_BUSY)) != 0) { - SFUD_INFO("Error: Flash wait busy has an error."); - } - - return result; -} - -static void make_adress_byte_array(const sfud_flash *flash, uint32_t addr, uint8_t *array) { - uint8_t len; - - SFUD_ASSERT(flash); - SFUD_ASSERT(array); - - len = flash->addr_in_4_byte ? 4 : 3; - - for (uint8_t i = 0; i < len; i++) { - array[i] = (addr >> ((len - (i + 1)) * 8)) & 0xFF; - } -} - -/** - * write status register - * - * @param flash flash device - * @param is_volatile true: volatile mode, false: non-volatile mode - * @param status register status - * - * @return result - */ -sfud_err sfud_write_status(const sfud_flash *flash, bool is_volatile, uint8_t status) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[2]; - - SFUD_ASSERT(flash); - - if (is_volatile) { - cmd_data[0] = SFUD_VOLATILE_SR_WRITE_ENABLE; - result = spi->wr(spi, cmd_data, 1, NULL, 0); - } else { - result = set_write_enabled(flash, true); - } - - if (result == SFUD_SUCCESS) { - cmd_data[0] = SFUD_CMD_WRITE_STATUS_REGISTER; - cmd_data[1] = status; - result = spi->wr(spi, cmd_data, 2, NULL, 0); - } - - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Write_status register failed."); - } - - return result; -} diff --git a/demo/env/stm32f10x/non_os_spi_flash/components/sfud/src/sfud_sfdp.c b/demo/env/stm32f10x/non_os_spi_flash/components/sfud/src/sfud_sfdp.c deleted file mode 100644 index 8034524..0000000 --- a/demo/env/stm32f10x/non_os_spi_flash/components/sfud/src/sfud_sfdp.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * This file is part of the Serial Flash Universal Driver Library. - * - * Copyright (c) 2016, Armink, - * - * 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. - * - * Function: Analyze the SFDP (Serial Flash Discoverable Parameters) which from JESD216/A/B (V1.X) standard. - * JESD216 (V1.0) document: http://www.jedec.org/sites/default/files/docs/JESD216.pdf - * JESD216A (V1.5) document: http://www.jedec.org/sites/default/files/docs/JESD216A.pdf - * JESD216B (V1.6) document: http://www.jedec.org/sites/default/files/docs/JESD216B.pdf - * - * Created on: 2016-05-26 - */ - -#include "../inc/sfud.h" - -/** - * JEDEC Standard JESD216 Terms and definitions: - * - * DWORD: Four consecutive 8-bit bytes used as the basic 32-bit building block for headers and parameter tables. - * - * Sector: The minimum granularity - size and alignment - of an area that can be erased in the data array - * of a flash memory device. Different areas within the address range of the data array may have a different - * minimum erase granularity (sector size). - */ - -#ifdef SFUD_USING_SFDP - -/* support maximum SFDP major revision by driver */ -#define SUPPORT_MAX_SFDP_MAJOR_REV 1 -/* The JEDEC basic flash parameter table length is 9 DWORDs (288-bit) on JESD216 (V1.0) initial release standard */ -#define BASIC_TABLE_LEN 9 - -/** - * SFDP parameter header structure - */ -typedef struct { - uint8_t id; /**< Parameter ID LSB */ - uint8_t minor_rev; /**< Parameter minor revision */ - uint8_t major_rev; /**< Parameter major revision */ - uint8_t len; /**< Parameter table length(in double words) */ - uint32_t ptp; /**< Parameter table 24bit pointer (byte address) */ -} sfdp_para_header; - -static sfud_err read_sfdp_data(const sfud_flash *flash, uint32_t addr, uint8_t *read_buf, size_t size); -static bool read_sfdp_header(sfud_flash *flash); -static bool read_basic_header(const sfud_flash *flash, sfdp_para_header *basic_header); -static bool read_basic_table(sfud_flash *flash, sfdp_para_header *basic_header); - -/* ../port/sfup_port.c */ -extern void sfud_log_debug(const char *file, const long line, const char *format, ...); -extern void sfud_log_info(const char *format, ...); - -/** - * Read SFDP parameter information - * - * @param flash flash device - * - * @return true: read OK - */ -bool sfud_read_sfdp(sfud_flash *flash) { - SFUD_ASSERT(flash); - - /* JEDEC basic flash parameter header */ - sfdp_para_header basic_header; - if (read_sfdp_header(flash) && read_basic_header(flash, &basic_header)) { - return read_basic_table(flash, &basic_header); - } else { - SFUD_INFO("Warning: Read SFDP parameter header information failed. The %s is not support JEDEC SFDP.", flash->name); - return false; - } -} - -/** - * Read SFDP parameter header - * - * @param flash flash device - * - * @return true: read OK - */ -static bool read_sfdp_header(sfud_flash *flash) { - sfud_sfdp *sfdp = &flash->sfdp; - /* The SFDP header is located at address 000000h of the SFDP data structure. - * It identifies the SFDP Signature, the number of parameter headers, and the SFDP revision numbers. */ - /* sfdp parameter header address */ - uint32_t header_addr = 0; - /* each parameter header being 2 DWORDs (64-bit) */ - uint8_t header[2 * 4] = { 0 }; - /* number of parameter headers */ - uint8_t npn = 0; - - SFUD_ASSERT(flash); - - sfdp->available = false; - /* read SFDP header */ - if (read_sfdp_data(flash, header_addr, header, sizeof(header)) != SFUD_SUCCESS) { - SFUD_INFO("Error: Can't read SFDP header."); - return false; - } - /* check SFDP header */ - if (!(header[0] == 'S' && - header[1] == 'F' && - header[2] == 'D' && - header[3] == 'P')) { - SFUD_INFO("Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P')."); - return false; - } - sfdp->minor_rev = header[4]; - sfdp->major_rev = header[5]; - npn = header[6]; - if (sfdp->major_rev > SUPPORT_MAX_SFDP_MAJOR_REV) { - SFUD_INFO("Error: This reversion(V%d.%d) SFDP is not supported.", sfdp->major_rev, sfdp->minor_rev); - return false; - } - SFUD_DEBUG("Check SFDP header is OK. The reversion is V%d.%d, NPN is %d.", sfdp->major_rev, sfdp->minor_rev, npn); - - return true; -} - -/** - * Read JEDEC basic parameter header - * - * @param flash flash device - * - * @return true: read OK - */ -static bool read_basic_header(const sfud_flash *flash, sfdp_para_header *basic_header) { - /* The basic parameter header is mandatory, is defined by this standard, and starts at byte offset 08h. */ - uint32_t header_addr = 8; - /* each parameter header being 2 DWORDs (64-bit) */ - uint8_t header[2 * 4] = { 0 }; - - SFUD_ASSERT(flash); - SFUD_ASSERT(basic_header); - - /* read JEDEC basic flash parameter header */ - if (read_sfdp_data(flash, header_addr, header, sizeof(header)) != SFUD_SUCCESS) { - SFUD_INFO("Error: Can't read JEDEC basic flash parameter header."); - return false; - } - basic_header->id = header[0]; - basic_header->minor_rev = header[1]; - basic_header->major_rev = header[2]; - basic_header->len = header[3]; - basic_header->ptp = header[4] | header[5] << 8 | header[6] << 16; - /* check JEDEC basic flash parameter header */ - if (basic_header->major_rev > SUPPORT_MAX_SFDP_MAJOR_REV) { - SFUD_INFO("Error: This reversion(V%d.%d) JEDEC basic flash parameter header is not supported.", - basic_header->major_rev, basic_header->minor_rev); - return false; - } - if (basic_header->len < BASIC_TABLE_LEN) { - SFUD_INFO("Error: The JEDEC basic flash parameter table length (now is %d) error.", basic_header->len); - return false; - } - SFUD_DEBUG("Check JEDEC basic flash parameter header is OK. The table id is %d, reversion is V%d.%d," - " length is %d, parameter table pointer is 0x%06X.", basic_header->id, basic_header->major_rev, - basic_header->minor_rev, basic_header->len, basic_header->ptp); - - return true; -} - -/** - * Read JEDEC basic parameter table - * - * @param flash flash device - * - * @return true: read OK - */ -static bool read_basic_table(sfud_flash *flash, sfdp_para_header *basic_header) { - sfud_sfdp *sfdp = &flash->sfdp; - /* parameter table address */ - uint32_t table_addr = basic_header->ptp; - /* parameter table */ - uint8_t table[BASIC_TABLE_LEN * 4] = { 0 }; - - SFUD_ASSERT(flash); - SFUD_ASSERT(basic_header); - - /* read JEDEC basic flash parameter table */ - if (read_sfdp_data(flash, table_addr, table, sizeof(table)) != SFUD_SUCCESS) { - SFUD_INFO("Error: Can't read JEDEC basic flash parameter table."); - return false; - } - /* print JEDEC basic flash parameter table info */ - SFUD_DEBUG("JEDEC basic flash parameter table info:"); - SFUD_DEBUG("MSB-LSB 3 2 1 0"); - for (uint8_t i = 0; i < BASIC_TABLE_LEN; i++) { - SFUD_DEBUG("[%04d] 0x%02X 0x%02X 0x%02X 0x%02X", i + 1, table[i * 4 + 3], table[i * 4 + 2], table[i * 4 + 1], - table[i * 4]); - } - - /* get block/sector 4 KB erase supported and command */ - sfdp->erase_4k_cmd = table[1]; - switch (table[0] & 0x03) { - case 1: - sfdp->erase_4k = true; - SFUD_DEBUG("4 KB Erase is supported throughout the device. Command is 0x%02X.", sfdp->erase_4k_cmd); - break; - case 3: - sfdp->erase_4k = false; - SFUD_DEBUG("Uniform 4 KB erase is unavailable for this device."); - break; - default: - SFUD_INFO("Error: Uniform 4 KB erase supported information error."); - return false; - } - /* get write granularity */ - //TODO 目前为 1.0 所提供的方式,后期支持 V1.5 及以上的方式读取 page size - switch ((table[0] & (0x01 << 2)) >> 2) { - case 0: - sfdp->write_gran = 1; - SFUD_DEBUG("Write granularity is 1 byte."); - break; - case 1: - sfdp->write_gran = 256; - SFUD_DEBUG("Write granularity is 64 bytes or larger."); - break; - } - /* volatile status register block protect bits */ - switch ((table[0] & (0x01 << 3)) >> 3) { - case 0: - /* Block Protect bits in device's status register are solely non-volatile or may be - * programmed either as volatile using the 50h instruction for write enable or non-volatile - * using the 06h instruction for write enable. - */ - sfdp->sr_is_non_vola = true; - SFUD_DEBUG("Target flash status register is non-volatile."); - break; - case 1: - /* block protect bits in device's status register are solely volatile. */ - sfdp->sr_is_non_vola = false; - SFUD_DEBUG("Block Protect bits in device's status register are solely volatile."); - /* write enable instruction select for writing to volatile status register */ - switch ((table[0] & (0x01 << 4)) >> 4) { - case 0: - sfdp->vola_sr_we_cmd = SFUD_VOLATILE_SR_WRITE_ENABLE; - SFUD_DEBUG("Flash device requires instruction 50h as the write enable prior " - "to performing a volatile write to the status register."); - break; - case 1: - sfdp->vola_sr_we_cmd = SFUD_CMD_WRITE_ENABLE; - SFUD_DEBUG("Flash device requires instruction 06h as the write enable prior " - "to performing a volatile write to the status register."); - break; - } - break; - } - /* get address bytes, number of bytes used in addressing flash array read, write and erase. */ - switch ((table[2] & (0x03 << 1)) >> 1) { - case 0: - sfdp->addr_3_byte = true; - sfdp->addr_4_byte = false; - SFUD_DEBUG("3-Byte only addressing."); - break; - case 1: - sfdp->addr_3_byte = true; - sfdp->addr_4_byte = true; - SFUD_DEBUG("3- or 4-Byte addressing."); - break; - case 2: - sfdp->addr_3_byte = false; - sfdp->addr_4_byte = true; - SFUD_DEBUG("4-Byte only addressing."); - break; - default: - sfdp->addr_3_byte = false; - sfdp->addr_4_byte = false; - SFUD_INFO("Error: Read address bytes error!"); - return false; - } - /* get flash memory capacity */ - uint32_t table2_temp = (table[7] << 24) | (table[6] << 16) | (table[5] << 8) | table[4]; - switch ((table[7] & (0x01 << 7)) >> 7) { - case 0: - sfdp->capacity = 1 + (table2_temp >> 3); - break; - case 1: - table2_temp &= 0x7FFFFFFF; - if (table2_temp > sizeof(sfdp->capacity) * 8 + 3) { - sfdp->capacity = 0; - SFUD_INFO("Error: The flash capacity is grater than 32 Gb/ 4 GB! Not Supported."); - return false; - } - sfdp->capacity = 1 << (table2_temp - 3); - break; - } - SFUD_DEBUG("Capacity is %ld Bytes.", sfdp->capacity); - /* get erase size and erase command */ - for (uint8_t i = 0, j = 0; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) { - if (table[28 + 2 * i] != 0x00) { - sfdp->eraser[j].size = 1 << table[28 + 2 * i]; - sfdp->eraser[j].cmd = table[28 + 2 * i + 1]; - SFUD_DEBUG("Flash device supports %ldKB block erase. Command is 0x%02X.", sfdp->eraser[j].size / 1024, - sfdp->eraser[j].cmd); - j++; - } - } - - sfdp->available = true; - return true; -} - -static sfud_err read_sfdp_data(const sfud_flash *flash, uint32_t addr, uint8_t *read_buf, size_t size) { - uint8_t cmd[] = { - SFUD_CMD_READ_SFDP_REGISTER, - (addr >> 16) & 0xFF, - (addr >> 8) & 0xFF, - (addr >> 0) & 0xFF, - SFUD_DUMMY_DATA, - }; - - SFUD_ASSERT(flash); - SFUD_ASSERT(addr < 1 << 24); - SFUD_ASSERT(read_buf); - SFUD_ASSERT(flash->spi.wr); - - return flash->spi.wr(&flash->spi, cmd, sizeof(cmd), read_buf, size); -} - -/** - * get the suitable eraser for erase process from SFDP parameter - * - * @param flash flash device - * @param erase_size will be erased size - * - * @return the eraser index of SFDP eraser table @see sfud_sfdp.eraser[] - */ -size_t sfud_sfdp_get_suitable_eraser(const sfud_flash *flash, size_t erase_size) { - size_t i, index = 0; - bool find_ok = false; - /* find an suitable eraser which size is less than and closest to erase size */ - for (i = 0; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) { - if (flash->sfdp.eraser[i].size != 0 && erase_size >= flash->sfdp.eraser[i].size - && flash->sfdp.eraser[i].size >= flash->sfdp.eraser[index].size) { - index = i; - find_ok = true; - } - } - /* erase size is lass than all eraser size then used smallest eraser */ - if (!find_ok) { - index = 0; - /* find the smallest erase size for eraser */ - for (i = 0; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) { - if (flash->sfdp.eraser[i].size != 0 && flash->sfdp.eraser[index].size > flash->sfdp.eraser[i].size) { - index = i; - } - } - } - return index; -} - -#endif /* SFUD_USING_SFDP */