Mbed OS Device Management example for various ST boards.

This example is known to work great on the following platforms:

  • DISCO_L475E_IOT01A - onboard WiFI and onboard QSPI flash. Board specific example using onboard sensors is available here.
  • DISCO_F413H - onboard WiFI and onboard QSPI flash.
  • DISCO_F469NI - WizFi310 WiFI shield and onboard QSPI flash (see WiFi shield instructions).
  • DISCO_F746NG - onboard Ethernet and using onboard QSPI flash.
  • DISCO_F769NI - onboard Ethernet and using onboard QSPI flash.
  • DISCO_L496AG - WizFi310 WiFI shield and onboard QSPI flash (see WiFi shield instructions).
  • NUCLEO_F207ZG - onboard Ethernet and wired SD card (SD card wiring instructions).
  • NUCLEO_F412ZG - WizFi310 WiFI shield and SD card shield (see WiFi shield instructions).
  • NUCLEO_F429ZI - onboard Ethernet and wired SD card (SD card wiring instructions).
  • NUCLEO_F746ZG - onboard Ethernet and wired SD card (SD card wiring instructions).
  • NUCLEO_F767ZI - onboard Ethernet and wired SD card (SD card wiring instructions).
  • NUCLEO_L476RG - WizFi310 WiFI shield and SD card shield (see WiFi shield instructions).
  • NUCLEO_L496ZG - WizFi310 WiFI shield and SD card shield (see WiFi shield instructions).
  • NUCLEO_L4R5ZI - WizFi310 WiFI shield and SD card shield (see WiFi shield instructions).

Follow the Quick-Start instructions: https://cloud.mbed.com/quick-start

DISCO_L475E_IOT01A DISCO_F413H DISCO_F746NG NUCLEO_F429ZI, NUCLEO_F767ZI, NUCLEO_F746ZG,NUCLEO_F207ZG

Example functionality

This example showcases the following device functionality:

  • Read ADC temperature and ADC vref, and report them as Pelion LWM2M resources (see image below).
  • On user button click, increment Pelion LWM2M button resource.
  • Allow the user to change the state of the board LED from Pelion LWM2M led_state resource and PUT request.

/media/uploads/screamer/pelion_st_adc_reading.png

SD card wiring

The ST Nucleo family of boards don't have storage onboard and therefore you will need an SD card. A limitation on ST Nucleo 144 boards is that there's a conflict between Ethernet and SPI pins on Arduino D11. Due to this, the SD card must be wired to different SPI bus that doesn't conflict with other functionality. The image below provide instructions on how to wire an SD card to a non-conflicting SPI instance.

/media/uploads/screamer/st_nucleo_144_sd.jpeg?v=4

If you are not a first-time Pelion Device Management user your device's SD card may already have connect and update certificates on it. If this is the case, remove and manually format your micro SD card, flash the binary to the device and then re-insert your micro SD card.

WiFi shield setup/wiring

Some ST Nucleo and Discovery boards don't have IP connectivity option, but bundled with a WiFi shield, they can take benefit of full device management capabilities. See links to reference images below on how to wire WizFI310 WiFi shield and/or SD card shield:

Use this example with Mbed CLI

1. Import the application into your desktop:

mbed import /teams/ST/code/pelion-example-common

cd pelion-example-common

2. Install the CLOUD_SDK_API_KEY

mbed config -G CLOUD_SDK_API_KEY <PELION_DM_API_KEY>

For instructions on how to generate your API key, please see the documentation.

3. Initialize firmware credentials (done once per repository). You can use the following command:

mbed dm init -d "<your company name in Pelion DM>" --model-name "<product model identifier>" -q --force

If above command do not work for your Mbed CLI, please consider upgrading Mbed CLI to version 1.8.x or above.

4. Compile and program:

mbed compile -t <toolchain> -m <TARGET_BOARD>

(supported toolchains : GCC_ARM / ARM / IAR)

Files at this revision

API Documentation at this revision

Comitter:
screamer
Date:
Tue Dec 18 18:26:12 2018 +0000
Parent:
15:4e50c457a40c
Child:
17:c154f7ed6649
Commit message:
Remove QSPIF driver, now provided by mbed-os-5.11

Changed in this revision

drivers/storage/COMPONENT_QSPIF/QSPIFBlockDevice.cpp Show diff for this revision Revisions of this file
drivers/storage/COMPONENT_QSPIF/QSPIFBlockDevice.h Show diff for this revision Revisions of this file
drivers/storage/COMPONENT_QSPIF/TESTS/block_device/qspif/main.cpp Show diff for this revision Revisions of this file
drivers/storage/COMPONENT_QSPIF/mbed_lib.json Show diff for this revision Revisions of this file
--- a/drivers/storage/COMPONENT_QSPIF/QSPIFBlockDevice.cpp	Tue Dec 18 17:17:42 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1405 +0,0 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2018 ARM Limited
- *
- * 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.
- */
-
-#include "QSPIFBlockDevice.h"
-#include <string.h>
-#include "mbed_wait_api.h"
-
-#ifndef MBED_CONF_MBED_TRACE_ENABLE
-#define MBED_CONF_MBED_TRACE_ENABLE        0
-#endif
-
-#include "mbed_trace.h"
-#define TRACE_GROUP "QSPIF"
-
-using namespace mbed;
-
-/* Default QSPIF Parameters */
-/****************************/
-#define QSPIF_DEFAULT_READ_SIZE  1
-#define QSPIF_DEFAULT_PROG_SIZE  1
-#define QSPIF_DEFAULT_PAGE_SIZE  256
-#define QSPIF_DEFAULT_SE_SIZE    4096
-#define QSPI_MAX_STATUS_REGISTER_SIZE 3
-#ifndef UINT64_MAX
-#define UINT64_MAX -1
-#endif
-#define QSPI_NO_ADDRESS_COMMAND UINT64_MAX
-// Status Register Bits
-#define QSPIF_STATUS_BIT_WIP        0x1 //Write In Progress
-#define QSPIF_STATUS_BIT_WEL        0x2 // Write Enable Latch
-
-/* SFDP Header Parsing */
-/***********************/
-#define QSPIF_SFDP_HEADER_SIZE 8
-#define QSPIF_PARAM_HEADER_SIZE 8
-
-/* Basic Parameters Table Parsing */
-/**********************************/
-#define SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES 64 /* 16 DWORDS */
-//READ Instruction support according to BUS Configuration
-#define QSPIF_BASIC_PARAM_TABLE_FAST_READ_SUPPORT_BYTE 2
-#define QSPIF_BASIC_PARAM_TABLE_QPI_READ_SUPPORT_BYTE 16
-#define QSPIF_BASIC_PARAM_TABLE_444_READ_INST_BYTE 27
-#define QSPIF_BASIC_PARAM_TABLE_144_READ_INST_BYTE 9
-#define QSPIF_BASIC_PARAM_TABLE_114_READ_INST_BYTE 11
-#define QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE 23
-#define QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE 15
-#define QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE 13
-#define QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE 40
-// Quad Enable Params
-#define QSPIF_BASIC_PARAM_TABLE_QER_BYTE 58
-#define QSPIF_BASIC_PARAM_TABLE_444_MODE_EN_SEQ_BYTE 56
-// Erase Types Params
-#define QSPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE 29
-#define QSPIF_BASIC_PARAM_ERASE_TYPE_2_BYTE 31
-#define QSPIF_BASIC_PARAM_ERASE_TYPE_3_BYTE 33
-#define QSPIF_BASIC_PARAM_ERASE_TYPE_4_BYTE 35
-#define QSPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE 28
-#define QSPIF_BASIC_PARAM_ERASE_TYPE_2_SIZE_BYTE 30
-#define QSPIF_BASIC_PARAM_ERASE_TYPE_3_SIZE_BYTE 32
-#define QSPIF_BASIC_PARAM_ERASE_TYPE_4_SIZE_BYTE 34
-#define QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE 1
-
-// Erase Types Per Region BitMask
-#define ERASE_BITMASK_TYPE4 0x08
-#define ERASE_BITMASK_TYPE1 0x01
-#define ERASE_BITMASK_NONE  0x00
-#define ERASE_BITMASK_ALL   0x0F
-
-#define IS_MEM_READY_MAX_RETRIES 10000
-
-enum qspif_default_instructions {
-    QSPIF_NOP  = 0x00, // No operation
-    QSPIF_PP = 0x02, // Page Program data
-    QSPIF_READ = 0x03, // Read data
-    QSPIF_SE   = 0x20, // 4KB Sector Erase
-    QSPIF_SFDP = 0x5a, // Read SFDP
-    QSPIF_WRSR = 0x01, // Write Status/Configuration Register
-    QSPIF_WRDI = 0x04, // Write Disable
-    QSPIF_RDSR = 0x05, // Read Status Register
-    QSPIF_WREN = 0x06, // Write Enable
-    QSPIF_RSTEN = 0x66, // Reset Enable
-    QSPIF_RST = 0x99, // Reset
-    QSPIF_RDID = 0x9f, // Read Manufacturer and JDEC Device ID
-};
-
-// Local Function
-static int local_math_power(int base, int exp);
-
-/* Init function to initialize Different Devices CS static list */
-static PinName *generate_initialized_active_qspif_csel_arr();
-// Static Members for different devices csel
-// _devices_mutex is used to lock csel list - only one QSPIFBlockDevice instance per csel is allowed
-SingletonPtr<PlatformMutex> QSPIFBlockDevice::_devices_mutex;
-int QSPIFBlockDevice::_number_of_active_qspif_flash_csel = 0;
-PinName *QSPIFBlockDevice::_active_qspif_flash_csel_arr = generate_initialized_active_qspif_csel_arr();
-
-/********* Public API Functions *********/
-/****************************************/
-QSPIFBlockDevice::QSPIFBlockDevice(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), _device_size_bytes(0),
-      _init_ref_count(0),
-      _is_initialized(false)
-{
-    _unique_device_status = add_new_csel_instance(csel);
-
-    if (_unique_device_status == 0) {
-        tr_info("Adding a new QSPIFBlockDevice csel: %d\n", (int)csel);
-    } else if (_unique_device_status == -1) {
-        tr_error("QSPIFBlockDevice with the same csel(%d) already exists\n", (int)csel);
-    } else {
-        tr_error("Too many different QSPIFBlockDevice devices - max allowed: %d\n", QSPIF_MAX_ACTIVE_FLASH_DEVICES);
-    }
-}
-
-int QSPIFBlockDevice::init()
-{
-    if (_unique_device_status == 0) {
-        tr_debug("QSPIFBlockDevice csel: %d", (int)_csel);
-    } else if (_unique_device_status == -1) {
-        tr_error("QSPIFBlockDevice with the same csel(%d) already exists", (int)_csel);
-        return QSPIF_BD_ERROR_DEVICE_NOT_UNIQE;
-    } else {
-        tr_error("Too many different QSPIFBlockDevice devices - max allowed: %d", QSPIF_MAX_ACTIVE_FLASH_DEVICES);
-        return QSPIF_BD_ERROR_DEVICE_MAX_EXCEED;
-    }
-
-    uint8_t vendor_device_ids[4];
-    size_t data_length = 3;
-    int status = QSPIF_BD_ERROR_OK;
-    uint32_t basic_table_addr = 0;
-    size_t basic_table_size = 0;
-    uint32_t sector_map_table_addr = 0;
-    size_t sector_map_table_size = 0;
-    int qspi_status = QSPI_STATUS_OK;
-
-    _mutex.lock();
-
-    if (!_is_initialized) {
-        _init_ref_count = 0;
-    }
-
-    _init_ref_count++;
-
-    if (_init_ref_count != 1) {
-        goto exit_point;
-    }
-
-    //Initialize parameters
-    _min_common_erase_size = 0;
-    _regions_count = 1;
-    _region_erase_types_bitfield[0] = ERASE_BITMASK_NONE;
-
-    //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_24;
-    _data_width = QSPI_CFG_BUS_SINGLE;
-    _dummy_and_mode_cycles = 0;
-    _write_register_inst = QSPIF_WRSR;
-    _read_register_inst = QSPIF_RDSR;
-
-
-    if (QSPI_STATUS_OK != _qspi_set_frequency(_freq)) {
-        tr_error("QSPI Set Frequency Failed");
-        status = QSPIF_BD_ERROR_DEVICE_ERROR;
-        goto exit_point;
-    }
-
-    // Soft Reset
-    if (-1 == _reset_flash_mem()) {
-        tr_error("Init - Unable to initialize flash memory, tests failed");
-        status = QSPIF_BD_ERROR_DEVICE_ERROR;
-        goto exit_point;
-    } else {
-        tr_info("Initialize flash memory OK");
-    }
-
-    /* Read Manufacturer ID (1byte), and Device ID (2bytes)*/
-    qspi_status = _qspi_send_general_command(QSPIF_RDID, QSPI_NO_ADDRESS_COMMAND, NULL, 0, (char *)vendor_device_ids,
-                                             data_length);
-    if (qspi_status != QSPI_STATUS_OK) {
-        tr_error("Init - Read Vendor ID Failed");
-        status = QSPIF_BD_ERROR_DEVICE_ERROR;
-        goto exit_point;
-    }
-
-    tr_debug("Vendor device ID = 0x%x 0x%x 0x%x 0x%x \n", vendor_device_ids[0],
-             vendor_device_ids[1], vendor_device_ids[2], vendor_device_ids[3]);
-    switch (vendor_device_ids[0]) {
-        case 0xbf:
-            // SST devices come preset with block protection
-            // enabled for some regions, issue write disable instruction to clear
-            _set_write_enable();
-            _qspi_send_general_command(QSPIF_WRDI, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0);
-            break;
-    }
-
-    //Synchronize Device
-    if (false == _is_mem_ready()) {
-        tr_error("Init - _is_mem_ready Failed");
-        status = QSPIF_BD_ERROR_READY_FAILED;
-        goto exit_point;
-    }
-
-    /**************************** Parse SFDP Header ***********************************/
-    if (0 != _sfdp_parse_sfdp_headers(basic_table_addr, basic_table_size, sector_map_table_addr, sector_map_table_size)) {
-        tr_error("Init - Parse SFDP Headers Failed");
-        status = QSPIF_BD_ERROR_PARSING_FAILED;
-        goto exit_point;
-    }
-
-    /**************************** Parse Basic Parameters Table ***********************************/
-    if (0 != _sfdp_parse_basic_param_table(basic_table_addr, basic_table_size)) {
-        tr_error("Init - Parse Basic Param Table Failed");
-        status = QSPIF_BD_ERROR_PARSING_FAILED;
-        goto exit_point;
-    }
-
-    /**************************** Parse Sector Map Table ***********************************/
-    _region_size_bytes[0] =
-        _device_size_bytes; // If there's no region map, we have a single region sized the entire device size
-    _region_high_boundary[0] = _device_size_bytes - 1;
-
-    if ((sector_map_table_addr != 0) && (0 != sector_map_table_size)) {
-        tr_info("Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d", sector_map_table_addr,
-                sector_map_table_size);
-        if (0 != _sfdp_parse_sector_map_table(sector_map_table_addr, sector_map_table_size)) {
-            tr_error("Init - Parse Sector Map Table Failed");
-            status = QSPIF_BD_ERROR_PARSING_FAILED;
-            goto exit_point;
-        }
-    }
-
-    // Configure  BUS Mode to 1_1_1 for all commands other than Read
-    _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
-                           QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0);
-
-    _is_initialized = true;
-
-exit_point:
-    _mutex.unlock();
-
-    return status;
-}
-
-int QSPIFBlockDevice::deinit()
-{
-    int result = QSPIF_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(QSPIF_WRDI, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0);
-    if (status != QSPI_STATUS_OK)  {
-        tr_error("Write Disable failed");
-        result = QSPIF_BD_ERROR_DEVICE_ERROR;
-    }
-
-    _is_initialized = false;
-
-    _mutex.unlock();
-
-    if (_unique_device_status == 0) {
-        remove_csel_instance(_csel);
-    }
-
-    return result;
-}
-
-int QSPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
-{
-    int status = QSPIF_BD_ERROR_OK;
-    tr_info("Read Inst: 0x%xh", _read_instruction);
-
-    _mutex.lock();
-
-    // Configure Bus for Reading
-    _qspi_configure_format(_inst_width, _address_width, _address_size, QSPI_CFG_BUS_SINGLE,
-                           QSPI_CFG_ALT_SIZE_8, _data_width, _dummy_and_mode_cycles);
-
-    if (QSPI_STATUS_OK != _qspi_send_read_command(_read_instruction, buffer, addr, size)) {
-        status = QSPIF_BD_ERROR_DEVICE_ERROR;
-        tr_error("Read Command failed");
-    }
-
-    // All commands other than Read use default 1-1-1 Bus mode (Program/Erase are constrained by flash memory performance less than that of the bus)
-    _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
-                           QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0);
-
-    _mutex.unlock();
-    return status;
-
-}
-
-int QSPIFBlockDevice::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 = QSPIF_BD_ERROR_OK;
-    uint32_t offset = 0;
-    uint32_t chunk = 0;
-    bd_size_t written_bytes = 0;
-
-    tr_debug("Program - Buff: 0x%lxh, addr: %llu, size: %llu", (uint32_t)buffer, addr, size);
-
-    while (size > 0) {
-        // Write on _page_size_bytes boundaries (Default 256 bytes a page)
-        offset = addr % _page_size_bytes;
-        chunk = (offset + size < _page_size_bytes) ? size : (_page_size_bytes - offset);
-        written_bytes = chunk;
-
-        _mutex.lock();
-
-        //Send WREN
-        if (_set_write_enable() != 0) {
-            tr_error("Write Enabe failed");
-            program_failed = true;
-            status = QSPIF_BD_ERROR_WREN_FAILED;
-            goto exit_point;
-        }
-
-        result = _qspi_send_program_command(_prog_instruction, buffer, addr, &written_bytes);
-        if ((result != QSPI_STATUS_OK) || (chunk != written_bytes)) {
-            tr_error("Write failed");
-            program_failed = true;
-            status = QSPIF_BD_ERROR_DEVICE_ERROR;
-            goto exit_point;
-        }
-
-        buffer = static_cast<const uint8_t *>(buffer) + chunk;
-        addr += chunk;
-        size -= chunk;
-
-        if (false == _is_mem_ready()) {
-            tr_error("Device not ready after write, failed");
-            program_failed = true;
-            status = QSPIF_BD_ERROR_READY_FAILED;
-            goto exit_point;
-        }
-        _mutex.unlock();
-    }
-
-exit_point:
-    if (program_failed) {
-        _mutex.unlock();
-    }
-
-    return status;
-}
-
-int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
-{
-    int type = 0;
-    uint32_t offset = 0;
-    uint32_t chunk = 4096;
-    unsigned int cur_erase_inst = _erase_instruction;
-    int size = (int)in_size;
-    bool erase_failed = false;
-    int status = QSPIF_BD_ERROR_OK;
-    // Find region of erased address
-    int region = _utils_find_addr_region(addr);
-    // Erase Types of selected region
-    uint8_t bitfield = _region_erase_types_bitfield[region];
-
-    tr_debug("Erase - addr: %llu, in_size: %llu", addr, in_size);
-
-    if ((addr + in_size) > _device_size_bytes) {
-        tr_error("Erase exceeds flash device size");
-        return QSPIF_BD_ERROR_INVALID_ERASE_PARAMS;
-    }
-
-    if (((addr % get_erase_size(addr)) != 0) || (((addr + in_size) % get_erase_size(addr + in_size - 1)) != 0)) {
-        tr_error("Invalid erase - unaligned address and size");
-        return QSPIF_BD_ERROR_INVALID_ERASE_PARAMS;
-    }
-
-    // For each iteration erase the largest section supported by current region
-    while (size > 0) {
-        // iterate to find next Largest erase type ( a. supported by region, b. smaller than size)
-        // find the matching instruction and erase size chunk for that type.
-        type = _utils_iterate_next_largest_erase_type(bitfield, size, (int)addr, _region_high_boundary[region]);
-        cur_erase_inst = _erase_type_inst_arr[type];
-        offset = addr % _erase_type_size_arr[type];
-        chunk = ((offset + size) < _erase_type_size_arr[type]) ? size : (_erase_type_size_arr[type] - offset);
-
-        tr_debug("Erase - addr: %llu, size:%d, Inst: 0x%xh, chunk: %lu ",
-                 addr, size, cur_erase_inst, chunk);
-        tr_debug("Erase - Region: %d, Type:%d ",
-                 region, type);
-
-        _mutex.lock();
-
-        if (_set_write_enable() != 0) {
-            tr_error("QSPI Erase Device not ready - failed");
-            erase_failed = true;
-            status = QSPIF_BD_ERROR_READY_FAILED;
-            goto exit_point;
-        }
-
-        if (QSPI_STATUS_OK != _qspi_send_erase_command(cur_erase_inst, addr, size)) {
-            tr_error("QSPI Erase command failed!");
-            erase_failed = true;
-            status = QSPIF_BD_ERROR_DEVICE_ERROR;
-            goto exit_point;
-        }
-
-        addr += chunk;
-        size -= chunk;
-
-        if ((size > 0) && (addr > _region_high_boundary[region])) {
-            // erase crossed to next region
-            region++;
-            bitfield = _region_erase_types_bitfield[region];
-        }
-
-        if (false == _is_mem_ready()) {
-            tr_error("QSPI After Erase Device not ready - failed");
-            erase_failed = true;
-            status = QSPIF_BD_ERROR_READY_FAILED;
-            goto exit_point;
-        }
-
-        _mutex.unlock();
-    }
-
-exit_point:
-    if (erase_failed) {
-        _mutex.unlock();
-    }
-
-    return status;
-}
-
-bd_size_t QSPIFBlockDevice::get_read_size() const
-{
-    // Assuming all devices support 1byte read granularity
-    return QSPIF_DEFAULT_READ_SIZE;
-}
-
-bd_size_t QSPIFBlockDevice::get_program_size() const
-{
-    // Assuming all devices support 1byte program granularity
-    return QSPIF_DEFAULT_PROG_SIZE;
-}
-
-bd_size_t QSPIFBlockDevice::get_erase_size() const
-{
-    // return minimal erase size supported by all regions (0 if none exists)
-    return _min_common_erase_size;
-}
-
-// Find minimal erase size supported by the region to which the address belongs to
-bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr)
-{
-    // Find region of current address
-    int region = _utils_find_addr_region(addr);
-
-    int min_region_erase_size = _min_common_erase_size;
-    int8_t type_mask = ERASE_BITMASK_TYPE1;
-    int i_ind = 0;
-
-
-    if (region != -1) {
-        type_mask = 0x01;
-
-        for (i_ind = 0; i_ind < 4; i_ind++) {
-            // loop through erase types bitfield supported by region
-            if (_region_erase_types_bitfield[region] & type_mask) {
-
-                min_region_erase_size = _erase_type_size_arr[i_ind];
-                break;
-            }
-            type_mask = type_mask << 1;
-        }
-
-        if (i_ind == 4) {
-            tr_error("No erase type was found for region addr");
-        }
-    }
-
-    return (bd_size_t)min_region_erase_size;
-}
-
-bd_size_t QSPIFBlockDevice::size() const
-{
-    return _device_size_bytes;
-}
-
-int QSPIFBlockDevice::get_erase_value() const
-{
-    return 0xFF;
-}
-
-/********************************/
-/*   Different Device Csel Mgmt */
-/********************************/
-static PinName *generate_initialized_active_qspif_csel_arr()
-{
-    PinName *init_arr = new PinName[QSPIF_MAX_ACTIVE_FLASH_DEVICES];
-    for (int i_ind = 0; i_ind < QSPIF_MAX_ACTIVE_FLASH_DEVICES; i_ind++) {
-        init_arr[i_ind] = NC;
-    }
-    return init_arr;
-}
-
-int QSPIFBlockDevice::add_new_csel_instance(PinName csel)
-{
-    int status = 0;
-    _devices_mutex->lock();
-    if (_number_of_active_qspif_flash_csel >= QSPIF_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 < QSPIF_MAX_ACTIVE_FLASH_DEVICES; i_ind++) {
-        if (_active_qspif_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 < QSPIF_MAX_ACTIVE_FLASH_DEVICES; i_ind++) {
-        if (_active_qspif_flash_csel_arr[i_ind] == NC) {
-            _active_qspif_flash_csel_arr[i_ind] = csel;
-            break;
-        }
-    }
-    _number_of_active_qspif_flash_csel++;
-
-exit_point:
-    _devices_mutex->unlock();
-    return status;
-}
-
-int QSPIFBlockDevice::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 < QSPIF_MAX_ACTIVE_FLASH_DEVICES; i_ind++) {
-        if (_active_qspif_flash_csel_arr[i_ind] == csel) {
-            _active_qspif_flash_csel_arr[i_ind] = NC;
-            if (_number_of_active_qspif_flash_csel > 0) {
-                _number_of_active_qspif_flash_csel--;
-            }
-            status = 0;
-            break;
-        }
-    }
-    _devices_mutex->unlock();
-    return status;
-}
-
-/*********************************************************/
-/********** SFDP Parsing and Detection Functions *********/
-/*********************************************************/
-int QSPIFBlockDevice::_sfdp_parse_sector_map_table(uint32_t sector_map_table_addr, size_t sector_map_table_size)
-{
-    uint8_t sector_map_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
-    uint32_t tmp_region_size = 0;
-    int i_ind = 0;
-    int prev_boundary = 0;
-    // Default set to all type bits 1-4 are common
-    int min_common_erase_type_bits = ERASE_BITMASK_ALL;
-
-
-    qspi_status_t status = _qspi_send_read_command(QSPIF_SFDP, (char *)sector_map_table, sector_map_table_addr /*address*/,
-                                                   sector_map_table_size);
-    if (status != QSPI_STATUS_OK) {
-        tr_error("Init - Read SFDP First Table Failed");
-        return -1;
-    }
-
-    // Currently we support only Single Map Descriptor
-    if (!((sector_map_table[0] & 0x3) == 0x03) && (sector_map_table[1]  == 0x0)) {
-        tr_error("Sector Map - Supporting Only Single! Map Descriptor (not map commands)");
-        return -1;
-    }
-
-    _regions_count = sector_map_table[2] + 1;
-    if (_regions_count > QSPIF_MAX_REGIONS) {
-        tr_error("Supporting up to %d regions, current setup to %d regions - fail",
-                 QSPIF_MAX_REGIONS, _regions_count);
-        return -1;
-    }
-
-    // Loop through Regions and set for each one: size, supported erase types, high boundary offset
-    // Calculate minimum Common Erase Type for all Regions
-    for (i_ind = 0; i_ind < _regions_count; i_ind++) {
-        tmp_region_size = ((*((uint32_t *)&sector_map_table[(i_ind + 1) * 4])) >> 8) & 0x00FFFFFF; // bits 9-32
-        _region_size_bytes[i_ind] = (tmp_region_size + 1) * 256; // Region size is 0 based multiple of 256 bytes;
-        _region_erase_types_bitfield[i_ind] = sector_map_table[(i_ind + 1) * 4] & 0x0F; // bits 1-4
-        min_common_erase_type_bits &= _region_erase_types_bitfield[i_ind];
-        _region_high_boundary[i_ind] = (_region_size_bytes[i_ind] - 1) + prev_boundary;
-        prev_boundary = _region_high_boundary[i_ind] + 1;
-    }
-
-    // Calc minimum Common Erase Size from min_common_erase_type_bits
-    uint8_t type_mask = ERASE_BITMASK_TYPE1;
-    for (i_ind = 0; i_ind < 4; i_ind++) {
-        if (min_common_erase_type_bits & type_mask) {
-            _min_common_erase_size = _erase_type_size_arr[i_ind];
-            break;
-        }
-        type_mask = type_mask << 1;
-    }
-
-    if (i_ind == 4) {
-        // No common erase type was found between regions
-        _min_common_erase_size = 0;
-    }
-
-    return 0;
-}
-
-int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, size_t basic_table_size)
-{
-    uint8_t param_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
-
-    qspi_status_t status = _qspi_send_read_command(QSPIF_SFDP, (char *)param_table, basic_table_addr /*address*/,
-                                                   basic_table_size);
-    if (status != QSPI_STATUS_OK) {
-        tr_error("Init - Read SFDP First Table Failed");
-        return -1;
-    }
-
-    // Check address size, currently only supports 3byte addresses
-    if ((param_table[2] & 0x4) != 0 || (param_table[7] & 0x80) != 0) {
-        tr_error("Init - verify 3byte addressing Failed");
-        return -1;
-    }
-
-    // Get device density (stored in bits - 1)
-    uint32_t density_bits = (
-                                (param_table[7] << 24) |
-                                (param_table[6] << 16) |
-                                (param_table[5] << 8) |
-                                param_table[4]);
-    _device_size_bytes = (density_bits + 1) / 8;
-
-    // Set Default read/program/erase Instructions
-    _read_instruction = QSPIF_READ;
-    _prog_instruction = QSPIF_PP;
-    _erase_instruction = QSPIF_SE;
-
-    _erase_instruction = _erase4k_inst;
-
-    // Set Page Size (QSPI write must be done on Page limits)
-    _page_size_bytes = _sfdp_detect_page_size(param_table, basic_table_size);
-
-    // Detect and Set Erase Types
-    bool shouldSetQuadEnable = false;
-    bool is_qpi_mode = false;
-
-    _sfdp_detect_erase_types_inst_and_size(param_table, basic_table_size, _erase4k_inst, _erase_type_inst_arr,
-                                           _erase_type_size_arr);
-    _erase_instruction = _erase4k_inst;
-
-    // Detect and Set fastest Bus mode (default 1-1-1)
-    _sfdp_detect_best_bus_read_mode(param_table, basic_table_size, shouldSetQuadEnable, is_qpi_mode, _read_instruction);
-    if (true == shouldSetQuadEnable) {
-        _enable_fast_mdoe();
-        // Set Quad Enable and QPI Bus modes if Supported
-        tr_info("Init - Setting Quad Enable");
-        if (0 != _sfdp_set_quad_enabled(param_table)) {
-            tr_error("Device supports Quad bus, but Quad Enable Failed");
-            return -1;
-        }
-        if (true == is_qpi_mode) {
-            tr_info("Init - Setting QPI mode");
-            _sfdp_set_qpi_enabled(param_table);
-        }
-    }
-    return 0;
-}
-
-int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
-                                               uint32_t &sector_map_table_addr, size_t &sector_map_table_size)
-{
-    uint8_t sfdp_header[QSPIF_SFDP_HEADER_SIZE];
-    uint8_t param_header[QSPIF_PARAM_HEADER_SIZE];
-    size_t data_length = QSPIF_SFDP_HEADER_SIZE;
-    bd_addr_t addr = 0x0;
-
-    // Set 1-1-1 bus mode for SFDP header parsing
-    _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
-                           QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 8);
-
-    qspi_status_t status = _qspi_send_read_command(QSPIF_SFDP, (char *)sfdp_header, addr /*address*/, data_length);
-    if (status != QSPI_STATUS_OK) {
-        tr_error("Init - Read SFDP Failed");
-        return -1;
-    }
-
-    // Verify SFDP signature for sanity
-    // Also check that major/minor version is acceptable
-    if (!(memcmp(&sfdp_header[0], "SFDP", 4) == 0 && sfdp_header[5] == 1)) {
-        tr_error("Init - _verify SFDP signature and version Failed");
-        return -1;
-    } else {
-        tr_info("Init - verified SFDP Signature and version Successfully");
-    }
-
-    // Discover Number of Parameter Headers
-    int number_of_param_headers = (int)(sfdp_header[6]) + 1;
-    tr_debug("Number of Param Headers: %d", number_of_param_headers);
-
-
-    addr += QSPIF_SFDP_HEADER_SIZE;
-    data_length = QSPIF_PARAM_HEADER_SIZE;
-
-    // Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
-    for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
-
-        status = _qspi_send_read_command(QSPIF_SFDP, (char *)param_header, addr, data_length);
-        if (status != QSPI_STATUS_OK) {
-            tr_error("Init - Read Param Table %d Failed", i_ind + 1);
-            return -1;
-        }
-
-        // The SFDP spec indicates the standard table is always at offset 0
-        // in the parameter headers, we check just to be safe
-        if (param_header[2] != 1) {
-            tr_error("Param Table %d - Major Version should be 1!", i_ind + 1);
-            return -1;
-        }
-
-        if ((param_header[0] == 0) && (param_header[7] == 0xFF)) {
-            // Found Basic Params Table: LSB=0x00, MSB=0xFF
-            tr_debug("Found Basic Param Table at Table: %d", i_ind + 1);
-            basic_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
-            // Supporting up to 64 Bytes Table (16 DWORDS)
-            basic_table_size = ((param_header[3] * 4) < SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES) ? (param_header[3] * 4) : 64;
-
-        } else if ((param_header[0] == 81) && (param_header[7] == 0xFF)) {
-            // Found Sector Map Table: LSB=0x81, MSB=0xFF
-            tr_debug("Found Sector Map Table at Table: %d", i_ind + 1);
-            sector_map_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
-            sector_map_table_size = param_header[3] * 4;
-
-        }
-        addr += QSPIF_PARAM_HEADER_SIZE;
-
-    }
-    return 0;
-}
-
-int QSPIFBlockDevice::_sfdp_set_qpi_enabled(uint8_t *basic_param_table_ptr)
-{
-    uint8_t config_reg[1];
-
-    // QPI 4-4-4 Enable Procedure is specified in 5 Bits
-    uint8_t en_seq_444_value = (((basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_444_MODE_EN_SEQ_BYTE] & 0xF0) >> 4) | ((
-                                                                                                                           basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_444_MODE_EN_SEQ_BYTE + 1] & 0x01) << 4));
-
-    switch (en_seq_444_value) {
-        case 1:
-        case 2:
-            tr_debug("_sfdp_set_qpi_enabled - send command 38h");
-            if (QSPI_STATUS_OK != _qspi_send_general_command(0x38, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0)) {
-                tr_error("_sfdp_set_qpi_enabled - send command 38h Failed");
-            }
-            break;
-
-        case 4:
-            tr_debug("_sfdp_set_qpi_enabled - send command 35h");
-            if (QSPI_STATUS_OK != _qspi_send_general_command(0x35, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0)) {
-                tr_error("_sfdp_set_qpi_enabled - send command 35h Failed");
-            }
-            break;
-
-        case 8:
-            tr_debug("_sfdp_set_qpi_enabled - set config bit 6 and send command 71h");
-            if (QSPI_STATUS_OK != _qspi_send_general_command(0x65, 0x800003, NULL, 0, (char *)config_reg, 1)) {
-                tr_error("_sfdp_set_qpi_enabled - set config bit 6 command 65h Failed");
-            }
-            config_reg[0] |= 0x40; //Set Bit 6
-            if (QSPI_STATUS_OK != _qspi_send_general_command(0x71, 0x800003, NULL, 0, (char *)config_reg, 1)) {
-                tr_error("_sfdp_set_qpi_enabled - send command 71h Failed");
-            }
-            break;
-
-        case 16:
-            tr_debug("_sfdp_set_qpi_enabled - reset config bits 0-7 and send command 61h");
-            if (QSPI_STATUS_OK != _qspi_send_general_command(0x65, QSPI_NO_ADDRESS_COMMAND, NULL, 0, (char *)config_reg, 1)) {
-                tr_error("_sfdp_set_qpi_enabled - send command 65h Failed");
-            }
-            config_reg[0] &= 0x7F; //Reset Bit 7 of CR
-            if (QSPI_STATUS_OK != _qspi_send_general_command(0x61, QSPI_NO_ADDRESS_COMMAND, NULL, 0, (char *)config_reg, 1)) {
-                tr_error("_sfdp_set_qpi_enabled - send command 61 Failed");
-            }
-            break;
-
-        default:
-            tr_warning("_sfdp_set_qpi_enabled - Unsuported En Seq 444 configuration");
-            break;
-    }
-    return 0;
-}
-
-
-
-int QSPIFBlockDevice::_sfdp_set_quad_enabled(uint8_t *basic_param_table_ptr)
-{
-    int sr_read_size = QSPI_MAX_STATUS_REGISTER_SIZE;
-    int sr_write_size = QSPI_MAX_STATUS_REGISTER_SIZE;
-
-    char status_reg_setup[QSPI_MAX_STATUS_REGISTER_SIZE] = {0};
-    char status_reg[QSPI_MAX_STATUS_REGISTER_SIZE] = {0};
-
-    // QUAD Enable procedure is specified by 3 bits
-    uint8_t qer_value = (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_QER_BYTE] & 0x70) >> 4;
-
-
-    switch (qer_value) {
-        case 0:
-            tr_debug("Device Does not Have a QE Bit, continue based on Read Inst");
-            return 0;
-
-        case 1:
-        case 4:
-            status_reg_setup[1] = 0x02;  //Bit 1 of Status Reg 2
-            tr_debug("Setting QE Bit, Bit 1 of Status Reg 2");
-            break;
-
-        case 2:
-            status_reg_setup[0] = 0x40; // Bit 6 of Status Reg 1
-            sr_write_size = 1;
-            tr_debug("Setting QE Bit, Bit 6 of Status Reg 1");
-            break;
-
-        case 3:
-            status_reg_setup[0] = 0x80; // Bit 7 of Status Reg 1
-            sr_write_size = 1;
-            _write_register_inst = 0x3E;
-            _read_register_inst = 0x3F;
-            tr_debug("Setting QE Bit, Bit 7 of Status Reg 1");
-            break;
-        case 5:
-            status_reg_setup[1] = 0x2; // Bit 1 of status Reg 2
-            _read_register_inst = 0x35;
-            sr_read_size = 1;
-            tr_debug("Setting QE Bit, Bit 1 of Status Reg 2 -special read command");
-            break;
-        default:
-            tr_warning("_setQuadEnable - Unsuported QER configuration");
-            break;
-    }
-
-    // Configure  BUS Mode to 1_1_1 for all commands other than Read
-    _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
-                           QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0);
-
-    // Read Status Register
-    if (QSPI_STATUS_OK == _qspi_send_general_command(_read_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL, 0,
-                                                     status_reg,
-                                                     sr_read_size)) {   // store received values in status_value
-        tr_debug("Reading Status Register Success: value = 0x%x", (int)status_reg[0]);
-    } else {
-        tr_error("Reading Status Register failed");
-        return -1;
-    }
-
-    // Set Bits for Quad Enable
-    for (int i = 0; i < QSPI_MAX_STATUS_REGISTER_SIZE; i++) {
-        status_reg[i] |= status_reg_setup[i];
-    }
-
-    // Write new Status Register Setup
-    if (_set_write_enable() != 0) {
-        tr_error("Write Enabe failed");
-        return -1;
-    }
-
-    if (QSPI_STATUS_OK == _qspi_send_general_command(_write_register_inst, QSPI_NO_ADDRESS_COMMAND, (char *)status_reg,
-                                                     sr_write_size, NULL,
-                                                     0)) {   // Write QE to status_register
-        tr_debug("_setQuadEnable - Writing Status Register Success: value = 0x%x",
-                 (int)status_reg[0]);
-    } else {
-        tr_error("_setQuadEnable - Writing Status Register failed");
-        return -1;
-    }
-
-    if (false == _is_mem_ready()) {
-        tr_error("Device not ready after write, failed");
-        return -1;
-    }
-
-
-    // For Debug
-    memset(status_reg, 0, QSPI_MAX_STATUS_REGISTER_SIZE);
-    if (QSPI_STATUS_OK == _qspi_send_general_command(_read_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL, 0,
-                                                     (char *)status_reg,
-                                                     sr_read_size)) {   // store received values in status_value
-        tr_debug("Reading Status Register Success: value = 0x%x", (int)status_reg[0]);
-    } else {
-        tr_error("Reading Status Register failed");
-        return -1;
-    }
-
-    return 0;
-}
-
-int QSPIFBlockDevice::_sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int basic_param_table_size)
-{
-    unsigned int page_size = QSPIF_DEFAULT_PAGE_SIZE;
-
-    if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE) {
-        // Page Size is specified by 4 Bits (N), calculated by 2^N
-        int page_to_power_size = ((int)basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE]) >> 4;
-        page_size = local_math_power(2, page_to_power_size);
-        tr_debug("Detected Page Size: %d", page_size);
-    } else {
-        tr_debug("Using Default Page Size: %d", page_size);
-    }
-    return page_size;
-}
-
-int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr, int basic_param_table_size,
-                                                             unsigned int &erase4k_inst,
-                                                             unsigned int *erase_type_inst_arr, unsigned int *erase_type_size_arr)
-{
-    erase4k_inst = 0xff;
-    bool found_4Kerase_type = false;
-    uint8_t bitfield = 0x01;
-
-    // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
-    erase4k_inst = basic_param_table_ptr[QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE];
-
-    if (basic_param_table_size > QSPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE) {
-        // Loop Erase Types 1-4
-        for (int i_ind = 0; i_ind < 4; i_ind++) {
-            erase_type_inst_arr[i_ind] = 0xff; //0xFF default for unsupported type
-            erase_type_size_arr[i_ind] = local_math_power(2,
-                                                          basic_param_table_ptr[QSPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]); // Size given as 2^N
-            tr_info("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), erase_type_inst_arr[i_ind],
-                    erase_type_size_arr[i_ind]);
-            if (erase_type_size_arr[i_ind] > 1) {
-                // if size==1 type is not supported
-                erase_type_inst_arr[i_ind] = basic_param_table_ptr[QSPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE + 2 * i_ind];
-
-                if ((erase_type_size_arr[i_ind] < _min_common_erase_size) || (_min_common_erase_size == 0)) {
-                    //Set default minimal common erase for singal region
-                    _min_common_erase_size = erase_type_size_arr[i_ind];
-                }
-
-                // SFDP standard requires 4K Erase type to exist and its instruction to be identical to legacy field erase instruction
-                if (erase_type_size_arr[i_ind] == 4096) {
-                    found_4Kerase_type = true;
-                    if (erase4k_inst != erase_type_inst_arr[i_ind]) {
-                        //Verify 4KErase Type is identical to Legacy 4K erase type specified in Byte 1 of Param Table
-                        erase4k_inst = erase_type_inst_arr[i_ind];
-                        tr_warning("_detectEraseTypesInstAndSize - Default 4K erase Inst is different than erase type Inst for 4K");
-
-                    }
-                }
-                _region_erase_types_bitfield[0] |= bitfield; // If there's no region map, set region "0" types bitfield as defualt;
-            }
-
-            tr_info("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1), erase_type_inst_arr[i_ind],
-                    erase_type_size_arr[i_ind]);
-            bitfield = bitfield << 1;
-        }
-    }
-
-    if (false == found_4Kerase_type) {
-        tr_warning("Couldn't find Erase Type for 4KB size");
-    }
-    return 0;
-}
-
-int QSPIFBlockDevice::_sfdp_detect_best_bus_read_mode(uint8_t *basic_param_table_ptr, int basic_param_table_size,
-                                                      bool &set_quad_enable,
-                                                      bool &is_qpi_mode, unsigned int &read_inst)
-{
-    set_quad_enable = false;
-    is_qpi_mode = false;
-    uint8_t examined_byte;
-
-    do { // compound statement is the loop body
-
-        if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_QPI_READ_SUPPORT_BYTE) {
-            examined_byte = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_QPI_READ_SUPPORT_BYTE];
-
-            if (examined_byte & 0x10) {
-                // QPI 4-4-4 Supported
-                read_inst = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_444_READ_INST_BYTE];
-                set_quad_enable = true;
-                is_qpi_mode = true;
-                _dummy_and_mode_cycles = (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_444_READ_INST_BYTE - 1] >> 5)
-                                         + (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_444_READ_INST_BYTE - 1] & 0x1F);
-                tr_debug("Read Bus Mode set to 4-4-4, Instruction: 0x%xh", _read_instruction);
-                //_inst_width = QSPI_CFG_BUS_QUAD;
-                _address_width = QSPI_CFG_BUS_QUAD;
-                _data_width = QSPI_CFG_BUS_QUAD;
-
-                break;
-            }
-        }
-
-
-        examined_byte = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_FAST_READ_SUPPORT_BYTE];
-        if (examined_byte & 0x40) {
-            //  Fast Read 1-4-4 Supported
-            read_inst = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_144_READ_INST_BYTE];
-            set_quad_enable = true;
-            // dummy cycles + mode cycles = Dummy Cycles
-            _dummy_and_mode_cycles = (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_144_READ_INST_BYTE - 1] >> 5)
-                                     + (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_144_READ_INST_BYTE - 1] & 0x1F);
-            _address_width = QSPI_CFG_BUS_QUAD;
-            _data_width = QSPI_CFG_BUS_QUAD;
-            tr_debug("Read Bus Mode set to 1-4-4, Instruction: 0x%xh", _read_instruction);
-            break;
-        }
-
-        if (examined_byte & 0x80) {
-            //  Fast Read 1-1-4 Supported
-            read_inst = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_114_READ_INST_BYTE];
-            set_quad_enable = true;
-            _dummy_and_mode_cycles = (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_114_READ_INST_BYTE - 1] >> 5)
-                                     + (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_114_READ_INST_BYTE - 1] & 0x1F);
-            _data_width = QSPI_CFG_BUS_QUAD;
-            tr_debug("Read Bus Mode set to 1-1-4, Instruction: 0x%xh", _read_instruction);
-            break;
-        }
-        examined_byte = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_QPI_READ_SUPPORT_BYTE];
-        if (examined_byte & 0x01) {
-            //  Fast Read 2-2-2 Supported
-            read_inst = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE];
-            _dummy_and_mode_cycles = (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE - 1] >> 5)
-                                     + (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE - 1] & 0x1F);
-            _address_width = QSPI_CFG_BUS_DUAL;
-            _data_width = QSPI_CFG_BUS_DUAL;
-            tr_info("Read Bus Mode set to 2-2-2, Instruction: 0x%xh", _read_instruction);
-            break;
-        }
-
-        examined_byte = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_FAST_READ_SUPPORT_BYTE];
-        if (examined_byte & 0x20) {
-            //  Fast Read 1-2-2 Supported
-            read_inst = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE];
-            _dummy_and_mode_cycles = (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE - 1] >> 5)
-                                     + (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE - 1] & 0x1F);
-            _address_width = QSPI_CFG_BUS_DUAL;
-            _data_width = QSPI_CFG_BUS_DUAL;
-            tr_debug("Read Bus Mode set to 1-2-2, Instruction: 0x%xh", _read_instruction);
-            break;
-        }
-        if (examined_byte & 0x01) {
-            // Fast Read 1-1-2 Supported
-            read_inst = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE];
-            _dummy_and_mode_cycles = (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE - 1] >> 5)
-                                     + (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE - 1] & 0x1F);
-            _data_width = QSPI_CFG_BUS_DUAL;
-            tr_debug("Read Bus Mode set to 1-1-2, Instruction: 0x%xh", _read_instruction);
-            break;
-        }
-        tr_debug("Read Bus Mode set to 1-1-1, Instruction: 0x%xh", _read_instruction);
-    } while (false);
-
-    return 0;
-}
-
-int QSPIFBlockDevice::_reset_flash_mem()
-{
-    // Perform Soft Reset of the Device prior to initialization
-    int status = 0;
-    char status_value[QSPI_MAX_STATUS_REGISTER_SIZE] = {0};
-    tr_info("_reset_flash_mem:");
-    //Read the Status Register from device
-    if (QSPI_STATUS_OK == _qspi_send_general_command(QSPIF_RDSR, QSPI_NO_ADDRESS_COMMAND, NULL, 0, status_value,
-                                                     QSPI_MAX_STATUS_REGISTER_SIZE)) {   // store received values in status_value
-        tr_debug("Reading Status Register Success: value = 0x%x", (int)status_value[0]);
-    } else {
-        tr_error("Reading Status Register failed: value = 0x%x", (int)status_value[0]);
-        status = -1;
-    }
-
-    if (0 == status) {
-        //Send Reset Enable
-        if (QSPI_STATUS_OK == _qspi_send_general_command(QSPIF_RSTEN, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL,
-                                                         0)) {    // store received values in status_value
-            tr_debug("Sending RSTEN Success");
-        } else {
-            tr_error("Sending RSTEN failed");
-            status = -1;
-        }
-
-
-        if (0 == status) {
-            //Send Reset
-            if (QSPI_STATUS_OK == _qspi_send_general_command(QSPIF_RST, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL,
-                                                             0)) {   // store received values in status_value
-                tr_debug("Sending RST Success");
-            } else {
-                tr_error("Sending RST failed");
-                status = -1;
-            }
-
-            _is_mem_ready();
-        }
-    }
-
-    return status;
-}
-
-bool QSPIFBlockDevice::_is_mem_ready()
-{
-    // Check Status Register Busy Bit to Verify the Device isn't Busy
-    char status_value[QSPI_MAX_STATUS_REGISTER_SIZE];
-    int retries = 0;
-    bool mem_ready = true;
-
-    do {
-        wait_ms(1);
-        retries++;
-        //Read the Status Register from device
-        memset(status_value, 0xFF, QSPI_MAX_STATUS_REGISTER_SIZE);
-        if (QSPI_STATUS_OK != _qspi_send_general_command(QSPIF_RDSR, QSPI_NO_ADDRESS_COMMAND, NULL, 0, status_value,
-                                                         QSPI_MAX_STATUS_REGISTER_SIZE)) {   // store received values in status_value
-            tr_error("Reading Status Register failed");
-        }
-    } while ((status_value[0] & QSPIF_STATUS_BIT_WIP) != 0 && retries < IS_MEM_READY_MAX_RETRIES);
-
-    if ((status_value[0] & QSPIF_STATUS_BIT_WIP) != 0) {
-        tr_error("_is_mem_ready FALSE: status value = 0x%x ", (int)status_value[0]);
-        mem_ready = false;
-    }
-    return mem_ready;
-}
-
-int QSPIFBlockDevice::_set_write_enable()
-{
-    // Check Status Register Busy Bit to Verify the Device isn't Busy
-    char status_value[QSPI_MAX_STATUS_REGISTER_SIZE];
-    int status = -1;
-
-    do {
-        if (QSPI_STATUS_OK !=  _qspi_send_general_command(QSPIF_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;
-        }
-
-        memset(status_value, 0, QSPI_MAX_STATUS_REGISTER_SIZE);
-        if (QSPI_STATUS_OK != _qspi_send_general_command(QSPIF_RDSR, QSPI_NO_ADDRESS_COMMAND, NULL, 0, status_value,
-                                                         QSPI_MAX_STATUS_REGISTER_SIZE)) {   // store received values in status_value
-            tr_error("Reading Status Register failed");
-            break;
-        }
-
-        if ((status_value[0] & QSPIF_STATUS_BIT_WEL) == 0) {
-            tr_error("_set_write_enable failed");
-            break;
-        }
-        status = 0;
-    } while (false);
-    return status;
-}
-
-int QSPIFBlockDevice::_enable_fast_mdoe()
-{
-    char status_reg[QSPI_MAX_STATUS_REGISTER_SIZE] = {0};
-    unsigned int read_conf_register_inst = 0x15;
-    char status_reg_qer_setup[QSPI_MAX_STATUS_REGISTER_SIZE] = {0};
-
-    status_reg_qer_setup[2] = 0x2; // Bit 1 of config Reg 2
-
-    // Configure  BUS Mode to 1_1_1 for all commands other than Read
-    _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
-                           QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0);
-
-    // Read Status Register
-    if (QSPI_STATUS_OK == _qspi_send_general_command(read_conf_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL, 0,
-                                                     &status_reg[1],
-                                                     QSPI_MAX_STATUS_REGISTER_SIZE - 1)) {  // store received values in status_value
-        tr_debug("Reading Config Register Success: value = 0x%x", (int)status_reg[2]);
-    } else {
-        tr_error("Reading Config Register failed");
-        return -1;
-    }
-
-    // Set Bits for Quad Enable
-    for (int i = 0; i < QSPI_MAX_STATUS_REGISTER_SIZE; i++) {
-        status_reg[i] |= status_reg_qer_setup[i];
-    }
-
-    // Write new Status Register Setup
-    if (_set_write_enable() != 0) {
-        tr_error("Write Enabe failed");
-        return -1;
-    }
-
-    if (QSPI_STATUS_OK == _qspi_send_general_command(_write_register_inst, QSPI_NO_ADDRESS_COMMAND, status_reg,
-                                                     QSPI_MAX_STATUS_REGISTER_SIZE, NULL,
-                                                     0)) {   // Write Fast mode bit to status_register
-        tr_debug("fast mode enable - Writing Config Register Success: value = 0x%x",
-                 (int)status_reg[2]);
-    } else {
-        tr_error("fast mode enable - Writing Config Register failed");
-        return -1;
-    }
-
-    if (false == _is_mem_ready()) {
-        tr_error("Device not ready after write, failed");
-        return -1;
-    }
-
-    // For Debug
-    memset(status_reg, 0, QSPI_MAX_STATUS_REGISTER_SIZE);
-    if (QSPI_STATUS_OK == _qspi_send_general_command(read_conf_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL, 0,
-                                                     &status_reg[1],
-                                                     QSPI_MAX_STATUS_REGISTER_SIZE - 1)) {  // store received values in status_value
-        tr_debug("Verifying Config Register Success: value = 0x%x", (int)status_reg[2]);
-    } else {
-        tr_error("Verifying Config Register failed");
-        return -1;
-    }
-
-    return 0;
-}
-
-/*********************************************/
-/************* Utility Functions *************/
-/*********************************************/
-int QSPIFBlockDevice::_utils_find_addr_region(bd_size_t offset)
-{
-    //Find the region to which the given offset belong to
-    if ((offset > _device_size_bytes) || (_regions_count == 0)) {
-        return -1;
-    }
-
-    if (_regions_count == 1) {
-        return 0;
-    }
-
-    for (int i_ind = _regions_count - 2; i_ind >= 0; i_ind--) {
-
-        if (offset > _region_high_boundary[i_ind]) {
-            return (i_ind + 1);
-        }
-    }
-    return -1;
-
-}
-
-int QSPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, int size, int offset, int boundry)
-{
-    // Iterate on all supported Erase Types of the Region to which the offset belong to.
-    // Iterates from highest type to lowest
-    uint8_t type_mask = ERASE_BITMASK_TYPE4;
-    int i_ind  = 0;
-    int largest_erase_type = 0;
-    for (i_ind = 3; i_ind >= 0; i_ind--) {
-        if (bitfield & type_mask) {
-            largest_erase_type = i_ind;
-            if ((size > (int)(_erase_type_size_arr[largest_erase_type])) &&
-                    ((boundry - offset) > (int)(_erase_type_size_arr[largest_erase_type]))) {
-                break;
-            } else {
-                bitfield &= ~type_mask;
-            }
-        }
-        type_mask = type_mask >> 1;
-    }
-
-    if (i_ind == 4) {
-        tr_error("No erase type was found for current region addr");
-    }
-    return largest_erase_type;
-
-}
-
-/***************************************************/
-/*********** QSPI Driver API Functions *************/
-/***************************************************/
-qspi_status_t QSPIFBlockDevice::_qspi_set_frequency(int freq)
-{
-    return _qspi.set_frequency(freq);
-}
-
-qspi_status_t QSPIFBlockDevice::_qspi_send_read_command(unsigned int read_inst, void *buffer, bd_addr_t addr,
-                                                        bd_size_t size)
-{
-    // Send Read command to device driver
-    size_t buf_len = size;
-
-    if (_qspi.read(read_inst, -1, (unsigned int)addr, (char *)buffer, &buf_len) != QSPI_STATUS_OK) {
-        tr_error("Read failed");
-        return QSPI_STATUS_ERROR;
-    }
-
-    return QSPI_STATUS_OK;
-
-}
-
-qspi_status_t QSPIFBlockDevice::_qspi_send_program_command(unsigned int progInst, const void *buffer, bd_addr_t addr,
-                                                           bd_size_t *size)
-{
-    // Send Program (write) command to device driver
-    qspi_status_t result = QSPI_STATUS_OK;
-
-    result = _qspi.write(progInst, -1, addr, (char *)buffer, (size_t *)size);
-    if (result != QSPI_STATUS_OK) {
-        tr_error("QSPI Write failed");
-    }
-
-    return result;
-}
-
-qspi_status_t QSPIFBlockDevice::_qspi_send_erase_command(unsigned int erase_inst, bd_addr_t addr, bd_size_t size)
-{
-    // Send Erase Instruction command to driver
-    qspi_status_t result = QSPI_STATUS_OK;
-
-    tr_info("Inst: 0x%xh, addr: %llu, size: %llu", erase_inst, addr, size);
-
-    result = _qspi.command_transfer(erase_inst, // command to send
-                                    (((int)addr) & 0x00FFF000), // Align addr to 4096
-                                    NULL,                 // do not transmit
-                                    0,              // do not transmit
-                                    NULL,                 // just receive two bytes of data
-                                    0); // store received values in status_value
-
-    if (QSPI_STATUS_OK != result) {
-        tr_error("QSPI Erase failed");
-    }
-
-    return result;
-
-}
-
-qspi_status_t QSPIFBlockDevice::_qspi_send_general_command(unsigned int instruction, bd_addr_t addr,
-                                                           const char *tx_buffer,
-                                                           size_t tx_length, const char *rx_buffer, size_t 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;
-}
-
-qspi_status_t QSPIFBlockDevice::_qspi_configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width,
-                                                       qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width,
-                                                       int dummy_cycles)
-{
-    // Configure QSPI driver Bus format
-    qspi_status_t status = _qspi.configure_format(inst_width, address_width, address_size, alt_width, alt_size, data_width,
-                                                  dummy_cycles);
-
-    return status;
-}
-
-/*********************************************/
-/************** Local Functions **************/
-/*********************************************/
-static int local_math_power(int base, int exp)
-{
-    // Integer X^Y function, used to calculate size fields given in 2^N format
-    int result = 1;
-    while (exp) {
-        result *= base;
-        exp--;
-    }
-    return result;
-}
--- a/drivers/storage/COMPONENT_QSPIF/QSPIFBlockDevice.h	Tue Dec 18 17:17:42 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,364 +0,0 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2018 ARM Limited
- *
- * 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_QSPIF_BLOCK_DEVICE_H
-#define MBED_QSPIF_BLOCK_DEVICE_H
-
-#include "QSPI.h"
-#include "BlockDevice.h"
-
-/** Enum qspif standard error codes
- *
- *  @enum qspif_bd_error
- */
-enum qspif_bd_error {
-    QSPIF_BD_ERROR_OK                    = 0,     /*!< no error */
-    QSPIF_BD_ERROR_DEVICE_ERROR          = BD_ERROR_DEVICE_ERROR, /*!< device specific error -4001 */
-    QSPIF_BD_ERROR_PARSING_FAILED        = -4002, /* SFDP Parsing failed */
-    QSPIF_BD_ERROR_READY_FAILED          = -4003, /* Wait for  Mem Ready failed */
-    QSPIF_BD_ERROR_WREN_FAILED           = -4004, /* Write Enable Failed */
-    QSPIF_BD_ERROR_INVALID_ERASE_PARAMS  = -4005, /* Erase command not on sector aligned addresses or exceeds device size */
-    QSPIF_BD_ERROR_DEVICE_NOT_UNIQE      = -4006, /* Only one instance per csel is allowed */
-    QSPIF_BD_ERROR_DEVICE_MAX_EXCEED     = -4007 /* Max active QSPIF devices exceeded */
-};
-
-/** Enum qspif polarity mode
- *
- *  @enum qspif_polarity_mode
- */
-enum qspif_polarity_mode {
-    QSPIF_POLARITY_MODE_0 = 0, /* CPOL=0, CPHA=0 */
-    QSPIF_POLARITY_MODE_1      /* CPOL=1, CPHA=1 */
-};
-
-#define QSPIF_MAX_REGIONS   10
-#define MAX_NUM_OF_ERASE_TYPES 4
-#define QSPIF_MAX_ACTIVE_FLASH_DEVICES 10
-
-/** BlockDevice for SFDP based flash devices over QSPI bus
- *
- *  @code
- *  // Here's an example using QSPI flash device on DISCO_L476VG target
- *  #include "mbed.h"
- *  #include "QSPIFBlockDevice.h"
- *
- *  QSPIFBlockDevice block_device(QSPI_FLASH1_IO0, QSPI_FLASH1_IO1, QSPI_FLASH1_IO2, QSPI_FLASH1_IO3,
- *                                QSPI_FLASH1_SCK, QSPI_FLASH1_CSN, QSPIF_POLARITY_MODE_0, MBED_CONF_QSPIF_QSPI_FREQ);
- *
- *  int main()
- *  {
- *      printf("QSPI SFDP Flash Block Device example\n");
- *
- *      // Initialize the SPI 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("QSPIF BD size: %llu\n",         block_device.size());
- *      printf("QSPIF BD read size: %llu\n",    block_device.get_read_size());
- *      printf("QSPIF BD program size: %llu\n", block_device.get_program_size());
- *      printf("QSPIF 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 QSPIFBlockDevice : public BlockDevice {
-public:
-    /** Create QSPIFBlockDevice - An SFDP based 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 (QSPIF_POLARITY_MODE_0/QSPIF_POLARITY_MODE_1)
-     *         default value = 0
-     *  @param freq Clock frequency of the QSPI bus (defaults to 40MHz)
-     *
-     */
-    QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName csel,
-                     int clock_mode, int freq = MBED_CONF_QSPIF_QSPI_FREQ);
-
-    /** Initialize a block device
-     *
-     *  @return         QSPIF_BD_ERROR_OK(0) - success
-     *                  QSPIF_BD_ERROR_DEVICE_ERROR - device driver transaction failed
-     *                  QSPIF_BD_ERROR_READY_FAILED - Waiting for Memory ready failed or timedout
-     *                  QSPIF_BD_ERROR_PARSING_FAILED - unexpected format or values in one of the SFDP tables
-     */
-    virtual int init();
-
-    /** Deinitialize a block device
-     *
-     *  @return         QSPIF_BD_ERROR_OK(0) - success
-     *                  QSPIF_BD_ERROR_DEVICE_ERROR - device driver transaction failed
-     */
-    virtual int deinit();
-
-    /** Desctruct QSPIFBlockDevie
-      */
-    ~QSPIFBlockDevice()
-    {
-        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         QSPIF_BD_ERROR_OK(0) - success
-     *                  QSPIF_BD_ERROR_DEVICE_ERROR - device driver transaction failed
-     */
-    virtual int read(void *buffer, bd_addr_t addr, 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         QSPIF_BD_ERROR_OK(0) - success
-     *                  QSPIF_BD_ERROR_DEVICE_ERROR - device driver transaction failed
-     *                  QSPIF_BD_ERROR_READY_FAILED - Waiting for Memory ready failed or timed out
-     *                  QSPIF_BD_ERROR_WREN_FAILED - Write Enable failed
-     *                  QSPIF_BD_ERROR_PARSING_FAILED - unexpected format or values in one of the SFDP tables
-     */
-    virtual int program(const void *buffer, bd_addr_t addr, 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         QSPIF_BD_ERROR_OK(0) - success
-     *                  QSPIF_BD_ERROR_DEVICE_ERROR - device driver transaction failed
-     *                  QSPIF_BD_ERROR_READY_FAILED - Waiting for Memory ready failed or timed out
-     *                  QSPIF_BD_ERROR_WREN_FAILED - Write Enable failed
-     *                  QSPIF_BD_ERROR_PARSING_FAILED - unexpected format or values in one of the SFDP tables
-     *                  QSPIF_BD_ERROR_INVALID_ERASE_PARAMS - Trying to erase unaligned address or size
-     */
-    virtual int erase(bd_addr_t addr, bd_size_t size);
-
-    /** Get the size of a readable block
-     *
-     *  @return         Size of a readable block in bytes
-     */
-    virtual 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 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 bd_size_t get_erase_size() const;
-
-    /** Get the size of minimal eraseable sector size of given address
-     *
-     *  @param addr     Any address within block queried for erase sector size (can be any address within flash size offset)
-     *  @return         Size of minimal erase sector size, in given address region, in bytes
-     *  @note Must be a multiple of the program size
-     */
-    virtual bd_size_t get_erase_size(bd_addr_t addr);
-
-    /** 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 bd_size_t size() const;
-
-private:
-    // Internal functions
-
-
-    /********************************/
-    /*   Different Device Csel Mgmt */
-    /********************************/
-    // Add a new QSPI device CS to existing devices list.
-    // Only one QSPIFBlockDevice 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(unsigned int prog_instruction, const void *buffer, bd_addr_t addr,
-                                             bd_size_t *size);
-
-    // Send Read command to Driver
-    qspi_status_t _qspi_send_read_command(unsigned int read_instruction, void *buffer, bd_addr_t addr, bd_size_t size);
-
-    // Send Erase Instruction using command_transfer command to Driver
-    qspi_status_t _qspi_send_erase_command(unsigned int erase_instruction, bd_addr_t addr, bd_size_t size);
-
-    // Send Generic command_transfer command to Driver
-    qspi_status_t _qspi_send_general_command(unsigned int instruction_int, bd_addr_t addr, const char *tx_buffer,
-                                             size_t tx_length, const char *rx_buffer, size_t rx_length);
-
-    // Send Bus configure_format command to Driver
-    qspi_status_t _qspi_configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width,
-                                         qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width,
-                                         int dummy_cycles);
-
-    // Send set_frequency command to Driver
-    qspi_status_t _qspi_set_frequency(int freq);
-
-    /*********************************/
-    /* Flash Configuration Functions */
-    /*********************************/
-    // Soft Reset Flash Memory
-    int _reset_flash_mem();
-
-    // Configure Write Enable in Status Register
-    int _set_write_enable();
-
-    // Wait on status register until write not-in-progress
-    bool _is_mem_ready();
-
-    // Enable Fast Mode - for flash chips with low power default
-    int _enable_fast_mdoe();
-
-    /****************************************/
-    /* SFDP Detection and Parsing Functions */
-    /****************************************/
-    // Parse SFDP Headers and retrieve Basic Param and Sector Map Tables (if exist)
-    int _sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
-                                 uint32_t &sector_map_table_addr, size_t &sector_map_table_size);
-
-    // Parse and Detect required Basic Parameters from Table
-    int _sfdp_parse_basic_param_table(uint32_t basic_table_addr, size_t basic_table_size);
-
-    // Parse and read information required by Regions Secotr Map
-    int _sfdp_parse_sector_map_table(uint32_t sector_map_table_addr, size_t sector_map_table_size);
-
-    // Detect fastest read Bus mode supported by device
-    int _sfdp_detect_best_bus_read_mode(uint8_t *basic_param_table_ptr, int basic_param_table_size, bool &set_quad_enable,
-                                        bool &is_qpi_mode, unsigned int &read_inst);
-
-    // Enable Quad mode if supported (1-1-4, 1-4-4, 4-4-4 bus modes)
-    int _sfdp_set_quad_enabled(uint8_t *basic_param_table_ptr);
-
-    // Enable QPI mode (4-4-4) is supported
-    int _sfdp_set_qpi_enabled(uint8_t *basic_param_table_ptr);
-
-    // Set Page size for program
-    int _sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int basic_param_table_size);
-
-    // Detect all supported erase types
-    int _sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr, int basic_param_table_size,
-                                               unsigned int &erase4k_inst,
-                                               unsigned int *erase_type_inst_arr, unsigned int *erase_type_size_arr);
-
-    /***********************/
-    /* Utilities Functions */
-    /***********************/
-    // Find the region to which the given offset belong to
-    int _utils_find_addr_region(bd_size_t offset);
-
-    // Iterate on all supported Erase Types of the Region to which the offset belong to.
-    // Iterates from highest type to lowest
-    int _utils_iterate_next_largest_erase_type(uint8_t &bitfield, int size, int offset, int boundry);
-
-private:
-    // Internal Members
-
-    // 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 QSPIFBlockDevice instance
-    // _devices_mutex is used to lock csel list - only one QSPIFBlockDevice instance per csel is allowed
-    static SingletonPtr<PlatformMutex> _devices_mutex;
-    static int _number_of_active_qspif_flash_csel;
-    static PinName *_active_qspif_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
-    unsigned int _read_instruction;
-    unsigned int _prog_instruction;
-    unsigned int _erase_instruction;
-    unsigned int _erase4k_inst;  // Legacy 4K erase instruction (default 0x20h)
-    unsigned int _write_register_inst; // Write status/config register instruction may vary between chips
-    unsigned int _read_register_inst; // Read status/config register instruction may vary between chips
-
-    // Up To 4 Erase Types are supported by SFDP (each with its own command Instruction and Size)
-    unsigned int _erase_type_inst_arr[MAX_NUM_OF_ERASE_TYPES];
-    unsigned int _erase_type_size_arr[MAX_NUM_OF_ERASE_TYPES];
-
-    // Sector Regions Map
-    int _regions_count; //number of regions
-    int _region_size_bytes[QSPIF_MAX_REGIONS]; //regions size in bytes
-    bd_size_t _region_high_boundary[QSPIF_MAX_REGIONS]; //region high address offset boundary
-    //Each Region can support a bit combination of any of the 4 Erase Types
-    uint8_t _region_erase_types_bitfield[QSPIF_MAX_REGIONS];
-    unsigned int _min_common_erase_size; // minimal common erase size for all regions (0 if none exists)
-
-    unsigned int _page_size_bytes; // Page size - 256 Bytes default
-    int _freq;
-    bd_size_t _device_size_bytes;
-
-    // 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 bytes for address
-    qspi_bus_width_t _data_width; //Bus width for Data phase
-    int _dummy_and_mode_cycles; // Number of Dummy and Mode Bits required by Current Bus Mode
-
-    uint32_t _init_ref_count;
-    bool _is_initialized;
-};
-
-#endif
--- a/drivers/storage/COMPONENT_QSPIF/TESTS/block_device/qspif/main.cpp	Tue Dec 18 17:17:42 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2018 ARM Limited
- *
- * 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.
- */
-#include "greentea-client/test_env.h"
-#include "unity.h"
-#include "utest.h"
-#include "QSPIFBlockDevice.h"
-#include "mbed_trace.h"
-#include "rtos/Thread.h"
-#include <stdlib.h>
-
-using namespace utest::v1;
-
-#define TEST_BLOCK_COUNT 10
-#define TEST_ERROR_MASK 16
-#define QSPIF_TEST_NUM_OF_THREADS 5
-
-const struct {
-    const char *name;
-    bd_size_t (BlockDevice::*method)() const;
-} ATTRS[] = {
-    {"read size",    &BlockDevice::get_read_size},
-    {"program size", &BlockDevice::get_program_size},
-    {"erase size",   &BlockDevice::get_erase_size},
-    {"total size",   &BlockDevice::size},
-};
-
-static SingletonPtr<PlatformMutex> _mutex;
-
-
-// Mutex is protecting rand() per srand for buffer writing and verification.
-// Mutex is also protecting printouts for clear logs.
-// Mutex is NOT protecting Block Device actions: erase/program/read - which is the purpose of the multithreaded test!
-void basic_erase_program_read_test(QSPIFBlockDevice &blockD, bd_size_t block_size, uint8_t *write_block,
-                                   uint8_t *read_block, unsigned addrwidth)
-{
-    int err = 0;
-    _mutex->lock();
-    // Find a random block
-    bd_addr_t block = (rand() * block_size) % blockD.size();
-
-    // Use next random number as temporary seed to keep
-    // the address progressing in the pseudorandom sequence
-    unsigned seed = rand();
-
-    // Fill with random sequence
-    srand(seed);
-    for (bd_size_t i_ind = 0; i_ind < block_size; i_ind++) {
-        write_block[i_ind] = 0xff & rand();
-    }
-    // Write, sync, and read the block
-    utest_printf("\ntest  %0*llx:%llu...", addrwidth, block, block_size);
-    _mutex->unlock();
-
-    err = blockD.erase(block, block_size);
-    TEST_ASSERT_EQUAL(0, err);
-
-    err = blockD.program(write_block, block, block_size);
-    TEST_ASSERT_EQUAL(0, err);
-
-    err = blockD.read(read_block, block, block_size);
-    TEST_ASSERT_EQUAL(0, err);
-
-    _mutex->lock();
-    // Check that the data was unmodified
-    srand(seed);
-    int val_rand;
-    for (bd_size_t i_ind = 0; i_ind < block_size; i_ind++) {
-        val_rand = rand();
-        if ((0xff & val_rand) != read_block[i_ind]) {
-            utest_printf("\n Assert Failed Buf Read - block:size: %llx:%llu \n", block, block_size);
-            utest_printf("\n pos: %llu, exp: %02x, act: %02x, wrt: %02x \n", i_ind, (0xff & val_rand), read_block[i_ind],
-                         write_block[i_ind]);
-        }
-        TEST_ASSERT_EQUAL(0xff & val_rand, read_block[i_ind]);
-    }
-    _mutex->unlock();
-}
-
-void test_qspif_random_program_read_erase()
-{
-    utest_printf("\nTest Random Program Read Erase Starts..\n");
-
-    QSPIFBlockDevice blockD(QSPI_FLASH1_IO0, QSPI_FLASH1_IO1, QSPI_FLASH1_IO2, QSPI_FLASH1_IO3,
-                            QSPI_FLASH1_SCK, QSPI_FLASH1_CSN, QSPIF_POLARITY_MODE_0, MBED_CONF_QSPIF_QSPI_FREQ);
-
-    int err = blockD.init();
-    TEST_ASSERT_EQUAL(0, err);
-
-    for (unsigned atr = 0; atr < sizeof(ATTRS) / sizeof(ATTRS[0]); atr++) {
-        static const char *prefixes[] = {"", "k", "M", "G"};
-        for (int i_ind = 3; i_ind >= 0; i_ind--) {
-            bd_size_t size = (blockD.*ATTRS[atr].method)();
-            if (size >= (1ULL << 10 * i_ind)) {
-                utest_printf("%s: %llu%sbytes (%llubytes)\n",
-                             ATTRS[atr].name, size >> 10 * i_ind, prefixes[i_ind], size);
-                break;
-            }
-        }
-    }
-
-    bd_size_t block_size = blockD.get_erase_size();
-    unsigned addrwidth = ceil(log(float(blockD.size() - 1)) / log(float(16))) + 1;
-
-    uint8_t *write_block = new (std::nothrow) uint8_t[block_size];
-    uint8_t *read_block = new (std::nothrow) uint8_t[block_size];
-    if (!write_block || !read_block) {
-        utest_printf("\n Not enough memory for test");
-        goto end;
-    }
-
-    for (int b = 0; b < TEST_BLOCK_COUNT; b++) {
-        basic_erase_program_read_test(blockD, block_size, write_block, read_block, addrwidth);
-    }
-
-    err = blockD.deinit();
-    TEST_ASSERT_EQUAL(0, err);
-
-end:
-    delete[] write_block;
-    delete[] read_block;
-}
-
-void test_qspif_unaligned_erase()
-{
-
-    utest_printf("\nTest Unaligned Erase Starts..\n");
-
-    QSPIFBlockDevice blockD(QSPI_FLASH1_IO0, QSPI_FLASH1_IO1, QSPI_FLASH1_IO2, QSPI_FLASH1_IO3,
-                            QSPI_FLASH1_SCK, QSPI_FLASH1_CSN, QSPIF_POLARITY_MODE_0, MBED_CONF_QSPIF_QSPI_FREQ);
-
-    int err = blockD.init();
-    TEST_ASSERT_EQUAL(0, err);
-
-    for (unsigned atr = 0; atr < sizeof(ATTRS) / sizeof(ATTRS[0]); atr++) {
-        static const char *prefixes[] = {"", "k", "M", "G"};
-        for (int i_ind = 3; i_ind >= 0; i_ind--) {
-            bd_size_t size = (blockD.*ATTRS[atr].method)();
-            if (size >= (1ULL << 10 * i_ind)) {
-                utest_printf("%s: %llu%sbytes (%llubytes)\n",
-                             ATTRS[atr].name, size >> 10 * i_ind, prefixes[i_ind], size);
-                break;
-            }
-        }
-    }
-
-    bd_addr_t addr = 0;
-    bd_size_t sector_erase_size = blockD.get_erase_size(addr);
-    unsigned addrwidth = ceil(log(float(blockD.size() - 1)) / log(float(16))) + 1;
-
-    utest_printf("\ntest  %0*llx:%llu...", addrwidth, addr, sector_erase_size);
-
-    //unaligned start address
-    addr += 1;
-    err = blockD.erase(addr, sector_erase_size - 1);
-    TEST_ASSERT_EQUAL(QSPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
-
-    err = blockD.erase(addr, sector_erase_size);
-    TEST_ASSERT_EQUAL(QSPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
-
-    err = blockD.erase(addr, 1);
-    TEST_ASSERT_EQUAL(QSPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
-
-    //unaligned end address
-    addr = 0;
-
-    err = blockD.erase(addr, 1);
-    TEST_ASSERT_EQUAL(QSPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
-
-    err = blockD.erase(addr, sector_erase_size + 1);
-    TEST_ASSERT_EQUAL(QSPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
-
-    //erase size exceeds flash device size
-    err = blockD.erase(addr, blockD.size() + 1);
-    TEST_ASSERT_EQUAL(QSPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
-
-    // Valid erase
-    err = blockD.erase(addr, sector_erase_size);
-    TEST_ASSERT_EQUAL(QSPIF_BD_ERROR_OK, err);
-
-    err = blockD.deinit();
-    TEST_ASSERT_EQUAL(0, err);
-}
-
-
-
-static void test_qspif_thread_job(void *vBlockD/*, int thread_num*/)
-{
-    static int thread_num = 0;
-    thread_num++;
-    QSPIFBlockDevice *blockD = (QSPIFBlockDevice *)vBlockD;
-    utest_printf("\n Thread %d Started \n", thread_num);
-
-    bd_size_t block_size = blockD->get_erase_size();
-    unsigned addrwidth = ceil(log(float(blockD->size() - 1)) / log(float(16))) + 1;
-
-    uint8_t *write_block = new (std::nothrow) uint8_t[block_size];
-    uint8_t *read_block = new (std::nothrow) uint8_t[block_size];
-    if (!write_block || !read_block) {
-        utest_printf("\n Not enough memory for test");
-        goto end;
-    }
-
-    for (int b = 0; b < TEST_BLOCK_COUNT; b++) {
-        basic_erase_program_read_test((*blockD), block_size, write_block, read_block, addrwidth);
-    }
-
-end:
-    delete[] write_block;
-    delete[] read_block;
-}
-
-void test_qspif_multi_threads()
-{
-
-    utest_printf("\nTest Multi Threaded Erase/Program/Read Starts..\n");
-
-    QSPIFBlockDevice blockD(QSPI_FLASH1_IO0, QSPI_FLASH1_IO1, QSPI_FLASH1_IO2, QSPI_FLASH1_IO3,
-                            QSPI_FLASH1_SCK, QSPI_FLASH1_CSN, QSPIF_POLARITY_MODE_0, MBED_CONF_QSPIF_QSPI_FREQ);
-
-    int err = blockD.init();
-    TEST_ASSERT_EQUAL(0, err);
-
-    for (unsigned atr = 0; atr < sizeof(ATTRS) / sizeof(ATTRS[0]); atr++) {
-        static const char *prefixes[] = {"", "k", "M", "G"};
-        for (int i_ind = 3; i_ind >= 0; i_ind--) {
-            bd_size_t size = (blockD.*ATTRS[atr].method)();
-            if (size >= (1ULL << 10 * i_ind)) {
-                utest_printf("%s: %llu%sbytes (%llubytes)\n",
-                             ATTRS[atr].name, size >> 10 * i_ind, prefixes[i_ind], size);
-                break;
-            }
-        }
-    }
-
-    rtos::Thread qspif_bd_thread[QSPIF_TEST_NUM_OF_THREADS];
-
-    osStatus threadStatus;
-    int i_ind;
-
-    for (i_ind = 0; i_ind < QSPIF_TEST_NUM_OF_THREADS; i_ind++) {
-        threadStatus = qspif_bd_thread[i_ind].start(test_qspif_thread_job, (void *)&blockD);
-        if (threadStatus != 0) {
-            utest_printf("\n Thread %d Start Failed!", i_ind + 1);
-        }
-    }
-
-    for (i_ind = 0; i_ind < QSPIF_TEST_NUM_OF_THREADS; i_ind++) {
-        qspif_bd_thread[i_ind].join();
-    }
-
-    err = blockD.deinit();
-    TEST_ASSERT_EQUAL(0, err);
-}
-
-
-
-
-// Test setup
-utest::v1::status_t test_setup(const size_t number_of_cases)
-{
-    GREENTEA_SETUP(60, "default_auto");
-    return verbose_test_setup_handler(number_of_cases);
-}
-
-Case cases[] = {
-    Case("Testing unaligned erase blocks", test_qspif_unaligned_erase),
-    Case("Testing read write random blocks", test_qspif_random_program_read_erase),
-    Case("Testing Multi Threads Erase Program Read", test_qspif_multi_threads)
-};
-
-Specification specification(test_setup, cases);
-
-
-int main()
-{
-    mbed_trace_init();
-    utest_printf("MAIN STARTS\n");
-    return !Harness::run(specification);
-}
--- a/drivers/storage/COMPONENT_QSPIF/mbed_lib.json	Tue Dec 18 17:17:42 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-{
-"name": "qspif",
-    "config": {
-        "QSPI_IO0": "QSPI_FLASH1_IO0",
-        "QSPI_IO1": "QSPI_FLASH1_IO1",
-        "QSPI_IO2": "QSPI_FLASH1_IO2",
-        "QSPI_IO3": "QSPI_FLASH1_IO3",
-        "QSPI_SCK": "QSPI_FLASH1_SCK",
-        "QSPI_CSN": "QSPI_FLASH1_CSN",
-        "QSPI_POLARITY_MODE": 0,
-        "QSPI_FREQ": "40000000"
-    },
-    "target_overrides": {
-        "DISCO_F413ZH": {
-            "QSPI_FREQ": "80000000"
-        },
-        "DISCO_L475VG_IOT01A": {
-            "QSPI_FREQ": "8000000"
-        },
-        "DISCO_L476VG": {
-            "QSPI_FREQ": "80000000"
-        },
-        "DISCO_F469NI": {
-            "QSPI_FREQ": "80000000"
-        },
-        "NRF52840_DK": {
-            "QSPI_FREQ": "32000000"
-        }
-    }
-}