From b8ccb2e6620ff32ba66993eb380620e02458b570 Mon Sep 17 00:00:00 2001 From: rogeryou Date: Tue, 9 Mar 2021 15:40:08 +0800 Subject: [PATCH 01/13] add SPI NAND Block device driver --- .../COMPONENT_SPINAND/CMakeLists.txt | 13 + .../include/SPINAND/.SPINANDBlockDevice.h.swo | Bin 0 -> 28672 bytes .../include/SPINAND/SPINANDBlockDevice.h | 325 +++++++ .../COMPONENT_SPINAND/mbed_lib.json | 31 + .../source/.SPINANDBlockDevice.cpp.swo | Bin 0 -> 77824 bytes .../source/SPINANDBlockDevice.cpp | 797 ++++++++++++++++++ .../blockdevice/general_block_device/main.cpp | 50 +- 7 files changed, 1214 insertions(+), 2 deletions(-) create mode 100644 storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt create mode 100644 storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/.SPINANDBlockDevice.h.swo create mode 100644 storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h create mode 100644 storage/blockdevice/COMPONENT_SPINAND/mbed_lib.json create mode 100644 storage/blockdevice/COMPONENT_SPINAND/source/.SPINANDBlockDevice.cpp.swo create mode 100644 storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp diff --git a/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt b/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt new file mode 100644 index 00000000000..fc07dbe3429 --- /dev/null +++ b/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +target_include_directories(mbed-storage-spinand + INTERFACE + include + include/SPINAND +) + +target_sources(mbed-storage-spinand + INTERFACE + source/SPINANDBlockDevice.cpp +) diff --git a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/.SPINANDBlockDevice.h.swo b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/.SPINANDBlockDevice.h.swo new file mode 100644 index 0000000000000000000000000000000000000000..b65bdd1d726dc95a256a7872f51747a7efaf40ae GIT binary patch literal 28672 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 literal 0 HcmV?d00001 diff --git a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h new file mode 100644 index 00000000000..1d6196f60aa --- /dev/null +++ b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h @@ -0,0 +1,325 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * 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 MBED_SPINAND_BLOCK_DEVICE_H +#define MBED_SPINAND_BLOCK_DEVICE_H + +#include "drivers/QSPI.h" +#include "blockdevice/BlockDevice.h" +#include "platform/Callback.h" + +#ifndef MBED_CONF_SPINAND_QSPI_IO0 +#define MBED_CONF_SPINAND_QSPI_IO0 NC +#endif +#ifndef MBED_CONF_SPINAND_QSPI_IO1 +#define MBED_CONF_SPINAND_QSPI_IO1 NC +#endif +#ifndef MBED_CONF_SPINAND_QSPI_IO2 +#define MBED_CONF_SPINAND_QSPI_IO2 NC +#endif +#ifndef MBED_CONF_SPINAND_QSPI_IO3 +#define MBED_CONF_SPINAND_QSPI_IO3 NC +#endif +#ifndef MBED_CONF_SPINAND_QSPI_SCK +#define MBED_CONF_SPINAND_QSPI_SCK NC +#endif +#ifndef MBED_CONF_SPINAND_QSPI_CSN +#define MBED_CONF_SPINAND_QSPI_CSN NC +#endif +#ifndef MBED_CONF_SPINAND_QSPI_POLARITY_MODE +#define MBED_CONF_SPINAND_QSPI_POLARITY_MODE 0 +#endif +#ifndef MBED_CONF_SPINAND_QSPI_FREQ +#define MBED_CONF_SPINAND_QSPI_FREQ 40000000 +#endif + +/** Enum spinand standard error codes + * + * @enum spinand_bd_error + */ +enum spinand_bd_error { + SPINAND_BD_ERROR_OK = 0, /*!< no error */ + SPINAND_BD_ERROR_DEVICE_ERROR = BD_ERROR_DEVICE_ERROR, /*!< device specific error -4001 */ + SPINAND_BD_ERROR_PARSING_FAILED = -4002, /* SFDP Parsing failed */ + SPINAND_BD_ERROR_READY_FAILED = -4003, /* Wait for Mem Ready failed */ + SPINAND_BD_ERROR_WREN_FAILED = -4004, /* Write Enable Failed */ + SPINAND_BD_ERROR_INVALID_ERASE_PARAMS = -4005, /* Erase command not on sector aligned addresses or exceeds device size */ + SPINAND_BD_ERROR_DEVICE_NOT_UNIQUE = -4006, /* Only one instance per csel is allowed */ + SPINAND_BD_ERROR_DEVICE_MAX_EXCEED = -4007 /* Max active SPINAND devices exceeded */ +}; + +/** Enum spinand polarity mode + * + * @enum spinand_polarity_mode + */ +enum spinand_polarity_mode { + SPINAND_POLARITY_MODE_0 = 0, /* CPOL=0, CPHA=0 */ + SPINAND_POLARITY_MODE_1 /* CPOL=1, CPHA=1 */ +}; + +#define SPINAND_MAX_ACTIVE_FLASH_DEVICES 10 + +/** BlockDevice for SPI NAND flash devices over QSPI bus + * + * @code + * // Here's an example using SPI NAND flash device on DISCO_L4R9I target + * #include "mbed.h" + * #include "SPINANDBlockDevice.h" + * + * SPINANDBlockDevice block_device(SPINAND_FLASH1_IO0, SPINAND_FLASH1_IO1, SPINAND_FLASH1_IO2, SPINAND_FLASH1_IO3, + * SPINAND_FLASH1_SCK, SPINAND_FLASH1_CSN, SPINAND_POLARITY_MODE_0, MBED_CONF_SPINAND_QSPI_FREQ); + * + * int main() + * { + * printf("SPI NAND Flash Block Device example\n"); + * + * // Initialize the SPI NAND flash device and print the memory layout + * block_device.init(); + * bd_size_t sector_size_at_address_0 = block_device.get_erase_size(0); + * + * printf("SPINAND BD size: %llu\n", block_device.size()); + * printf("SPINAND BD read size: %llu\n", block_device.get_read_size()); + * printf("SPINAND BD program size: %llu\n", block_device.get_program_size()); + * printf("SPINAND BD erase size (at address 0): %llu\n", sector_size_at_address_0); + * + * // Write "Hello World!" to the first block + * char *buffer = (char *) malloc(sector_size_at_address_0); + * sprintf(buffer, "Hello World!\n"); + * block_device.erase(0, sector_size_at_address_0); + * block_device.program(buffer, 0, sector_size_at_address_0); + * + * // Read back what was stored + * block_device.read(buffer, 0, sector_size_at_address_0); + * printf("%s", buffer); + * + * // Deinitialize the device + * block_device.deinit(); + * } + * @endcode + */ +class SPINANDBlockDevice : public mbed::BlockDevice { +public: + /** Create SPINANDBlockDevice - An SPI NAND Flash Block Device over QSPI bus + * + * @param io0 1st IO pin used for sending/receiving data during data phase of a transaction + * @param io1 2nd IO pin used for sending/receiving data during data phase of a transaction + * @param io2 3rd IO pin used for sending/receiving data during data phase of a transaction + * @param io3 4th IO pin used for sending/receiving data during data phase of a transaction + * @param sclk QSPI Clock pin + * @param csel QSPI chip select pin + * @param clock_mode specifies the QSPI Clock Polarity mode (SPINAND_POLARITY_MODE_0/SPINAND_POLARITY_MODE_1) + * default value = 0 + * @param freq Clock frequency of the QSPI bus (defaults to 40MHz) + */ + SPINANDBlockDevice(PinName io0 = MBED_CONF_SPINAND_QSPI_IO0, + PinName io1 = MBED_CONF_SPINAND_QSPI_IO1, + PinName io2 = MBED_CONF_SPINAND_QSPI_IO2, + PinName io3 = MBED_CONF_SPINAND_QSPI_IO3, + PinName sclk = MBED_CONF_SPINAND_QSPI_SCK, + PinName csel = MBED_CONF_SPINAND_QSPI_CSN, + int clock_mode = MBED_CONF_SPINAND_QSPI_POLARITY_MODE, + int freq = MBED_CONF_SPINAND_QSPI_FREQ); + + /** Initialize a block device + * + * @return SPINAND_BD_ERROR_OK(0) - success + * SPINAND_BD_ERROR_DEVICE_ERROR - device driver transaction failed + * SPINAND_BD_ERROR_READY_FAILED - Waiting for Memory ready failed or timedout + */ + virtual int init(); + + /** Deinitialize a block device + * + * @return SPINAND_BD_ERROR_OK(0) - success + * SPINAND_BD_ERROR_DEVICE_ERROR - device driver transaction failed + */ + virtual int deinit(); + + /** Desctruct SPINANDBlockDevie + */ + ~SPINANDBlockDevice() + { + deinit(); + } + + /** Read blocks from a block device + * + * @param buffer Buffer to write blocks to + * @param addr Address of block to begin reading from + * @param size Size to read in bytes, must be a multiple of read block size + * @return SPINAND_BD_ERROR_OK(0) - success + * SPINAND_BD_ERROR_DEVICE_ERROR - device driver transaction failed + */ + virtual int read(void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size); + + /** Program blocks to a block device + * + * The blocks must have been erased prior to being programmed + * + * @param buffer Buffer of data to write to blocks + * @param addr Address of block to begin writing to + * @param size Size to write in bytes, must be a multiple of program block size + * @return SPINAND_BD_ERROR_OK(0) - success + * SPINAND_BD_ERROR_DEVICE_ERROR - device driver transaction failed + * SPINAND_BD_ERROR_READY_FAILED - Waiting for Memory ready failed or timed out + * SPINAND_BD_ERROR_WREN_FAILED - Write Enable failed + */ + virtual int program(const void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size); + + /** Erase blocks on a block device + * + * The state of an erased block is undefined until it has been programmed + * + * @param addr Address of block to begin erasing + * @param size Size to erase in bytes, must be a multiple of erase block size + * @return SPINAND_BD_ERROR_OK(0) - success + * SPINAND_BD_ERROR_DEVICE_ERROR - device driver transaction failed + * SPINAND_BD_ERROR_READY_FAILED - Waiting for Memory ready failed or timed out + * SPINAND_BD_ERROR_WREN_FAILED - Write Enable failed + * SPINAND_BD_ERROR_INVALID_ERASE_PARAMS - Trying to erase unaligned address or size + */ + virtual int erase(mbed::bd_addr_t addr, mbed::bd_size_t size); + + /** Get the size of a readable block + * + * @return Size of a readable block in bytes + */ + virtual mbed::bd_size_t get_read_size() const; + + /** Get the size of a programable block + * + * @return Size of a program block size in bytes + * @note Must be a multiple of the read size + */ + virtual mbed::bd_size_t get_program_size() const; + + /** Get the size of a eraseable block + * + * @return Size of a minimal erase block, common to all regions, in bytes + * @note Must be a multiple of the program size + */ + virtual mbed::bd_size_t get_erase_size() const; + virtual mbed::bd_size_t get_erase_size(bd_addr_t addr) const; + + /** Get the value of storage byte after it was erased + * + * If get_erase_value returns a non-negative byte value, the underlying + * storage is set to that value when erased, and storage containing + * that value can be programmed without another erase. + * + * @return The value of storage when erased, or -1 if you can't + * rely on the value of erased storage + */ + virtual int get_erase_value() const; + + /** Get the total size of the underlying device + * + * @return Size of the underlying device in bytes + */ + virtual mbed::bd_size_t size() const; + + /** Get the BlockDevice class type. + * + * @return A string represent the BlockDevice class type. + */ + virtual const char *get_type() const; + +private: + /********************************/ + /* Different Device Csel Mgmt */ + /********************************/ + // Add a new SPI NAND device CS to existing devices list. + // Only one SPINANDBlockDevice instance per CS is allowed + int add_new_csel_instance(PinName csel); + + // Remove device CS from existing device list upon destroying object (last deinit is called) + int remove_csel_instance(PinName csel); + + /********************************/ + /* Calls to QSPI Driver APIs */ + /********************************/ + // Send Program/Write command to Driver + qspi_status_t _qspi_send_program_command(mbed::qspi_inst_t prog_instruction, const void *buffer, + mbed::bd_addr_t addr, mbed::bd_size_t *size); + + // Send Read command to Driver + qspi_status_t _qspi_send_read_command(mbed::qspi_inst_t read_instruction, void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size); + + // Send Erase Instruction using command_transfer command to Driver + qspi_status_t _qspi_send_erase_command(mbed::qspi_inst_t erase_instruction, mbed::bd_addr_t addr, mbed::bd_size_t size); + + // Send Generic command_transfer command to Driver + qspi_status_t _qspi_send_general_command(mbed::qspi_inst_t instruction_int, mbed::bd_addr_t addr, const char *tx_buffer, + mbed::bd_size_t tx_length, const char *rx_buffer, mbed::bd_size_t rx_length); + + // Send set_frequency command to Driver + qspi_status_t _qspi_set_frequency(int freq); + + /*********************************/ + /* Flash Configuration Functions */ + /*********************************/ + + // Quad Enable in Sercurity Register + int _set_quad_enable(); + + // Clear the device's block protection + int _clear_block_protection(); + + // Configure Write Enable in Status Register + int _set_write_enable(); + + // Wait on status register until write not-in-progress + bool _is_mem_ready(); + +private: + + // QSPI Driver Object + mbed::QSPI _qspi; + + // Static List of different QSPI based Flash devices csel that already exist + // Each QSPI Flash device csel can have only 1 SPINANDBlockDevice instance + // _devices_mutex is used to lock csel list - only one SPINANDBlockDevice instance per csel is allowed + static SingletonPtr _devices_mutex; + static int _number_of_active_spinand_flash_csel; + static PinName *_active_spinand_flash_csel_arr; + + int _unique_device_status; + PinName _csel; + + // Mutex is used to protect Flash device for some QSPI Driver commands that must be done sequentially with no other commands in between + // e.g. (1)Set Write Enable, (2)Program, (3)Wait Memory Ready + PlatformMutex _mutex; + + // Command Instructions + mbed::qspi_inst_t _read_instruction; + mbed::qspi_inst_t _program_instruction; + + int _freq; + + // Bus speed configuration + qspi_bus_width_t _inst_width; //Bus width for Instruction phase + qspi_bus_width_t _address_width; //Bus width for Address phase + qspi_address_size_t _address_size; //Number of bits for address + qspi_alt_size_t _alt_size; //Number of bits for alt + bool _alt_enabled; //Whether alt is enabled + uint8_t _dummy_cycles; //Number of Dummy cycles required by Current Bus Mode + qspi_bus_width_t _data_width; //Bus width for Data phase + + uint32_t _init_ref_count; + bool _is_initialized; +}; + +#endif diff --git a/storage/blockdevice/COMPONENT_SPINAND/mbed_lib.json b/storage/blockdevice/COMPONENT_SPINAND/mbed_lib.json new file mode 100644 index 00000000000..89f69e7e8d3 --- /dev/null +++ b/storage/blockdevice/COMPONENT_SPINAND/mbed_lib.json @@ -0,0 +1,31 @@ +{ + "name": "spinand", + "config": { + "enable-and-reset": { + "help": "(Legacy SFDP 1.0 ONLY) Reset sequence is enable reset (0x66) then reset (0x99)", + "value": false + }, + "direct-reset": { + "help": "(Legacy SFDP 1.0 ONLY) Reset involves a single command (0xF0)", + "value": false + }, + "SPINAND_IO0": "MBED_CONF_DRIVERS_QSPI_IO0", + "SPINAND_IO1": "MBED_CONF_DRIVERS_QSPI_IO1", + "SPINAND_IO2": "MBED_CONF_DRIVERS_QSPI_IO2", + "SPINAND_IO3": "MBED_CONF_DRIVERS_QSPI_IO3", + "SPINAND_SCK": "MBED_CONF_DRIVERS_QSPI_SCK", + "SPINAND_CSN": "MBED_CONF_DRIVERS_QSPI_CSN", + "SPINAND_POLARITY_MODE": 0, + "SPINAND_FREQ": "40000000", + "SPINAND_MIN_READ_SIZE": "1", + "SPINAND_MIN_PROG_SIZE": "1", + "SPINAND_FLASH_SIZE": "2048*64*512", + "SPINAND_BLOCK_SIZE": "2048*64", + "SPINAND_PAGE_SIZE": "2048" + }, + "target_overrides": { + "MX31LF4GE4BC": { + "SPINAND_FREQ": "2000000" + } + } +} diff --git a/storage/blockdevice/COMPONENT_SPINAND/source/.SPINANDBlockDevice.cpp.swo b/storage/blockdevice/COMPONENT_SPINAND/source/.SPINANDBlockDevice.cpp.swo new file mode 100644 index 0000000000000000000000000000000000000000..a45aeb1e50d748dd5595efa46cf871fcaeef3b6a GIT binary patch literal 77824 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 +#include "rtos/ThisThread.h" + +#ifndef MBED_CONF_MBED_TRACE_ENABLE +#define MBED_CONF_MBED_TRACE_ENABLE 0 +#endif + +#include "mbed_trace.h" +#define TRACE_GROUP "SPINAND" + +using namespace std::chrono; +using namespace mbed; + +/* SPINAND Parameters */ +/****************************/ +#ifndef UINT64_MAX +#define UINT64_MAX -1 +#endif +#define QSPI_NO_ADDRESS_COMMAND UINT64_MAX +#define QSPI_ALT_DEFAULT_VALUE 0 + +// Get/Set Feature Address Definition +#define FEATURES_ADDR_BLOCK_PROTECTION 0xA0 +#define FEATURES_ADDR_SECURE_OTP 0xB0 +#define FEATURES_ADDR_STATUS 0xC0 + +// Status Register Bits +#define SPINAND_STATUS_BIT_WIP 0x1 // Write In Progress +#define SPINAND_STATUS_BIT_WEL 0x2 // Write Enable Latch +#define SPINAND_STATUS_BIT_ERASE_FAIL 0x4 // Erase failed +#define SPINAND_STATUS_BIT_PROGRAM_FAIL 0x8 // Program failed +#define SPINAND_STATUS_BIT_ECC_STATUS_MASK 0x30 // ECC status + #define SPINAND_STATUS_ECC_STATUS_NO_ERR 0x00 + #define SPINAND_STATUS_ECC_STATUS_ERR_COR 0x00 + #define SPINAND_STATUS_ECC_STATUS_ERR_NO_COR 0x00 + +// Secure OTP Register Bits +#define SPINAND_SECURE_BIT_QE 0x01 // Quad enable +#define SPINAND_SECURE_BIT_ECC_EN 0x10 // On-die ECC enable +#define SPINAND_SECURE_BIT_OTP_EN 0x40 // +#define SPINAND_SECURE_BIT_OTP_PROT 0x80 // + +// Block Protection Register Bits +#define SPINAND_BLOCK_PROT_BIT_SP 0x01 +#define SPINAND_BLOCK_PROT_BIT_COMPLE 0x02 +#define SPINAND_BLOCK_PROT_BIT_INVERT 0x04 +#define SPINAND_BLOCK_PROT_BIT_BP0 0x08 +#define SPINAND_BLOCK_PROT_BIT_BP1 0x10 +#define SPINAND_BLOCK_PROT_BIT_BP2 0x20 +#define SPINAND_BLOCK_PROT_BIT_BPRWD 0x80 +#define SPINAND_BLOCK_PROT_BIT_BP_MASK 0x38 + +#define SPINAND_BLOCK_PROT_BP_OFFSET 3 +#define SPINAND_BLOCK_PROT_COMPLE_OFFSET 1 + +#define IS_MEM_READY_MAX_RETRIES 10000 + +// General SPI NAND Flash instructions +#define SPINAND_INST_RDID 0x9F // Read Manufacturer and JDEC Device ID +#define SPINAND_INST_RSR1 0x05 // Read status register 1 + +#define SPINAND_INST_PAGE_READ 0x13 // Read data from array to cache +#define SPINAND_INST_READ_CACHE 0x03 // Read data from cache +#define SPINAND_INST_READ_CACHE2 0x3B +#define SPINAND_INST_READ_CACHE4 0x6B +#define SPINAND_INST_READ_CACHE_SEQ 0x31 +#define SPINAND_INST_READ_CACHE_END 0x3F + +#define SPINAND_INST_WREN 0x06 // Write enable +#define SPINAND_INST_WRDI 0x04 // Write disable +#define SPINAND_INST_PP_LOAD 0x02 +#define SPINAND_INST_PP_RAND_LOAD 0x84 +#define SPINAND_INST_4PP_LOAD 0x32 +#define SPINAND_INST_4PP_RAND_LOAD 0x34 +#define SPINAND_INST_PROGRAM_EXEC 0x10 +#define SPINAND_INST_BE 0xD8 + +#define SPINAND_INST_GET_FEATURE 0x0F +#define SPINAND_INST_SET_FEATURE 0x1F +#define SPINAND_INST_RESET 0xFF +#define SPINAND_INST_ECC_STAT_READ 0x7C + +// Default read/legacy erase instructions +//#define SPINAND_INST_READ_DEFAULT SPINAND_INST_READ_CACHE +//#define SPINAND_INST_READ_DEFAULT SPINAND_INST_READ_CACHE2 +#define SPINAND_INST_READ_DEFAULT SPINAND_INST_READ_CACHE4 +//#define SPINAND_INST_PROGRAM_DEFAULT SPINAND_INST_PP_LOAD +#define SPINAND_INST_PROGRAM_DEFAULT SPINAND_INST_4PP_LOAD + +#define SPINAND_BLOCK_OFFSET 0x40000 +#define SPINAND_PAGE_OFFSET 0x1000 + +#define SPI_NAND_ROW_ADDR_SIZE QSPI_CFG_ADDR_SIZE_16 +#define SPI_NAND_COLUMN_ADDR_SIZE QSPI_CFG_ADDR_SIZE_24 + +/* Init function to initialize Different Devices CS static list */ +static PinName *generate_initialized_active_spinand_csel_arr(); +// Static Members for different devices csel +// _devices_mutex is used to lock csel list - only one SPINANDBlockDevice instance per csel is allowed +SingletonPtr SPINANDBlockDevice::_devices_mutex; +int SPINANDBlockDevice::_number_of_active_spinand_flash_csel = 0; +PinName *SPINANDBlockDevice::_active_spinand_flash_csel_arr = generate_initialized_active_spinand_csel_arr(); + +/********* Public API Functions *********/ +/****************************************/ +SPINANDBlockDevice::SPINANDBlockDevice(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName csel, + int clock_mode, + int freq) + : + _qspi(io0, io1, io2, io3, sclk, csel, clock_mode), _csel(csel), _freq(freq), + _init_ref_count(0), + _is_initialized(false) +{ + _unique_device_status = add_new_csel_instance(csel); + + if (_unique_device_status == 0) { + tr_debug("Adding a new SPINANDBlockDevice csel: %d", (int)csel); + } else if (_unique_device_status == -1) { + tr_error("SPINANDBlockDevice with the same csel(%d) already exists", (int)csel); + } else { + tr_error("Too many different SPINANDBlockDevice devices - max allowed: %d", SPINAND_MAX_ACTIVE_FLASH_DEVICES); + } + + // Default Bus Setup 1_1_1 with 0 dummy and mode cycles + _inst_width = QSPI_CFG_BUS_SINGLE; + _address_width = QSPI_CFG_BUS_SINGLE; + _address_size = QSPI_CFG_ADDR_SIZE_8; + _alt_size = 0; + _dummy_cycles = 8; + _data_width = QSPI_CFG_BUS_SINGLE; + + // Set default read/erase instructions + _read_instruction = SPINAND_INST_READ_DEFAULT; + _program_instruction = SPINAND_INST_PROGRAM_DEFAULT; +} + +int SPINANDBlockDevice::init() +{ + int status = SPINAND_BD_ERROR_OK; + + if (_unique_device_status == 0) { + tr_debug("SPINANDBlockDevice csel: %d", (int)_csel); + } else if (_unique_device_status == -1) { + tr_error("SPINANDBlockDevice with the same csel(%d) already exists", (int)_csel); + return SPINAND_BD_ERROR_DEVICE_NOT_UNIQUE; + } else { + tr_error("Too many different SPINANDBlockDevice devices - max allowed: %d", SPINAND_MAX_ACTIVE_FLASH_DEVICES); + return SPINAND_BD_ERROR_DEVICE_MAX_EXCEED; + } + + _mutex.lock(); + + // All commands other than Read and RSFDP use default 1-1-1 bus mode (Program/Erase are constrained by flash memory performance more than bus performance) + if (QSPI_STATUS_OK != _qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, _address_size, QSPI_CFG_BUS_SINGLE, + 0, QSPI_CFG_BUS_SINGLE, 0)) { + tr_error("_qspi_configure_format failed"); + status = SPINAND_BD_ERROR_DEVICE_ERROR; + goto exit_point; + } + + if (!_is_initialized) { + _init_ref_count = 0; + } + + _init_ref_count++; + + if (_init_ref_count != 1) { + goto exit_point; + } + + _alt_size = 0; + _dummy_cycles = 8; + if (QSPI_STATUS_OK != _qspi_set_frequency(_freq)) { + tr_error("QSPI Set Frequency Failed"); + status = SPINAND_BD_ERROR_DEVICE_ERROR; + goto exit_point; + } + + // Synchronize Device + if (false == _is_mem_ready()) { + tr_error("Init - _is_mem_ready Failed"); + status = SPINAND_BD_ERROR_READY_FAILED; + goto exit_point; + } + + if (0 != _clear_block_protection()) { + tr_error("Init - clearing block protection failed"); + status = SPINAND_BD_ERROR_PARSING_FAILED; + goto exit_point; + } + + if (_read_instruction == SPINAND_INST_READ_CACHE4) { + if (QSPI_STATUS_OK !=_set_quad_enable()) { + tr_error("SPI NAND Set Quad enable Failed"); + status = SPINAND_BD_ERROR_DEVICE_ERROR; + goto exit_point; + } + } + + _is_initialized = true; + +exit_point: + _mutex.unlock(); + + return status; +} + +int SPINANDBlockDevice::deinit() +{ + int result = SPINAND_BD_ERROR_OK; + + _mutex.lock(); + + if (!_is_initialized) { + _init_ref_count = 0; + _mutex.unlock(); + return result; + } + + _init_ref_count--; + + if (_init_ref_count) { + _mutex.unlock(); + return result; + } + + // Disable Device for Writing + qspi_status_t status = _qspi_send_general_command(SPINAND_INST_WRDI, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0); + if (status != QSPI_STATUS_OK) { + tr_error("Write Disable failed"); + result = SPINAND_BD_ERROR_DEVICE_ERROR; + } + + _is_initialized = false; + + _mutex.unlock(); + + if (_unique_device_status == 0) { + remove_csel_instance(_csel); + } + + return result; +} + +int SPINANDBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) +{ + int status = SPINAND_BD_ERROR_OK; + uint32_t offset = 0; + uint32_t chunk = 0; + bd_size_t read_bytes = 0; + + tr_debug("Read Inst: 0x%xh", _read_instruction); + + while (size > 0) { + // Read on _page_size_bytes boundaries (Default 2048 bytes a page) + offset = addr % MBED_CONF_SPINAND_SPINAND_PAGE_SIZE; + chunk = (offset + size < MBED_CONF_SPINAND_SPINAND_PAGE_SIZE) ? size : (MBED_CONF_SPINAND_SPINAND_PAGE_SIZE - offset); + read_bytes = chunk; + + _mutex.lock(); + + if (QSPI_STATUS_OK != _qspi_send_read_command(_read_instruction, buffer, addr, read_bytes)) { + tr_error("Read Command failed"); + status = SPINAND_BD_ERROR_DEVICE_ERROR; + } + + buffer = static_cast< uint8_t *>(buffer) + chunk; + addr += SPINAND_PAGE_OFFSET; + size -= chunk; + + _mutex.unlock(); + } + + return status; +} + +int SPINANDBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size) +{ + qspi_status_t result = QSPI_STATUS_OK; + bool program_failed = false; + int status = SPINAND_BD_ERROR_OK; + uint32_t offset = 0; + uint32_t chunk = 0; + bd_size_t written_bytes = 0; + + tr_debug("Program - Buff: %p, addr: %llu, size: %llu", buffer, addr, size); + + while (size > 0) { + // Write on _page_size_bytes boundaries (Default 2048 bytes a page) + offset = addr % MBED_CONF_SPINAND_SPINAND_PAGE_SIZE; + chunk = (offset + size < MBED_CONF_SPINAND_SPINAND_PAGE_SIZE) ? size : (MBED_CONF_SPINAND_SPINAND_PAGE_SIZE - offset); + written_bytes = chunk; + + _mutex.lock(); + + //Send WREN + if (_set_write_enable() != 0) { + tr_error("Write Enabe failed"); + program_failed = true; + status = SPINAND_BD_ERROR_WREN_FAILED; + goto exit_point; + } + + result = _qspi_send_program_command(_program_instruction, buffer, addr, &written_bytes); + if ((result != QSPI_STATUS_OK) || (chunk != written_bytes)) { + tr_error("Write failed"); + program_failed = true; + status = SPINAND_BD_ERROR_DEVICE_ERROR; + goto exit_point; + } + + buffer = static_cast(buffer) + chunk; + addr += SPINAND_PAGE_OFFSET; + size -= chunk; + + if (false == _is_mem_ready()) { + tr_error("Device not ready after write, failed"); + program_failed = true; + status = SPINAND_BD_ERROR_READY_FAILED; + goto exit_point; + } + _mutex.unlock(); + } + +exit_point: + if (program_failed) { + _mutex.unlock(); + } + + return status; +} + +int SPINANDBlockDevice::erase(bd_addr_t addr, bd_size_t size) +{ + bool erase_failed = false; + int status = SPINAND_BD_ERROR_OK; + + tr_debug("Erase - addr: %llu, size: %llu", addr, size); + + if ((addr + size) > MBED_CONF_SPINAND_SPINAND_FLASH_SIZE) { + tr_error("Erase exceeds flash device size"); + return SPINAND_BD_ERROR_INVALID_ERASE_PARAMS; + } + + if (((addr % SPINAND_BLOCK_OFFSET) != 0) || ((size % get_erase_size()) != 0)) { + tr_error("Invalid erase - unaligned address and size"); + return SPINAND_BD_ERROR_INVALID_ERASE_PARAMS; + } + + while (size > 0) { + + _mutex.lock(); + + if (_set_write_enable() != 0) { + tr_error("SPI NAND Erase Device not ready - failed"); + erase_failed = true; + status = SPINAND_BD_ERROR_WREN_FAILED; + goto exit_point; + } + + if (QSPI_STATUS_OK != _qspi_send_erase_command(SPINAND_INST_BE, addr, size)) { + tr_error("SPI NAND Erase command failed!"); + erase_failed = true; + status = SPINAND_BD_ERROR_DEVICE_ERROR; + goto exit_point; + } + + addr += SPINAND_BLOCK_OFFSET; + if(size > MBED_CONF_SPINAND_SPINAND_BLOCK_SIZE) { + size -= MBED_CONF_SPINAND_SPINAND_BLOCK_SIZE; + } else { + size = 0; + } + + if (false == _is_mem_ready()) { + tr_error("SPI NAND After Erase Device not ready - failed"); + erase_failed = true; + status = SPINAND_BD_ERROR_READY_FAILED; + goto exit_point; + } + + _mutex.unlock(); + } + +exit_point: + if (erase_failed) { + _mutex.unlock(); + } + + return status; +} + +bd_size_t SPINANDBlockDevice::get_read_size() const +{ + // Return minimum read size in bytes for the device + return MBED_CONF_SPINAND_SPINAND_MIN_READ_SIZE; +} + +bd_size_t SPINANDBlockDevice::get_program_size() const +{ + // Return minimum program/write size in bytes for the device + return MBED_CONF_SPINAND_SPINAND_MIN_PROG_SIZE; +} + +bd_size_t SPINANDBlockDevice::get_erase_size() const +{ + return MBED_CONF_SPINAND_SPINAND_BLOCK_SIZE; +} + +bd_size_t SPINANDBlockDevice::get_erase_size(bd_addr_t addr) const +{ + return MBED_CONF_SPINAND_SPINAND_BLOCK_SIZE; +} + +const char *SPINANDBlockDevice::get_type() const +{ + return "SPINAND"; +} + +bd_size_t SPINANDBlockDevice::size() const +{ + return MBED_CONF_SPINAND_SPINAND_FLASH_SIZE; +} + +int SPINANDBlockDevice::get_erase_value() const +{ + return 0xFF; +} + +/********************************/ +/* Different Device Csel Mgmt */ +/********************************/ +static PinName *generate_initialized_active_spinand_csel_arr() +{ + PinName *init_arr = new PinName[SPINAND_MAX_ACTIVE_FLASH_DEVICES]; + for (int i_ind = 0; i_ind < SPINAND_MAX_ACTIVE_FLASH_DEVICES; i_ind++) { + init_arr[i_ind] = NC; + } + return init_arr; +} + +int SPINANDBlockDevice::add_new_csel_instance(PinName csel) +{ + int status = 0; + _devices_mutex->lock(); + if (_number_of_active_spinand_flash_csel >= SPINAND_MAX_ACTIVE_FLASH_DEVICES) { + status = -2; + goto exit_point; + } + + // verify the device is unique(no identical csel already exists) + for (int i_ind = 0; i_ind < SPINAND_MAX_ACTIVE_FLASH_DEVICES; i_ind++) { + if (_active_spinand_flash_csel_arr[i_ind] == csel) { + status = -1; + goto exit_point; + } + } + + // Insert new csel into existing device list + for (int i_ind = 0; i_ind < SPINAND_MAX_ACTIVE_FLASH_DEVICES; i_ind++) { + if (_active_spinand_flash_csel_arr[i_ind] == NC) { + _active_spinand_flash_csel_arr[i_ind] = csel; + break; + } + } + _number_of_active_spinand_flash_csel++; + +exit_point: + _devices_mutex->unlock(); + return status; +} + +int SPINANDBlockDevice::remove_csel_instance(PinName csel) +{ + int status = -1; + _devices_mutex->lock(); + // remove the csel from existing device list + for (int i_ind = 0; i_ind < SPINAND_MAX_ACTIVE_FLASH_DEVICES; i_ind++) { + if (_active_spinand_flash_csel_arr[i_ind] == csel) { + _active_spinand_flash_csel_arr[i_ind] = NC; + if (_number_of_active_spinand_flash_csel > 0) { + _number_of_active_spinand_flash_csel--; + } + status = 0; + break; + } + } + _devices_mutex->unlock(); + return status; +} + +int SPINANDBlockDevice::_set_quad_enable() +{ + uint8_t secur_reg = 0; + + if (false == _is_mem_ready()) { + tr_error("Device not ready, set quad enable failed"); + return -1; + } + + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_SECURE_OTP, + NULL, 0, (char *) &secur_reg, 1)) { + tr_error("Reading Security Register failed"); + } + + secur_reg |= SPINAND_SECURE_BIT_QE; + + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_SET_FEATURE, FEATURES_ADDR_SECURE_OTP, + (char *) &secur_reg, 1, NULL, 0)) { + tr_error("Writing Security Register failed"); + } + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_SECURE_OTP, + NULL, 0, (char *) &secur_reg, 1)) { + tr_error("Reading Security Register failed"); + } + if (false == _is_mem_ready()) { + tr_error("Device not ready, set quad enable failed"); + return -1; + } + + return 0; +} + +int SPINANDBlockDevice::_clear_block_protection() +{ + uint8_t block_protection_reg = 0; + + if (false == _is_mem_ready()) { + tr_error("Device not ready, clearing block protection failed"); + return -1; + } + + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, + NULL, 0, (char *) &block_protection_reg, 1)) { + tr_error("Reading Block Protection Register failed"); + } + + block_protection_reg &= ~SPINAND_BLOCK_PROT_BIT_BP_MASK; + + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_SET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, + (char *) &block_protection_reg, 1, NULL, 0)) { + tr_error("Writing Block Protection Register failed"); + } + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, + NULL, 0, (char *) &block_protection_reg, 1)) { + tr_error("Reading Block Protection Register failed"); + } + if (false == _is_mem_ready()) { + tr_error("Device not ready, clearing block protection failed"); + return -1; + } + + return 0; +} + +int SPINANDBlockDevice::_set_write_enable() +{ + // Check Status Register Busy Bit to Verify the Device isn't Busy + uint8_t status_value = 0; + int status = -1; + + do { + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_WREN, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0)) { + tr_error("Sending WREN command FAILED"); + break; + } + + if (false == _is_mem_ready()) { + tr_error("Device not ready, write failed"); + break; + } + + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, + NULL, 0, + (char *) &status_value, 1)) { // store received value in status_value + tr_error("Reading Status Register failed"); + } + + if ((status_value & SPINAND_STATUS_BIT_WEL) == 0) { + tr_error("_set_write_enable failed - status register 1 value: %u", status_value); + break; + } + + status = 0; + } while (false); + + return status; +} + +bool SPINANDBlockDevice::_is_mem_ready() +{ + // Check Status Register Busy Bit to Verify the Device isn't Busy + uint8_t status_value = 0; + int retries = 0; + bool mem_ready = true; + + do { + rtos::ThisThread::sleep_for(1ms); + retries++; + //Read Status Register 1 from device + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, + NULL, 0, + (char *) &status_value, 1)) { // store received value in status_value + tr_error("Reading Status Register failed"); + } + } while ((status_value & SPINAND_STATUS_BIT_WIP) != 0 && retries < IS_MEM_READY_MAX_RETRIES); + + if ((status_value & SPINAND_STATUS_BIT_WIP) != 0) { + tr_error("_is_mem_ready FALSE: status value = 0x%x ", status_value); + mem_ready = false; + } + return mem_ready; +} + +/***************************************************/ +/*********** QSPI Driver API Functions *************/ +/***************************************************/ +qspi_status_t SPINANDBlockDevice::_qspi_set_frequency(int freq) +{ + return _qspi.set_frequency(freq); +} + +qspi_status_t SPINANDBlockDevice::_qspi_send_read_command(qspi_inst_t read_inst, void *buffer, + bd_addr_t addr, bd_size_t size) +{ + tr_debug("Inst: 0x%xh, addr: %llu, size: %llu", read_inst, addr, size); + + size_t buf_len = size; + + // Send read command to device driver + // Read commands use the best bus mode supported by the part + qspi_status_t status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_COLUMN_ADDR_SIZE, // Alt width should be the same as address width + _address_width,_alt_size, _data_width, 0); + if (QSPI_STATUS_OK != status) { + tr_error("_qspi_configure_format failed"); + return status; + } + + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_PAGE_READ, addr >> 12, NULL, 0, NULL, 0)) { + tr_error("Read page from array failed"); + } + + status = _qspi.configure_format(_inst_width, _address_width, _address_size, _address_width, // Alt width should be the same as address width + _alt_size, _data_width, 0); + if (QSPI_STATUS_OK != status) { + tr_error("_qspi_configure_format failed"); + return status; + } + + if (false == _is_mem_ready()) { + tr_error("Device not ready, clearing block protection failed"); + // return -1; + } + + status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_ROW_ADDR_SIZE, _address_width, // Alt width should be the same as address width + _alt_size, QSPI_CFG_BUS_QUAD, _dummy_cycles); + if (QSPI_STATUS_OK != status) { + tr_error("_qspi_configure_format failed"); + return status; + } + + // Don't check the read status until after we've configured the format back to 1-1-1, to avoid leaving the interface in an + // incorrect state if the read fails. + status = _qspi.read(read_inst, (_alt_size == 0) ? -1 : QSPI_ALT_DEFAULT_VALUE, (unsigned int)addr, (char *)buffer, &buf_len); + + // All commands other than Read use default 1-1-1 bus mode (Program/Erase are constrained by flash memory performance more than bus performance) + qspi_status_t format_status = _qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, _address_size, QSPI_CFG_BUS_SINGLE, 0, QSPI_CFG_BUS_SINGLE, 0); + if (QSPI_STATUS_OK != format_status) { + tr_error("_qspi_configure_format failed"); + return format_status; + } + + if (QSPI_STATUS_OK != status) { + tr_error("QSPI Read failed"); + return status; + } + + return QSPI_STATUS_OK; +} + +qspi_status_t SPINANDBlockDevice::_qspi_send_program_command(qspi_inst_t prog_inst, const void *buffer, + bd_addr_t addr, bd_size_t *size) +{ + tr_debug("Inst: 0x%xh, addr: %llu, size: %llu", prog_inst, addr, *size); + + // Program load commands need 16 bit row address + qspi_status_t status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_ROW_ADDR_SIZE, // Alt width should be the same as address width + _address_width, _alt_size, QSPI_CFG_BUS_QUAD, 0); + if (QSPI_STATUS_OK != status) { + tr_error("_qspi_configure_format failed"); + return status; + } + + // Send program (write) command to device driver + status = _qspi.write(prog_inst, -1, addr, (char *)buffer, (size_t *)size); + if (QSPI_STATUS_OK != status) { + tr_error("QSPI Write failed"); + return status; + } + + // Program execute command need 24 bit column address + qspi_status_t format_status = _qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, SPI_NAND_COLUMN_ADDR_SIZE, QSPI_CFG_BUS_SINGLE, + 0, QSPI_CFG_BUS_SINGLE, 0); + if (QSPI_STATUS_OK != format_status) { + tr_error("_qspi_configure_format failed"); + return format_status; + } + + // Program execute command + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_PROGRAM_EXEC, addr >> 12, NULL, 0, NULL, 0)) { + tr_error("Read page from array failed"); + } + + status = _qspi.configure_format(_inst_width, _address_width, _address_size, _address_width, // Alt width should be the same as address width + _alt_size, _data_width, 0); + if (QSPI_STATUS_OK != status) { + tr_error("_qspi_configure_format failed"); + return status; + } + uint8_t status_value = 0; + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, + NULL, 0, + (char *) &status_value, 1)) { // store received value in status_value + tr_error("Reading Status Register failed"); + } + return QSPI_STATUS_OK; +} + +qspi_status_t SPINANDBlockDevice::_qspi_send_erase_command(qspi_inst_t erase_inst, bd_addr_t addr, bd_size_t size) +{ + tr_debug("Inst: 0x%xh, addr: %llu, size: %llu", erase_inst, addr, size); + + qspi_status_t status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_COLUMN_ADDR_SIZE,// Alt width should be the same as address width + _address_width, _alt_size, _data_width, 0); + if (QSPI_STATUS_OK != status) { + tr_error("_qspi_configure_format failed"); + return status; + } + + // Send erase command to driver + status = _qspi.command_transfer(erase_inst, (int) (addr >> 12), NULL, 0, NULL, 0); + + if (QSPI_STATUS_OK != status) { + tr_error("QSPI Erase failed"); + return status; + } + + status = _qspi.configure_format(_inst_width, _address_width, _address_size, _address_width, // Alt width should be the same as address width + _alt_size, _data_width, 0); + if (QSPI_STATUS_OK != status) { + tr_error("_qspi_configure_format failed"); + return status; + } + uint8_t status_value = 0; + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, + NULL, 0, + (char *) &status_value, 1)) { // store received value in status_value + tr_error("Reading Status Register failed"); + } + return QSPI_STATUS_OK; +} + +qspi_status_t SPINANDBlockDevice::_qspi_send_general_command(qspi_inst_t instruction, bd_addr_t addr, + const char *tx_buffer, bd_size_t tx_length, + const char *rx_buffer, bd_size_t rx_length) +{ + tr_debug("Inst: 0x%xh, addr: %llu, tx length: %llu, rx length: %llu", instruction, addr, tx_length, rx_length); + + // Send a general command instruction to driver + qspi_status_t status = _qspi.command_transfer(instruction, (int)addr, tx_buffer, tx_length, rx_buffer, rx_length); + if (QSPI_STATUS_OK != status) { + tr_error("Sending Generic command: %x", instruction); + return status; + } + + return QSPI_STATUS_OK; +} + diff --git a/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp b/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp index ff6bd9e1f8c..474165e6bd2 100644 --- a/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp +++ b/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp @@ -53,6 +53,10 @@ #include "FlashIAPBlockDevice.h" #endif +#if COMPONENT_SPINAND +#include "SPINANDBlockDevice.h" +#endif + // Debug available #ifndef MODE_DEBUG #define MODE_DEBUG 0 @@ -92,6 +96,7 @@ enum bd_type { sd, flashiap, ospif, + spinand, default_bd }; @@ -163,6 +168,23 @@ static BlockDevice *get_bd_instance(uint8_t bd_type) #endif break; } + case spinand: { +#if COMPONENT_SPINAND + static SPINANDBlockDevice default_bd( + MBED_CONF_SPINAND_SPINAND_IO0, + MBED_CONF_SPINAND_SPINAND_IO1, + MBED_CONF_SPINAND_SPINAND_IO2, + MBED_CONF_SPINAND_SPINAND_IO3, + MBED_CONF_SPINAND_SPINAND_SCK, + MBED_CONF_SPINAND_SPINAND_CSN, + MBED_CONF_SPINAND_SPINAND_POLARITY_MODE, + MBED_CONF_SPINAND_SPINAND_FREQ + ); + return &default_bd; +#endif + break; + } + case dataflash: { #if COMPONENT_DATAFLASH static DataFlashBlockDevice default_bd( @@ -298,7 +320,11 @@ void test_init_bd() if (curr_sector_size > max_sector_size) { max_sector_size = curr_sector_size; } +#if COMPONENT_SPINAND + start_address += 0x40000; +#else start_address += curr_sector_size; +#endif } num_of_sectors = i; } @@ -555,11 +581,19 @@ void test_contiguous_erase_write_read() // helping to avoid test timeouts. Try 256-byte chunks if contiguous_erase_size // (which should be a power of 2) is greater than that. If it's less than // that, the test finishes quickly anyway... +#if COMPONENT_SPINAND + if ((program_size < 2048) && (2048 % program_size == 0) + && (contiguous_erase_size >= 2048) && (contiguous_erase_size % 2048 == 0)) { + utest_printf("using 2048-byte write/read buffer\n"); + write_read_buf_size = 2048; + } +#else if ((program_size < 256) && (256 % program_size == 0) && (contiguous_erase_size >= 256) && (contiguous_erase_size % 256 == 0)) { utest_printf("using 256-byte write/read buffer\n"); write_read_buf_size = 256; } +#endif // Allocate write/read buffer uint8_t *write_read_buf = new (std::nothrow) uint8_t[write_read_buf_size]; @@ -572,7 +606,11 @@ void test_contiguous_erase_write_read() // Pre-fill the to-be-erased region. By pre-filling the region, // we can be sure the test will not pass if the erase doesn't work. +#if COMPONENT_SPINAND + for (bd_size_t offset = 0; start_address + offset < stop_address; offset += 0x40000) { +#else for (bd_size_t offset = 0; start_address + offset < stop_address; offset += write_read_buf_size) { +#endif for (size_t i = 0; i < write_read_buf_size; i++) { write_read_buf[i] = (uint8_t)rand(); } @@ -589,8 +627,11 @@ void test_contiguous_erase_write_read() // Loop through all write/read regions int region = 0; +#if COMPONENT_SPINAND + for (; start_address < stop_address; start_address += 0x40000) { +#else for (; start_address < stop_address; start_address += write_read_buf_size) { - +#endif // Generate test data unsigned int seed = rand(); srand(seed); @@ -790,6 +831,8 @@ void test_get_type_functionality() TEST_ASSERT_EQUAL(0, strcmp(bd_type, "SD")); #elif COMPONENT_FLASHIAP TEST_ASSERT_EQUAL(0, strcmp(bd_type, "FLASHIAP")); +#elif COMPONENT_SPINAND + TEST_ASSERT_EQUAL(0, strcmp(bd_type, "SPINAND")); #endif } @@ -848,11 +891,14 @@ int get_bd_count() #if COMPONENT_OSPIF bd_arr[count++] = ospif; //5 #endif +#if COMPONENT_SPINAND + bd_arr[count++] = spinand; //6 +#endif return count; } -static const char *prefix[] = {"SPIF ", "QSPIF ", "DATAFLASH ", "SD ", "FLASHIAP ", "OSPIF ", "DEFAULT "}; +static const char *prefix[] = {"SPIF ", "QSPIF ", "DATAFLASH ", "SD ", "FLASHIAP ", "OSPIF ","SPINAND ", "DEFAULT "}; int main() { From 7885a27068de9f6a3661216bd3503697d6da91fa Mon Sep 17 00:00:00 2001 From: rogeryou Date: Tue, 9 Mar 2021 16:08:59 +0800 Subject: [PATCH 02/13] add SPI NAND Block device driver --- targets/targets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/targets.json b/targets/targets.json index 80d998cc189..754fc027bb1 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -3832,7 +3832,7 @@ "MX25LM51245G" ], "components_add": [ - "OSPIF" + "SPINAND" ], "macros_add": [ "HSE_VALUE=16000000" From 5f56a5e6d6d26ebf16968acaa8ea7cf71104f273 Mon Sep 17 00:00:00 2001 From: rogeryou Date: Wed, 10 Mar 2021 16:18:22 +0800 Subject: [PATCH 03/13] modify astyle --- .../source/SPINANDBlockDevice.cpp | 82 +++++++++---------- .../blockdevice/general_block_device/main.cpp | 2 +- targets/targets.json | 1 - 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp index 81afc212f25..eb30a5ae27a 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp @@ -49,9 +49,9 @@ using namespace mbed; #define SPINAND_STATUS_BIT_ERASE_FAIL 0x4 // Erase failed #define SPINAND_STATUS_BIT_PROGRAM_FAIL 0x8 // Program failed #define SPINAND_STATUS_BIT_ECC_STATUS_MASK 0x30 // ECC status - #define SPINAND_STATUS_ECC_STATUS_NO_ERR 0x00 - #define SPINAND_STATUS_ECC_STATUS_ERR_COR 0x00 - #define SPINAND_STATUS_ECC_STATUS_ERR_NO_COR 0x00 +#define SPINAND_STATUS_ECC_STATUS_NO_ERR 0x00 +#define SPINAND_STATUS_ECC_STATUS_ERR_COR 0x00 +#define SPINAND_STATUS_ECC_STATUS_ERR_NO_COR 0x00 // Secure OTP Register Bits #define SPINAND_SECURE_BIT_QE 0x01 // Quad enable @@ -61,12 +61,12 @@ using namespace mbed; // Block Protection Register Bits #define SPINAND_BLOCK_PROT_BIT_SP 0x01 -#define SPINAND_BLOCK_PROT_BIT_COMPLE 0x02 +#define SPINAND_BLOCK_PROT_BIT_COMPLE 0x02 #define SPINAND_BLOCK_PROT_BIT_INVERT 0x04 -#define SPINAND_BLOCK_PROT_BIT_BP0 0x08 -#define SPINAND_BLOCK_PROT_BIT_BP1 0x10 -#define SPINAND_BLOCK_PROT_BIT_BP2 0x20 -#define SPINAND_BLOCK_PROT_BIT_BPRWD 0x80 +#define SPINAND_BLOCK_PROT_BIT_BP0 0x08 +#define SPINAND_BLOCK_PROT_BIT_BP1 0x10 +#define SPINAND_BLOCK_PROT_BIT_BP2 0x20 +#define SPINAND_BLOCK_PROT_BIT_BPRWD 0x80 #define SPINAND_BLOCK_PROT_BIT_BP_MASK 0x38 #define SPINAND_BLOCK_PROT_BP_OFFSET 3 @@ -209,7 +209,7 @@ int SPINANDBlockDevice::init() } if (_read_instruction == SPINAND_INST_READ_CACHE4) { - if (QSPI_STATUS_OK !=_set_quad_enable()) { + if (QSPI_STATUS_OK != _set_quad_enable()) { tr_error("SPI NAND Set Quad enable Failed"); status = SPINAND_BD_ERROR_DEVICE_ERROR; goto exit_point; @@ -269,7 +269,7 @@ int SPINANDBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) bd_size_t read_bytes = 0; tr_debug("Read Inst: 0x%xh", _read_instruction); - + while (size > 0) { // Read on _page_size_bytes boundaries (Default 2048 bytes a page) offset = addr % MBED_CONF_SPINAND_SPINAND_PAGE_SIZE; @@ -385,7 +385,7 @@ int SPINANDBlockDevice::erase(bd_addr_t addr, bd_size_t size) } addr += SPINAND_BLOCK_OFFSET; - if(size > MBED_CONF_SPINAND_SPINAND_BLOCK_SIZE) { + if (size > MBED_CONF_SPINAND_SPINAND_BLOCK_SIZE) { size -= MBED_CONF_SPINAND_SPINAND_BLOCK_SIZE; } else { size = 0; @@ -519,19 +519,19 @@ int SPINANDBlockDevice::_set_quad_enable() if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_SECURE_OTP, NULL, 0, (char *) &secur_reg, 1)) { - tr_error("Reading Security Register failed"); - } + tr_error("Reading Security Register failed"); + } secur_reg |= SPINAND_SECURE_BIT_QE; if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_SET_FEATURE, FEATURES_ADDR_SECURE_OTP, (char *) &secur_reg, 1, NULL, 0)) { - tr_error("Writing Security Register failed"); - } + tr_error("Writing Security Register failed"); + } if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_SECURE_OTP, NULL, 0, (char *) &secur_reg, 1)) { - tr_error("Reading Security Register failed"); - } + tr_error("Reading Security Register failed"); + } if (false == _is_mem_ready()) { tr_error("Device not ready, set quad enable failed"); return -1; @@ -551,19 +551,19 @@ int SPINANDBlockDevice::_clear_block_protection() if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, NULL, 0, (char *) &block_protection_reg, 1)) { - tr_error("Reading Block Protection Register failed"); - } + tr_error("Reading Block Protection Register failed"); + } block_protection_reg &= ~SPINAND_BLOCK_PROT_BIT_BP_MASK; if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_SET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, (char *) &block_protection_reg, 1, NULL, 0)) { - tr_error("Writing Block Protection Register failed"); - } + tr_error("Writing Block Protection Register failed"); + } if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, NULL, 0, (char *) &block_protection_reg, 1)) { - tr_error("Reading Block Protection Register failed"); - } + tr_error("Reading Block Protection Register failed"); + } if (false == _is_mem_ready()) { tr_error("Device not ready, clearing block protection failed"); return -1; @@ -588,7 +588,7 @@ int SPINANDBlockDevice::_set_write_enable() tr_error("Device not ready, write failed"); break; } - + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, NULL, 0, (char *) &status_value, 1)) { // store received value in status_value @@ -612,7 +612,7 @@ bool SPINANDBlockDevice::_is_mem_ready() uint8_t status_value = 0; int retries = 0; bool mem_ready = true; - + do { rtos::ThisThread::sleep_for(1ms); retries++; @@ -649,7 +649,7 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_read_command(qspi_inst_t read_inst, // Send read command to device driver // Read commands use the best bus mode supported by the part qspi_status_t status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_COLUMN_ADDR_SIZE, // Alt width should be the same as address width - _address_width,_alt_size, _data_width, 0); + _address_width, _alt_size, _data_width, 0); if (QSPI_STATUS_OK != status) { tr_error("_qspi_configure_format failed"); return status; @@ -668,7 +668,7 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_read_command(qspi_inst_t read_inst, if (false == _is_mem_ready()) { tr_error("Device not ready, clearing block protection failed"); - // return -1; + return -1; } status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_ROW_ADDR_SIZE, _address_width, // Alt width should be the same as address width @@ -701,7 +701,7 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_program_command(qspi_inst_t prog_in bd_addr_t addr, bd_size_t *size) { tr_debug("Inst: 0x%xh, addr: %llu, size: %llu", prog_inst, addr, *size); - + // Program load commands need 16 bit row address qspi_status_t status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_ROW_ADDR_SIZE, // Alt width should be the same as address width _address_width, _alt_size, QSPI_CFG_BUS_QUAD, 0); @@ -725,7 +725,7 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_program_command(qspi_inst_t prog_in return format_status; } - // Program execute command + // Program execute command if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_PROGRAM_EXEC, addr >> 12, NULL, 0, NULL, 0)) { tr_error("Read page from array failed"); } @@ -737,18 +737,18 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_program_command(qspi_inst_t prog_in return status; } uint8_t status_value = 0; - if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, - NULL, 0, - (char *) &status_value, 1)) { // store received value in status_value - tr_error("Reading Status Register failed"); - } + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, + NULL, 0, + (char *) &status_value, 1)) { // store received value in status_value + tr_error("Reading Status Register failed"); + } return QSPI_STATUS_OK; } qspi_status_t SPINANDBlockDevice::_qspi_send_erase_command(qspi_inst_t erase_inst, bd_addr_t addr, bd_size_t size) { tr_debug("Inst: 0x%xh, addr: %llu, size: %llu", erase_inst, addr, size); - + qspi_status_t status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_COLUMN_ADDR_SIZE,// Alt width should be the same as address width _address_width, _alt_size, _data_width, 0); if (QSPI_STATUS_OK != status) { @@ -757,7 +757,7 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_erase_command(qspi_inst_t erase_ins } // Send erase command to driver - status = _qspi.command_transfer(erase_inst, (int) (addr >> 12), NULL, 0, NULL, 0); + status = _qspi.command_transfer(erase_inst, (int)(addr >> 12), NULL, 0, NULL, 0); if (QSPI_STATUS_OK != status) { tr_error("QSPI Erase failed"); @@ -771,11 +771,11 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_erase_command(qspi_inst_t erase_ins return status; } uint8_t status_value = 0; - if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, - NULL, 0, - (char *) &status_value, 1)) { // store received value in status_value - tr_error("Reading Status Register failed"); - } + if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_STATUS, + NULL, 0, + (char *) &status_value, 1)) { // store received value in status_value + tr_error("Reading Status Register failed"); + } return QSPI_STATUS_OK; } diff --git a/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp b/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp index 474165e6bd2..2fb74eae815 100644 --- a/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp +++ b/storage/blockdevice/tests/TESTS/blockdevice/general_block_device/main.cpp @@ -898,7 +898,7 @@ int get_bd_count() return count; } -static const char *prefix[] = {"SPIF ", "QSPIF ", "DATAFLASH ", "SD ", "FLASHIAP ", "OSPIF ","SPINAND ", "DEFAULT "}; +static const char *prefix[] = {"SPIF ", "QSPIF ", "DATAFLASH ", "SD ", "FLASHIAP ", "OSPIF ", "SPINAND ", "DEFAULT "}; int main() { diff --git a/targets/targets.json b/targets/targets.json index 754fc027bb1..b75dceb8e8e 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -3812,7 +3812,6 @@ "STM32L4R9xI" ], "components_add": [ - "FLASHIAP" ], "macros_add": [ "STM32L4R9xx" From 1bca44fe2d0c7e97de9b49a1488c9fb647d4e649 Mon Sep 17 00:00:00 2001 From: rogeryou Date: Wed, 10 Mar 2021 16:47:35 +0800 Subject: [PATCH 04/13] modify astyle --- .../include/SPINAND/SPINANDBlockDevice.h | 2 +- .../source/SPINANDBlockDevice.cpp | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h index 1d6196f60aa..85935cbc233 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h +++ b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h @@ -271,7 +271,7 @@ class SPINANDBlockDevice : public mbed::BlockDevice { /*********************************/ /* Flash Configuration Functions */ /*********************************/ - + // Quad Enable in Sercurity Register int _set_quad_enable(); diff --git a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp index eb30a5ae27a..77d3a238c0e 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp @@ -63,13 +63,13 @@ using namespace mbed; #define SPINAND_BLOCK_PROT_BIT_SP 0x01 #define SPINAND_BLOCK_PROT_BIT_COMPLE 0x02 #define SPINAND_BLOCK_PROT_BIT_INVERT 0x04 -#define SPINAND_BLOCK_PROT_BIT_BP0 0x08 -#define SPINAND_BLOCK_PROT_BIT_BP1 0x10 -#define SPINAND_BLOCK_PROT_BIT_BP2 0x20 +#define SPINAND_BLOCK_PROT_BIT_BP0 0x08 +#define SPINAND_BLOCK_PROT_BIT_BP1 0x10 +#define SPINAND_BLOCK_PROT_BIT_BP2 0x20 #define SPINAND_BLOCK_PROT_BIT_BPRWD 0x80 #define SPINAND_BLOCK_PROT_BIT_BP_MASK 0x38 -#define SPINAND_BLOCK_PROT_BP_OFFSET 3 +#define SPINAND_BLOCK_PROT_BP_OFFSET 3 #define SPINAND_BLOCK_PROT_COMPLE_OFFSET 1 #define IS_MEM_READY_MAX_RETRIES 10000 @@ -286,7 +286,7 @@ int SPINANDBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) buffer = static_cast< uint8_t *>(buffer) + chunk; addr += SPINAND_PAGE_OFFSET; size -= chunk; - + _mutex.unlock(); } @@ -518,18 +518,18 @@ int SPINANDBlockDevice::_set_quad_enable() } if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_SECURE_OTP, - NULL, 0, (char *) &secur_reg, 1)) { + NULL, 0, (char *) &secur_reg, 1)) { tr_error("Reading Security Register failed"); } secur_reg |= SPINAND_SECURE_BIT_QE; if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_SET_FEATURE, FEATURES_ADDR_SECURE_OTP, - (char *) &secur_reg, 1, NULL, 0)) { + (char *) &secur_reg, 1, NULL, 0)) { tr_error("Writing Security Register failed"); } if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_SECURE_OTP, - NULL, 0, (char *) &secur_reg, 1)) { + NULL, 0, (char *) &secur_reg, 1)) { tr_error("Reading Security Register failed"); } if (false == _is_mem_ready()) { @@ -550,18 +550,18 @@ int SPINANDBlockDevice::_clear_block_protection() } if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, - NULL, 0, (char *) &block_protection_reg, 1)) { + NULL, 0, (char *) &block_protection_reg, 1)) { tr_error("Reading Block Protection Register failed"); } block_protection_reg &= ~SPINAND_BLOCK_PROT_BIT_BP_MASK; if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_SET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, - (char *) &block_protection_reg, 1, NULL, 0)) { + (char *) &block_protection_reg, 1, NULL, 0)) { tr_error("Writing Block Protection Register failed"); } if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_GET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, - NULL, 0, (char *) &block_protection_reg, 1)) { + NULL, 0, (char *) &block_protection_reg, 1)) { tr_error("Reading Block Protection Register failed"); } if (false == _is_mem_ready()) { @@ -729,7 +729,7 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_program_command(qspi_inst_t prog_in if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_PROGRAM_EXEC, addr >> 12, NULL, 0, NULL, 0)) { tr_error("Read page from array failed"); } - + status = _qspi.configure_format(_inst_width, _address_width, _address_size, _address_width, // Alt width should be the same as address width _alt_size, _data_width, 0); if (QSPI_STATUS_OK != status) { @@ -763,7 +763,7 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_erase_command(qspi_inst_t erase_ins tr_error("QSPI Erase failed"); return status; } - + status = _qspi.configure_format(_inst_width, _address_width, _address_size, _address_width, // Alt width should be the same as address width _alt_size, _data_width, 0); if (QSPI_STATUS_OK != status) { From 948c8c71c0a5ec28132e73567bc1157a56e13ebd Mon Sep 17 00:00:00 2001 From: rogeryou Date: Thu, 11 Mar 2021 14:36:38 +0800 Subject: [PATCH 05/13] modify astyle --- .../COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp index 77d3a238c0e..b8aec5ba339 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp @@ -58,7 +58,7 @@ using namespace mbed; #define SPINAND_SECURE_BIT_ECC_EN 0x10 // On-die ECC enable #define SPINAND_SECURE_BIT_OTP_EN 0x40 // #define SPINAND_SECURE_BIT_OTP_PROT 0x80 // - + // Block Protection Register Bits #define SPINAND_BLOCK_PROT_BIT_SP 0x01 #define SPINAND_BLOCK_PROT_BIT_COMPLE 0x02 @@ -521,7 +521,7 @@ int SPINANDBlockDevice::_set_quad_enable() NULL, 0, (char *) &secur_reg, 1)) { tr_error("Reading Security Register failed"); } - + secur_reg |= SPINAND_SECURE_BIT_QE; if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_SET_FEATURE, FEATURES_ADDR_SECURE_OTP, @@ -553,7 +553,7 @@ int SPINANDBlockDevice::_clear_block_protection() NULL, 0, (char *) &block_protection_reg, 1)) { tr_error("Reading Block Protection Register failed"); } - + block_protection_reg &= ~SPINAND_BLOCK_PROT_BIT_BP_MASK; if (QSPI_STATUS_OK != _qspi_send_general_command(SPINAND_INST_SET_FEATURE, FEATURES_ADDR_BLOCK_PROTECTION, From d444e39842fefc8fb99dea04d79422fed7150982 Mon Sep 17 00:00:00 2001 From: rogeryou Date: Thu, 11 Mar 2021 14:44:12 +0800 Subject: [PATCH 06/13] remove --- .../include/SPINAND/.SPINANDBlockDevice.h.swo | Bin 28672 -> 0 bytes .../source/.SPINANDBlockDevice.cpp.swo | Bin 77824 -> 0 bytes targets/targets.json | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/.SPINANDBlockDevice.h.swo delete mode 100644 storage/blockdevice/COMPONENT_SPINAND/source/.SPINANDBlockDevice.cpp.swo diff --git a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/.SPINANDBlockDevice.h.swo b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/.SPINANDBlockDevice.h.swo deleted file mode 100644 index b65bdd1d726dc95a256a7872f51747a7efaf40ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 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 diff --git a/storage/blockdevice/COMPONENT_SPINAND/source/.SPINANDBlockDevice.cpp.swo b/storage/blockdevice/COMPONENT_SPINAND/source/.SPINANDBlockDevice.cpp.swo deleted file mode 100644 index a45aeb1e50d748dd5595efa46cf871fcaeef3b6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77824 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 Date: Mon, 15 Mar 2021 15:34:34 +0800 Subject: [PATCH 07/13] Update CMakeLists.txt Modify astyle --- storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt b/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt index fc07dbe3429..5b05ce42bd7 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt +++ b/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt @@ -9,5 +9,5 @@ target_include_directories(mbed-storage-spinand target_sources(mbed-storage-spinand INTERFACE - source/SPINANDBlockDevice.cpp + source/SPINANDBlockDevice.cpp ) From a0ca54c219a5c40d47caeb21b28d23a4a40b12d8 Mon Sep 17 00:00:00 2001 From: rogeryou Date: Mon, 15 Mar 2021 15:36:01 +0800 Subject: [PATCH 08/13] Update SPINANDBlockDevice.h Modify astyle --- .../COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h index 85935cbc233..f54b0543114 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h +++ b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h @@ -1,5 +1,5 @@ /* mbed Microcontroller Library - * Copyright (c) 2018 ARM Limited + * Copyright (c) 2021 ARM Limited * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); From ce2c0a23bdf24d94f2a60a53495b3b2e5391cc3a Mon Sep 17 00:00:00 2001 From: rogeryou Date: Thu, 18 Mar 2021 15:08:50 +0800 Subject: [PATCH 09/13] modify for 1IO read --- .../source/SPINANDBlockDevice.cpp | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp index b8aec5ba339..db3ff9316a6 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp @@ -646,6 +646,15 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_read_command(qspi_inst_t read_inst, size_t buf_len = size; + qspi_bus_width_t data_width; + if (read_inst == SPINAND_INST_READ_CACHE) { + data_width = QSPI_CFG_BUS_SINGLE; + } else if (read_inst == SPINAND_INST_READ_CACHE2) { + data_width = QSPI_CFG_BUS_DUAL; + } else if (read_inst == SPINAND_INST_READ_CACHE4) { + data_width = QSPI_CFG_BUS_QUAD; + } + // Send read command to device driver // Read commands use the best bus mode supported by the part qspi_status_t status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_COLUMN_ADDR_SIZE, // Alt width should be the same as address width @@ -668,11 +677,11 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_read_command(qspi_inst_t read_inst, if (false == _is_mem_ready()) { tr_error("Device not ready, clearing block protection failed"); - return -1; + return QSPI_STATUS_ERROR; } status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_ROW_ADDR_SIZE, _address_width, // Alt width should be the same as address width - _alt_size, QSPI_CFG_BUS_QUAD, _dummy_cycles); + _alt_size, data_width, _dummy_cycles); if (QSPI_STATUS_OK != status) { tr_error("_qspi_configure_format failed"); return status; @@ -702,9 +711,17 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_program_command(qspi_inst_t prog_in { tr_debug("Inst: 0x%xh, addr: %llu, size: %llu", prog_inst, addr, *size); + qspi_bus_width_t data_width; + + if (prog_inst == SPINAND_INST_PP_LOAD) { + data_width = QSPI_CFG_BUS_SINGLE; + } else if (prog_inst == SPINAND_INST_4PP_LOAD) { + data_width = QSPI_CFG_BUS_QUAD; + } + // Program load commands need 16 bit row address qspi_status_t status = _qspi.configure_format(_inst_width, _address_width, SPI_NAND_ROW_ADDR_SIZE, // Alt width should be the same as address width - _address_width, _alt_size, QSPI_CFG_BUS_QUAD, 0); + _address_width, _alt_size, data_width, 0); if (QSPI_STATUS_OK != status) { tr_error("_qspi_configure_format failed"); return status; @@ -795,3 +812,4 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_general_command(qspi_inst_t instruc return QSPI_STATUS_OK; } + From 643a92623bb88b7829d826de55defd4b868fb75a Mon Sep 17 00:00:00 2001 From: rogeryou Date: Wed, 12 May 2021 09:37:24 +0800 Subject: [PATCH 10/13] Update SPINANDBlockDevice.cpp Modify astyle --- .../COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp index db3ff9316a6..61d1e2e1084 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp @@ -648,11 +648,11 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_read_command(qspi_inst_t read_inst, qspi_bus_width_t data_width; if (read_inst == SPINAND_INST_READ_CACHE) { - data_width = QSPI_CFG_BUS_SINGLE; + data_width = QSPI_CFG_BUS_SINGLE; } else if (read_inst == SPINAND_INST_READ_CACHE2) { - data_width = QSPI_CFG_BUS_DUAL; + data_width = QSPI_CFG_BUS_DUAL; } else if (read_inst == SPINAND_INST_READ_CACHE4) { - data_width = QSPI_CFG_BUS_QUAD; + data_width = QSPI_CFG_BUS_QUAD; } // Send read command to device driver @@ -714,9 +714,9 @@ qspi_status_t SPINANDBlockDevice::_qspi_send_program_command(qspi_inst_t prog_in qspi_bus_width_t data_width; if (prog_inst == SPINAND_INST_PP_LOAD) { - data_width = QSPI_CFG_BUS_SINGLE; + data_width = QSPI_CFG_BUS_SINGLE; } else if (prog_inst == SPINAND_INST_4PP_LOAD) { - data_width = QSPI_CFG_BUS_QUAD; + data_width = QSPI_CFG_BUS_QUAD; } // Program load commands need 16 bit row address From 99a3bb98963d4469f6c3e8647c531497584b9b48 Mon Sep 17 00:00:00 2001 From: rogeryou Date: Thu, 10 Jun 2021 09:38:36 +0800 Subject: [PATCH 11/13] Update CMakeLists.txt Fix the issue --- storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt b/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt index 5b05ce42bd7..b743beeaf52 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt +++ b/storage/blockdevice/COMPONENT_SPINAND/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 ARM Limited. All rights reserved. +# Copyright (c) 2021 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 target_include_directories(mbed-storage-spinand From e66784fc808ebef98e172a1ed55a54428f6702d7 Mon Sep 17 00:00:00 2001 From: rogeryou Date: Thu, 10 Jun 2021 09:46:17 +0800 Subject: [PATCH 12/13] Update SPINANDBlockDevice.h Fix the spelling issue --- .../COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h index f54b0543114..b310f53962c 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h +++ b/storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/SPINANDBlockDevice.h @@ -148,7 +148,7 @@ class SPINANDBlockDevice : public mbed::BlockDevice { */ virtual int deinit(); - /** Desctruct SPINANDBlockDevie + /** Destruct SPINANDBlockDevie */ ~SPINANDBlockDevice() { @@ -272,7 +272,7 @@ class SPINANDBlockDevice : public mbed::BlockDevice { /* Flash Configuration Functions */ /*********************************/ - // Quad Enable in Sercurity Register + // Quad Enable in Security Register int _set_quad_enable(); // Clear the device's block protection From 4f29d6a643943c3968280df6dafb8504010e14de Mon Sep 17 00:00:00 2001 From: rogeryou Date: Thu, 10 Jun 2021 09:47:43 +0800 Subject: [PATCH 13/13] Update SPINANDBlockDevice.cpp Fix the spelling issue --- .../COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp index 61d1e2e1084..6f11d8b1546 100644 --- a/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_SPINAND/source/SPINANDBlockDevice.cpp @@ -1,5 +1,5 @@ /* mbed Microcontroller Library - * Copyright (c) 2018 ARM Limited + * Copyright (c) 2021 ARM Limited * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -314,7 +314,7 @@ int SPINANDBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t si //Send WREN if (_set_write_enable() != 0) { - tr_error("Write Enabe failed"); + tr_error("Write Enable failed"); program_failed = true; status = SPINAND_BD_ERROR_WREN_FAILED; goto exit_point;