Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers QSPIFBlockDevice.cpp Source File

QSPIFBlockDevice.cpp

00001 
00002 /* mbed Microcontroller Library
00003  * Copyright (c) 2016 ARM Limited
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 //#include "./mbed-os/drivers/qspi.h"
00019 
00020 #define DEVICE_QSPI 1
00021 
00022 #include "QSPIFBlockDevice.h"
00023 
00024 /* Default QSPIF Parameters */
00025 /****************************/
00026 #define QSPIF_DEFAULT_READ_SIZE  1
00027 #define QSPIF_DEFAULT_PROG_SIZE  1
00028 #define QSPIF_DEFAULT_SE_SIZE    4096
00029 #define QSPI_MAX_STATUS_REGISTER_SIZE 2
00030 #define QSPI_STATUS_REGISTER_WRITE_TIMEOUT_MSEC 50
00031 #define QSPIF_DEFAULT_TIMEOUT_MSEC    1
00032 
00033 
00034 /* SFDP Header Parsing */
00035 /***********************/
00036 #define QSPIF_SFDP_HEADER_SIZE 8
00037 #define QSPIF_PARAM_HEADER_SIZE 8
00038 
00039 /* Basic Parameters Table Parsing */
00040 /**********************************/
00041 #define SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES 64 /* 16 DWORDS */
00042 //READ Instruction support according to BUS Configuration
00043 #define QSPIF_BASIC_PARAM_TABLE_FAST_READ_SUPPORT_BYTE 2
00044 #define QSPIF_BASIC_PARAM_TABLE_QPI_READ_SUPPOR_BYTE 16
00045 #define QSPIF_BASIC_PARAM_TABLE_444_READ_INST_BYTE 27
00046 #define QSPIF_BASIC_PARAM_TABLE_144_READ_INST_BYTE 9
00047 #define QSPIF_BASIC_PARAM_TABLE_114_READ_INST_BYTE 11
00048 #define QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE 23
00049 #define QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE 15
00050 #define QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE 13
00051 #define QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE 40
00052 // Quad Enable Params
00053 #define QSPIF_BASIC_PARAM_TABLE_QER_BYTE 58
00054 #define QSPIF_BASIC_PARAM_TABLE_444_MODE_EN_SEQ_BYTE 56
00055 // Erase Types Params
00056 #define QSPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE 29
00057 #define QSPIF_BASIC_PARAM_ERASE_TYPE_2_BYTE 31
00058 #define QSPIF_BASIC_PARAM_ERASE_TYPE_3_BYTE 33
00059 #define QSPIF_BASIC_PARAM_ERASE_TYPE_4_BYTE 35
00060 #define QSPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE 28
00061 #define QSPIF_BASIC_PARAM_ERASE_TYPE_2_SIZE_BYTE 30
00062 #define QSPIF_BASIC_PARAM_ERASE_TYPE_3_SIZE_BYTE 32
00063 #define QSPIF_BASIC_PARAM_ERASE_TYPE_4_SIZE_BYTE 34
00064 #define QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE 1
00065 
00066 // Debug Printouts
00067 #define QSPIF_DEBUG_ERROR     1
00068 #define QSPIF_DEBUG_WARNING 2
00069 #define QSPIF_DEBUG_INFO     3
00070 #define QSPIF_DEBUG_DEBUG     4
00071 #define QSPIF_DEBUG_TRACE     5
00072 // #define QSPIF_DEFAULT_DEBUG_LEVEL  QSPIF_DEBUG_INFO
00073 // #define QSPIF_DEFAULT_DEBUG_LEVEL  QSPIF_DEBUG_TRACE
00074 #define QSPIF_DEFAULT_DEBUG_LEVEL  QSPIF_DEBUG_WARNING
00075 
00076 
00077 enum qspif_default_instructions {
00078     QSPIF_NOP  = 0x00, // No operation
00079     QSPIF_PP = 0x02, // Page Program data
00080     QSPIF_READ = 0x03, // Read data
00081     QSPIF_SE   = 0x20, // 4KB Sector Erase
00082     QSPIF_SFDP = 0x5a, // Read SFDP
00083 
00084     QSPIF_WRSR = 0x01, // Write Status/Configuration Register
00085     QSPIF_WRDI = 0x04, // Write Disable
00086     QSPIF_RDSR = 0x05, // Read Status Register
00087     QSPIF_WREN = 0x06, // Write Enable
00088 
00089     QSPIF_RSTEN = 0x66, // Reset Enable
00090     QSPIF_RST = 0x99, // Reset
00091     QSPIF_RDID = 0x9f, // Read Manufacturer and JDEC Device ID
00092 };
00093 
00094 #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
00095 
00096 #define QSPIF_LOG(level,...) {\
00097         if (level <= QSPIF_DEFAULT_DEBUG_LEVEL) {\
00098           char str[256];\
00099           sprintf(str, "\n[%s][%s:%d], ", __FILENAME__, __FUNCTION__, __LINE__);\
00100             sprintf(str+strlen(str),__VA_ARGS__);\
00101           printf(str);\
00102         }\
00103     }
00104 
00105 // Mutex is used for some QSPI Driver commands that must be done sequentially with no other commands in between
00106 // e.g. (1)Set Write Enable, (2)Program, (3)Wait Memory Ready
00107 SingletonPtr<PlatformMutex> QSPIFBlockDevice::_mutex;
00108 
00109 
00110 /********* Public API Functions *********/
00111 /****************************************/
00112 
00113 QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName csel,
00114                                    int clock_mode, int freq)
00115     : _qspi(io0, io1, io2, io3, sclk, csel, clock_mode), _deviceSizeBytes(0)
00116 {
00117     //_cs = 1;
00118     is_initialized = false;
00119     _minCommonEraseSize = 0;
00120     _regions_count = 1;
00121     _region_erase_types[0] = 0;
00122 
00123     //Default Bus Setup 1_1_1 with 0 dummy and mode cycles
00124     _inst_width = QSPI_CFG_BUS_SINGLE;
00125     _address_width = QSPI_CFG_BUS_SINGLE;
00126     _address_size = QSPI_CFG_ADDR_SIZE_24;
00127     _alt_width = QSPI_CFG_BUS_SINGLE;
00128     _alt_size = QSPI_CFG_ALT_SIZE_8;
00129     _data_width = QSPI_CFG_BUS_SINGLE;
00130     _dummy_and_mode_cycles = 0;
00131 
00132     if (QSPI_STATUS_OK != _qspiSetFrequency(freq)) {
00133         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: QSPI Set Frequency Failed");
00134     }
00135 }
00136 
00137 
00138 int QSPIFBlockDevice::init()
00139 {
00140 
00141     uint8_t vendor_device_ids[4];
00142     size_t data_length = 3;
00143 
00144     _mutex->lock();
00145     if (is_initialized == true) {
00146         _mutex->unlock();
00147         return 0;
00148     }
00149 
00150     // Soft Reset
00151     if ( -1 == _resetFlashMem()) {
00152         QSPIF_LOG(QSPIF_DEBUG_INFO, "ERROR: init - Unable to initialize flash memory, tests failed\n");
00153         return -1;
00154     } else {
00155         QSPIF_LOG(QSPIF_DEBUG_INFO, "INFO: Initialize flash memory OK\n");
00156     }
00157 
00158 
00159 
00160     /* Read Manufacturer ID (1byte), and Device ID (2bytes)*/
00161     int status = _qspiSendReadCommand(QSPIF_RDID, (char *)vendor_device_ids, 0x0 /*address*/, data_length);
00162     if (status != QSPI_STATUS_OK) {
00163         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - Read Vendor ID Failed");
00164         return status;
00165     }
00166 
00167     switch (vendor_device_ids[0]) {
00168         case 0xbf:
00169             // SST devices come preset with block protection
00170             // enabled for some regions, issue write disable instruction to clear
00171             _setWriteEnable();
00172             //_cmdwrite(0x98, 0, 0, 0x0, NULL);
00173             _qspiSendGeneralCommand(QSPIF_WRDI, -1, NULL, 0, NULL, 0);
00174 
00175             break;
00176     }
00177 
00178     //Synchronize Device
00179     if ( false == _isMemReady()) {
00180         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - _isMemReady Failed");
00181         return BD_ERROR_DEVICE_ERROR;
00182     }
00183 
00184 
00185     /**************************** Parse SFDP Header ***********************************/
00186     uint32_t basic_table_addr = NULL;
00187     size_t basic_table_size = 0;
00188     uint32_t sector_map_table_addr = NULL;
00189     size_t sector_map_table_size = 0;
00190     if ( 0 != _sfdpParseSFDPHeaders(basic_table_addr, basic_table_size, sector_map_table_addr, sector_map_table_size)) {
00191         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - Parse SFDP Headers Failed");
00192         return BD_ERROR_DEVICE_ERROR;
00193     }
00194 
00195 
00196     /**************************** Parse Basic Parameters Table ***********************************/
00197     if ( 0 != _sfdpParseBasicParamTable(basic_table_addr, basic_table_size) ) {
00198         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - Parse Basic Param Table Failed");
00199         return BD_ERROR_DEVICE_ERROR;
00200     }
00201 
00202 
00203     /**************************** Parse Sector Map Table ***********************************/
00204     _region_size_bytes[0] =
00205         _deviceSizeBytes; // If there's no region map, we have a single region sized the entire device size
00206     _region_high_boundary[0] = _deviceSizeBytes - 1;
00207 
00208     if ( (sector_map_table_addr != NULL) && (0 != sector_map_table_size) ) {
00209         QSPIF_LOG(QSPIF_DEBUG_INFO, "INFO: init - Parsing Sector Map Table - addr: 0x%xh, Size: %d", sector_map_table_addr,
00210                   sector_map_table_size);
00211         if ( 0 != _sfdpParseSectorMapTable(sector_map_table_addr, sector_map_table_size) ) {
00212             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - Parse Sector Map Table Failed");
00213             return BD_ERROR_DEVICE_ERROR;
00214         }
00215     }
00216 
00217 
00218     // Configure  BUS Mode to 1_1_1 for all commands other than Read
00219     _qspiConfiureFormat( QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
00220                          QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0);
00221     /*// Soft Reset
00222     if( -1 == _resetFlashMem()) {
00223         QSPIF_LOG(QSPIF_DEBUG_INFO,"ERROR: init - Unable to initialize flash memory, tests failed\n");
00224         return -1;
00225     } else {
00226         QSPIF_LOG(QSPIF_DEBUG_INFO,"INFO: Initialize flash memory OK\n");
00227     }*/
00228 
00229     is_initialized = true;
00230     _mutex->unlock();
00231 
00232     return 0;
00233 }
00234 
00235 int QSPIFBlockDevice::deinit()
00236 {
00237     _mutex->lock();
00238     if (is_initialized == false) {
00239         _mutex->unlock();
00240         return 0;
00241     }
00242     qspi_status_t status = _qspiSendGeneralCommand(QSPIF_WRDI, -1, NULL, 0, NULL, 0);
00243     int result = 0;
00244 
00245     if (status != QSPI_STATUS_OK)  {
00246         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Write Disable failed");
00247         result = -1;
00248     }
00249     is_initialized = false;
00250     _mutex->unlock();
00251 
00252     return result;
00253 }
00254 
00255 
00256 int QSPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
00257 {
00258 
00259 
00260     int status = 0;
00261 
00262     QSPIF_LOG(QSPIF_DEBUG_INFO, "INFO Inst: 0x%xh", _readInstruction);
00263 
00264     _mutex->lock();
00265 
00266     _qspiConfiureFormat(
00267         _inst_width, //Bus width for Instruction phase
00268         _address_width, //Bus width for Address phase
00269         _address_size,
00270         _alt_width, //Bus width for Alt phase
00271         _alt_size,
00272         _data_width, //Bus width for Data phase
00273         _dummy_and_mode_cycles);
00274     //_qspiConfiureFormat( 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);
00275 
00276     if (QSPI_STATUS_OK != _qspiSendReadCommand(_readInstruction, buffer, addr, size)) {
00277         status = -1;
00278         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Read failed\n");
00279     }
00280 
00281     // 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)
00282     _qspiConfiureFormat( QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
00283                          QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0);
00284 
00285     _mutex->unlock();
00286     return status;
00287 
00288 }
00289 
00290 
00291 
00292 
00293 int QSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
00294 {
00295     qspi_status_t result = QSPI_STATUS_OK;
00296     bool program_failed = false;
00297     int status = 0;
00298     uint32_t offset = 0;
00299     uint32_t chunk = 0;
00300     bd_size_t writtenBytes = 0;
00301 
00302     while (size > 0) {
00303 
00304         // Write on _pageSizeBytes boundaries (Default 256 bytes a page)
00305         offset = addr % _pageSizeBytes;
00306         chunk = (offset + size < _pageSizeBytes) ? size : (_pageSizeBytes - offset);
00307         writtenBytes = chunk;
00308 
00309         _mutex->lock();
00310 
00311         //Send WREN
00312         if (_setWriteEnable() != 0) {
00313             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Write Enabe failed\n");
00314             program_failed = true;
00315             goto Exit_Point;
00316         }
00317 
00318         if ( false == _isMemReady()) {
00319             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Device not ready, write failed\n");
00320             program_failed = true;
00321             goto Exit_Point;
00322         }
00323 
00324         result = _qspiSendProgramCommand(_progInstruction, buffer, addr, &writtenBytes);
00325         if ( (result != QSPI_STATUS_OK) || (chunk != writtenBytes) ) {
00326             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Write failed");
00327             program_failed = true;
00328             goto Exit_Point;
00329         }
00330 
00331         buffer = static_cast<const uint8_t *>(buffer) + chunk;
00332         addr += chunk;
00333         size -= chunk;
00334 
00335         wait_ms(QSPIF_DEFAULT_TIMEOUT_MSEC);
00336 
00337         if ( false == _isMemReady()) {
00338             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Device not ready after write, failed\n");
00339             program_failed = true;
00340             goto Exit_Point;
00341         }
00342         _mutex->unlock();
00343 
00344 
00345     }
00346 
00347 Exit_Point:
00348     if (program_failed) {
00349         _mutex->unlock();
00350         status = -1;
00351     }
00352 
00353     return status;
00354 }
00355 
00356 
00357 int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t inSize)
00358 {
00359 
00360     int type = 0;
00361     uint32_t chunk = 4096;
00362     unsigned int curEraseInst = _eraseInstruction;
00363     int size = (int)inSize;
00364     bool erase_failed = false;
00365     int status = 0;
00366     // Find region of erased address
00367     int region = _utilsFindAddrRegion((int)addr);
00368     // Erase Types of selected region
00369     uint8_t bitfield = _region_erase_types[region];
00370 
00371 
00372     while (size > 0) {
00373 
00374         // iterate to find next Largest erase type (1) supported by region, 2) smaller than size)
00375         // find the matching instruction and erase size chunk for that type.
00376         type = _utilsIterateNextLargestEraseType(bitfield, (int)size, (int)addr, _region_high_boundary[region]);
00377         curEraseInst = _eraseTypeInstArr[type];
00378         chunk = _eraseTypeSizeArr[type];
00379 
00380         QSPIF_LOG(QSPIF_DEBUG_DEBUG, " Debug: addr: 0x%xh, size:%d, Inst: 0x%xh, chunk: %d , ",
00381                   (int)addr, (int)size, curEraseInst, chunk);
00382 
00383         _mutex->lock();
00384 
00385         if (_setWriteEnable() != 0) {
00386             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: QSPI Erase - Write Enable failed");
00387             erase_failed = true;
00388             goto Exit_Point;
00389         }
00390 
00391         if ( false == _isMemReady()) {
00392             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: QSPI Erase Device not ready - failed");
00393             erase_failed = true;
00394             goto Exit_Point;
00395         }
00396 
00397         if (QSPI_STATUS_OK != _qspiSendEraseCommand(curEraseInst, addr, size) ) {
00398             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: QSPI Erase command failed!");
00399             erase_failed = true;
00400             goto Exit_Point;
00401         }
00402 
00403         addr += chunk;
00404         size -= chunk;
00405 
00406         if ( (size > 0) && (addr > _region_high_boundary[region]) ) {
00407             // erase crossed to next region
00408             region++;
00409             bitfield = _region_erase_types[region];
00410         }
00411         wait_ms(QSPIF_DEFAULT_TIMEOUT_MSEC);
00412         if ( false == _isMemReady()) {
00413             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: QSPI After Erase Device not ready - failed\n");
00414             erase_failed = true;
00415             goto Exit_Point;
00416         }
00417         _mutex->unlock();
00418 
00419     }
00420 
00421 
00422 Exit_Point:
00423     if (erase_failed) {
00424         _mutex->unlock();
00425         status = -1;
00426     }
00427 
00428     return status;
00429 }
00430 
00431 
00432 
00433 bd_size_t QSPIFBlockDevice::get_read_size() const
00434 {
00435     return QSPIF_DEFAULT_READ_SIZE;
00436 }
00437 
00438 bd_size_t QSPIFBlockDevice::get_program_size() const
00439 {
00440     return QSPIF_DEFAULT_PROG_SIZE;
00441 }
00442 
00443 bd_size_t QSPIFBlockDevice::get_erase_size() const
00444 {
00445     return _minCommonEraseSize;
00446 }
00447 
00448 
00449 // Find minimal erase size supported by address region
00450 bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr)
00451 {
00452     // Find region of current address
00453     int region = _utilsFindAddrRegion((int)addr);
00454 
00455     int minRegionEraseSize = _minCommonEraseSize;
00456     int8_t type_mask = 0x01;
00457     int i_ind = 0;
00458 
00459     if (region != -1) {
00460         type_mask = 0x01;
00461 
00462         for (i_ind = 0; i_ind < 4; i_ind++) {
00463             // loop through erase types supported by region
00464             if (_region_erase_types[region] & type_mask) {
00465 
00466                 minRegionEraseSize = _eraseTypeSizeArr[i_ind];
00467                 break;
00468             }
00469             type_mask = type_mask << 1;
00470         }
00471 
00472         if (i_ind == 4) {
00473             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: no erase type was found for region addr");
00474         }
00475     }
00476 
00477     return (bd_size_t)minRegionEraseSize;
00478 
00479 }
00480 
00481 bd_size_t QSPIFBlockDevice::size() const
00482 {
00483     return _deviceSizeBytes;
00484 }
00485 
00486 
00487 /*********************************************************/
00488 /********** SFDP Parsing and Detection Functions *********/
00489 /*********************************************************/
00490 
00491 int QSPIFBlockDevice::_sfdpParseSectorMapTable(uint32_t sector_map_table_addr, size_t sector_map_table_size)
00492 {
00493     uint8_t sector_map_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
00494     uint32_t tmpRegionSize = 0;
00495     int i_ind = 0;
00496     int prevBoundary = 0;
00497     // Default set to all type bits 1-4 are common
00498     _minCommonEraseType = 0x0F;
00499 
00500     qspi_status_t status = _qspiSendReadCommand(QSPIF_SFDP, (char *)sector_map_table, sector_map_table_addr /*address*/,
00501                            sector_map_table_size);
00502     if (status != QSPI_STATUS_OK) {
00503         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - Read SFDP First Table Failed");
00504         return -1;
00505     }
00506 
00507     //QSPIF_LOG(QSPIF_DEBUG_DEBUG,\nDEBUG: "Read table: %x %x %x %x %x %x %x %x %x[56] %x[57] %x[58] %x[59] %x[52]\n",sector_map_table[0],
00508     //      sector_map_table[1],
00509     //      sector_map_table[2],
00510     //      sector_map_table[3],
00511     //      sector_map_table[4],
00512     //      sector_map_table[5],
00513     //      sector_map_table[6],
00514     //      sector_map_table[7], sector_map_table[56], sector_map_table[57], sector_map_table[58], sector_map_table[59], sector_map_table[52]);
00515 
00516     // Currently we support only Single Map Descriptor
00517     if (! ( (sector_map_table[0] & 0x3) == 0x03 ) && (sector_map_table[1]  == 0x0) ) {
00518         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Sector Map - Supporting Only Single! Map Descriptor (not map commands)");
00519         return -1;
00520     }
00521 
00522     _regions_count = sector_map_table[2] + 1;
00523     if (_regions_count > QSPIF_MAX_REGIONS) {
00524         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Supporting up to %d regions, current setup to %d regions - fail",
00525                   QSPIF_MAX_REGIONS, _regions_count);
00526         return -1;
00527     }
00528 
00529     // Loop through Regions and set for each one: size, supported erase types, high boundary offset
00530     // Calculate minimum Common Erase Type for all Regions
00531     for (i_ind = 0; i_ind < _regions_count; i_ind++) {
00532         tmpRegionSize = ((*((uint32_t *)&sector_map_table[(i_ind + 1) * 4])) >> 8) & 0x00FFFFFF; // bits 9-32
00533         _region_size_bytes[i_ind] = (tmpRegionSize + 1) * 256; // Region size is 0 based multiple of 256 bytes;
00534         _region_erase_types[i_ind] = sector_map_table[(i_ind + 1) * 4] & 0x0F; // bits 1-4
00535         _minCommonEraseType &= _region_erase_types[i_ind];
00536         _region_high_boundary[i_ind] = (_region_size_bytes[i_ind] - 1) + prevBoundary;
00537         prevBoundary = _region_high_boundary[i_ind] + 1;
00538     }
00539 
00540     // Calc minimum Common Erase Size from _minCommonEraseType
00541     uint8_t type_mask = 0x01;
00542     for (i_ind = 0; i_ind < 4; i_ind++) {
00543         if (_minCommonEraseType & type_mask) {
00544             _minCommonEraseType = i_ind;
00545             _minCommonEraseSize = _eraseTypeSizeArr[i_ind];
00546             break;
00547         }
00548         type_mask = type_mask << 1;
00549     }
00550 
00551     if (i_ind == 4) {
00552         // No common erase type was found between regions
00553         _minCommonEraseType = 0;
00554         _minCommonEraseSize = -1;
00555     }
00556 
00557     return 0;
00558 }
00559 
00560 
00561 int QSPIFBlockDevice::_sfdpParseBasicParamTable(uint32_t basic_table_addr, size_t basic_table_size)
00562 {
00563     uint8_t param_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
00564 
00565     qspi_status_t status = _qspiSendReadCommand(QSPIF_SFDP, (char *)param_table, basic_table_addr /*address*/,
00566                            basic_table_size);
00567     if (status != QSPI_STATUS_OK) {
00568         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - Read SFDP First Table Failed, Status %d",status);
00569         return -1;
00570     }
00571 
00572     QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Read table: %x %x %x %x %x %x %x %x %x[56] %x[57] %x[58] %x[59] %x[52]\n",
00573               param_table[0],
00574               param_table[1],
00575               param_table[2],
00576               param_table[3],
00577               param_table[4],
00578               param_table[5],
00579               param_table[6],
00580               param_table[7], param_table[56], param_table[57], param_table[58], param_table[59], param_table[52]);
00581 
00582 
00583     // Check address size, currently only supports 3byte addresses
00584     if ((param_table[2] & 0x4) != 0 || (param_table[7] & 0x80) != 0) {
00585         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - verify 3byte addressing Failed");
00586         return -1;
00587     }
00588 
00589     // Get device density (stored in bits - 1)
00590     uint32_t density_bits = (
00591                                 (param_table[7] << 24) |
00592                                 (param_table[6] << 16) |
00593                                 (param_table[5] << 8 ) |
00594                                 param_table[4] );
00595     _deviceSizeBytes = (density_bits + 1) / 8;
00596 
00597     // Set Default read/program/erase Instructions
00598     _readInstruction = QSPIF_READ;
00599     _progInstruction = QSPIF_PP;
00600     _eraseInstruction = QSPIF_SE;
00601 
00602     // Set Page Size (QSPI write must be done on Page limits)
00603     _pageSizeBytes = _sfdpDetectPageSize(param_table);
00604 
00605     // Detect and Set Erase Types
00606     bool shouldSetQuadEnable = false;
00607     bool isQPIMode = false;
00608     _sfdpDetectEraseTypesInstAndSize(param_table, _erase4KInst, _eraseTypeInstArr, _eraseTypeSizeArr);
00609     _eraseInstruction = _erase4KInst;
00610 
00611 
00612     // Detect and Set fastest Bus mode (default 1-1-1)
00613     _sfdpDetectBestBusReadMode(param_table, shouldSetQuadEnable, isQPIMode, _readInstruction);
00614 
00615     if (true == shouldSetQuadEnable) {
00616         // Set Quad Enable and QPI Bus modes if Supported
00617         QSPIF_LOG(QSPIF_DEBUG_INFO, "INFO: init - Setting Quad Enable");
00618         _sfdpSetQuadEnabled(param_table);
00619         if (true == isQPIMode) {
00620             QSPIF_LOG(QSPIF_DEBUG_INFO, "INFO: init - Setting QPI mode");
00621             _sfdpSetQPIEnabled(param_table);
00622         }
00623     }
00624     return 0;
00625 }
00626 
00627 int QSPIFBlockDevice::_sfdpParseSFDPHeaders(uint32_t& basic_table_addr, size_t& basic_table_size,
00628         uint32_t& sector_map_table_addr, size_t& sector_map_table_size)
00629 {
00630     uint8_t sfdp_header[QSPIF_SFDP_HEADER_SIZE];
00631     uint8_t param_header[QSPIF_PARAM_HEADER_SIZE];
00632     size_t data_length = QSPIF_SFDP_HEADER_SIZE;
00633     bd_addr_t addr = 0x0;
00634 
00635     // Set 1-1-1 bus mode for SFDP header parsing
00636     _qspiConfiureFormat( QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
00637                          QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 8);
00638 
00639     qspi_status_t status = _qspiSendReadCommand(QSPIF_SFDP, (char *)sfdp_header, addr /*address*/, data_length);
00640     if (status != QSPI_STATUS_OK) {
00641         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - Read SFDP Failed");
00642         return -1;
00643     }
00644 
00645 
00646     QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG11: Read SFDP Header: %x %x %x %x %x %x %x %x\n", sfdp_header[0],
00647               sfdp_header[1],
00648               sfdp_header[2],
00649               sfdp_header[3],
00650               sfdp_header[4],
00651               sfdp_header[5],
00652               sfdp_header[6],
00653               sfdp_header[7]);
00654 
00655 
00656     // Verify SFDP signature for sanity
00657     // Also check that major/minor version is acceptable
00658     if (!(memcmp(&sfdp_header[0], "SFDP", 4) == 0 && sfdp_header[5] == 1)) {
00659         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - _verify SFDP signature and version Failed");
00660         return -1;
00661     } else {
00662         QSPIF_LOG(QSPIF_DEBUG_INFO, "INFO: init - verified SFDP Signature and version Successfully");
00663     }
00664 
00665     // Discover Number of Parameter Headers
00666     int number_of_param_headers = (int)(sfdp_header[6]) + 1;
00667     QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: number of Param Headers: %d", number_of_param_headers);
00668 
00669 
00670     addr += QSPIF_SFDP_HEADER_SIZE;
00671     data_length = QSPIF_PARAM_HEADER_SIZE;
00672 
00673     // Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
00674     for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
00675 
00676         status = _qspiSendReadCommand(QSPIF_SFDP, (char *)param_header, addr, data_length);
00677         if (status != QSPI_STATUS_OK) {
00678             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: init - Read Param Table %d Failed", i_ind + 1);
00679             return -1;
00680         }
00681         // The SFDP spec indicates the standard table is always at offset 0
00682         // in the parameter headers, we check just to be safe
00683         if (param_header[2] != 1) {
00684             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Param Table %d - Major Version should be 1!", i_ind + 1);
00685             return -1;
00686         }
00687 
00688         if ((param_header[0] == 0) && (param_header[7] == 0xFF)) {
00689             // Found Basic Params Table: LSB=0x00, MSB=0xFF
00690             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Found Basic Param Table at Table: %d", i_ind + 1);
00691             basic_table_addr = ( (param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]) );
00692             // Supporting up to 64 Bytes Table (16 DWORDS)
00693             basic_table_size = ((param_header[3] * 4) < SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES) ? (param_header[11] * 4) : 64;
00694 
00695         } else if ((param_header[0] == 81) && (param_header[7] == 0xFF)) {
00696             // Found Sector Map Table: LSB=0x81, MSB=0xFF
00697             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Found Sector Map Table at Table: %d", i_ind + 1);
00698             sector_map_table_addr = ( (param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]) );
00699 
00700             sector_map_table_size = param_header[3] * 4;
00701 
00702         }
00703         addr += QSPIF_PARAM_HEADER_SIZE;
00704 
00705     }
00706     return 0;
00707 }
00708 
00709 
00710 
00711 int QSPIFBlockDevice::_sfdpSetQPIEnabled(uint8_t *basicParamTablePtr)
00712 {
00713     uint8_t config_reg[1];
00714 
00715     // QPI 4-4-4 Enable Procedure is specified in 5 Bits
00716     uint8_t en_seq_444_value = ( ((basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_444_MODE_EN_SEQ_BYTE] & 0xF0) >> 4) | ((
00717                                      basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_444_MODE_EN_SEQ_BYTE + 1] & 0x01) << 4 ));
00718 
00719     switch (en_seq_444_value) {
00720         case 1:
00721         case 2:
00722             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: _setQPIEnabled - send command 38h");
00723             /*if (_setWriteEnable() != 0) {
00724                 printf("ERROR: Write Enabe failed\n");
00725                 return -1;
00726             }
00727             if( false == _isMemReady()) {
00728                 printf("ERROR: Device not ready, write failed\n");
00729                 return -1;
00730             }*/
00731 
00732             _qspiSendGeneralCommand(0x38, -1, NULL, 0, NULL, 0);
00733             /*wait_ms(QSPI_STATUS_REGISTER_WRITE_TIMEOUT_MSEC);
00734             if( false == _isMemReady()) {
00735                 printf("ERROR: Device not ready after write, failed\n");
00736                 return -1;
00737             }*/
00738 
00739 
00740             break;
00741 
00742         case 4:
00743             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: _setQPIEnabled - send command 35h");
00744             _qspiSendGeneralCommand(0x35, -1, NULL, 0, NULL, 0);
00745             break;
00746 
00747         case 8:
00748             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: _setQPIEnabled - set config bit 6 and send command 71h");
00749             _qspiSendGeneralCommand(0x65, 0x800003, NULL, 0, (char *)config_reg, 1);
00750             config_reg[1] |= 0x40; //Set Bit 6
00751             _qspiSendGeneralCommand(0x71, 0x800003, NULL, 0, (char *)config_reg, 1);
00752             break;
00753 
00754         case 16:
00755             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: _setQPIEnabled - reset config bits 0-7 and send command 61h");
00756             _qspiSendGeneralCommand(0x65, -1, NULL, 0, (char *)config_reg, 1);
00757             config_reg[1] &= 0x7F; //Reset Bit 7 of CR
00758 
00759 
00760 
00761 
00762             /*
00763             if (_setWriteEnable() != 0) {
00764                 printf("ERROR: Write Enabe failed\n");
00765                 return -1;
00766             }
00767             if( false == _isMemReady()) {
00768                 printf("ERROR: Device not ready, write failed\n");
00769                 return -1;
00770             }*/
00771 
00772             _qspiSendGeneralCommand(0x61, -1, NULL, 0, (char *)config_reg, 1);
00773 
00774 
00775             /* wait_ms(QSPI_STATUS_REGISTER_WRITE_TIMEOUT_MSEC);
00776             if( false == _isMemReady()) {
00777                 printf("ERROR: Device not ready after write, failed\n");
00778                 return -1;
00779             }
00780 
00781 
00782 
00783             _qspiSendGeneralCommand(0x65, -1, NULL, 0, (char *)config_reg, 1);
00784 
00785             if (_setWriteEnable() != 0) {
00786                 printf("ERROR: Write Enabe failed\n");
00787                 return -1;
00788             }
00789             if( false == _isMemReady()) {
00790                 printf("ERROR: Device not ready, write failed\n");
00791                 return -1;
00792             }
00793             config_reg[1] = 0x00; //Reset Bits 0-7
00794             _qspiSendGeneralCommand(0x61, -1, NULL, 0, (char *)config_reg, 1);
00795             wait_ms(QSPI_STATUS_REGISTER_WRITE_TIMEOUT_MSEC);*/
00796             /*  if( false == _isMemReady()) {
00797                 printf("ERROR: Device not ready after write, failed\n");
00798                 return -1;
00799             }*/
00800 
00801             break;
00802 
00803         default:
00804             QSPIF_LOG(QSPIF_DEBUG_WARNING, "WARNING: _setQPIEnabled - Unsuported En Seq 444 configuration");
00805             break;
00806 
00807 
00808     }
00809 
00810     return 0;
00811 }
00812 
00813 
00814 
00815 int QSPIFBlockDevice::_sfdpSetQuadEnabled(uint8_t *basicParamTablePtr)
00816 {
00817 
00818     int sr_read_size = QSPI_MAX_STATUS_REGISTER_SIZE;
00819     int sr_write_size = QSPI_MAX_STATUS_REGISTER_SIZE;
00820 
00821     int status_reg_setup[QSPI_MAX_STATUS_REGISTER_SIZE];
00822     uint8_t status_reg[QSPI_MAX_STATUS_REGISTER_SIZE];
00823     unsigned int writeRegisterInst = QSPIF_WRSR;
00824     unsigned int readRegisterInst = QSPIF_RDSR;
00825 
00826     uint8_t qer_value = (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_QER_BYTE] & 0x70) >> 4;
00827 
00828 
00829 
00830     switch (qer_value) {
00831         case 0:
00832             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Device Does not Have a QE Bit, continue based on Read Inst");
00833             return 0;
00834 
00835         case 1:
00836         case 4:
00837             status_reg_setup[0] = 0;
00838             status_reg_setup[1] = 0x02;
00839             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Setting QE Bit, Bit 1 of Status Reg 2");
00840             break;
00841 
00842         case 2:
00843             status_reg_setup[0] = 0x40;
00844             status_reg_setup[1] = 0;
00845             sr_write_size = 1;
00846             sr_read_size = 1;
00847             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Setting QE Bit, Bit 6 of Status Reg 1");
00848             break;
00849 
00850         case 3:
00851             status_reg_setup[0] = 0x80; // Bit 7 of Status Reg 1
00852             status_reg_setup[1] = 0;
00853             sr_write_size = 1;
00854             sr_read_size = 1;
00855             writeRegisterInst = 0x3E;
00856             readRegisterInst = 0x3F;
00857             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Setting QE Bit, Bit 7 of Status Reg 1");
00858             break;
00859         case 5:
00860             status_reg_setup[0] = 0;
00861             status_reg_setup[1] = 0x02;
00862             readRegisterInst = 0x35;
00863             sr_read_size = 1;
00864             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Setting QE Bit, Bit 1 of Status Reg 2 -special read command");
00865             break;
00866         default:
00867             QSPIF_LOG(QSPIF_DEBUG_WARNING, "WARNING: _setQuadEnable - Unsuported QER configuration");
00868             break;
00869 
00870 
00871     }
00872 
00873     // Read Status Register
00874     if (QSPI_STATUS_OK == _qspiSendGeneralCommand(readRegisterInst, -1, NULL, 0, (char *)status_reg,
00875             sr_read_size) ) {  // store received values in status_value
00876         QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Reading Status Register Success: value = 0x%x\n", (int)status_reg[0]);
00877     } else {
00878         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Reading Status Register failed");
00879         return -1;
00880     }
00881 
00882     // Set Bits for Quad Enable
00883     status_reg[0] |= status_reg_setup[0];
00884     status_reg[1] |= status_reg_setup[1];
00885 
00886 
00887     // Write new Status Register Setup
00888     if (_setWriteEnable() != 0) {
00889         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Write Enabe failed\n");
00890         return -1;
00891     }
00892 
00893     if ( false == _isMemReady()) {
00894         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Device not ready, write failed");
00895         return -1;
00896     }
00897 
00898     if (QSPI_STATUS_OK == _qspiSendGeneralCommand(writeRegisterInst, -1, (char *)status_reg, sr_write_size, NULL,
00899             0) ) {  // Write QE to status_register
00900         QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: _setQuadEnable - Writing Status Register Success: value = 0x%x",
00901                   (int)status_reg[0]);
00902     } else {
00903         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: _setQuadEnable - Writing Status Register failed");
00904         return -1;
00905     }
00906 
00907     wait_ms(QSPI_STATUS_REGISTER_WRITE_TIMEOUT_MSEC);
00908 
00909     if ( false == _isMemReady()) {
00910         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Device not ready after write, failed");
00911         return -1;
00912     }
00913 
00914 
00915     // For Debug
00916     memset(status_reg, 0, QSPI_MAX_STATUS_REGISTER_SIZE);
00917     if (QSPI_STATUS_OK == _qspiSendGeneralCommand(readRegisterInst, -1, NULL, 0, (char *)status_reg,
00918             sr_read_size) ) {  // store received values in status_value
00919         QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Reading Status Register Success: value = 0x%x\n", (int)status_reg[0]);
00920     } else {
00921         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Reading Status Register failed");
00922         return -1;
00923     }
00924 
00925 
00926     return 0;//((status_reg[0] & QSPI_STATUS_BIT_QE) != 0 ? 0 : -1);
00927 }
00928 
00929 
00930 int QSPIFBlockDevice::_sfdpDetectPageSize(uint8_t *basicParamTablePtr)
00931 {
00932     int page2PowerSize = ( (int)basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE]) >> 4;
00933     int pageSize = _utilsMathPower(2, page2PowerSize);
00934     QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: _detectPageSize - Page Size: %d", pageSize);
00935     return pageSize;
00936 }
00937 
00938 
00939 
00940 int QSPIFBlockDevice::_sfdpDetectEraseTypesInstAndSize(uint8_t *basicParamTablePtr, unsigned int& erase4KInst,
00941         unsigned int *eraseTypeInstArr, unsigned int *eraseTypeSizeArr)
00942 {
00943     erase4KInst = 0xff;
00944     bool found4KEraseType = false;
00945     uint8_t bitfield = 0x01;
00946 
00947     // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
00948     erase4KInst = basicParamTablePtr[QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE];
00949 
00950     // Loop Erase Types 1-4
00951     for (int i_ind = 0; i_ind < 4; i_ind++) {
00952         eraseTypeInstArr[i_ind] = 0xff; //0xFF default for unsupported type
00953         eraseTypeSizeArr[i_ind] = _utilsMathPower(2, basicParamTablePtr[QSPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]);
00954         if (eraseTypeSizeArr[i_ind] > 1) {
00955             // if size==1 type is not supported
00956             eraseTypeInstArr[i_ind] = basicParamTablePtr[QSPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE + 2 * i_ind];
00957 
00958             if ((eraseTypeSizeArr[i_ind] < _minCommonEraseSize) || (_minCommonEraseSize == 0) ) {
00959                 //Set default minimal common erase for singal region
00960                 _minCommonEraseSize = eraseTypeSizeArr[i_ind];
00961             }
00962 
00963             if (eraseTypeSizeArr[i_ind] == 4096) {
00964                 found4KEraseType = true;
00965                 if (erase4KInst != eraseTypeInstArr[i_ind]) {
00966                     //Verify 4KErase Type is identical to Legacy 4K erase type specified in Byte 1 of Param Table
00967                     erase4KInst = eraseTypeInstArr[i_ind];
00968                     QSPIF_LOG(QSPIF_DEBUG_WARNING,
00969                               "WARNING: _detectEraseTypesInstAndSize - Default 4K erase Inst is different than erase type Inst for 4K");
00970 
00971                 }
00972             }
00973             _region_erase_types[0] |= bitfield; // If there's no region map, set region "0" types as defualt;
00974         }
00975 
00976         QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1), eraseTypeInstArr[i_ind],
00977                   eraseTypeSizeArr[i_ind]);
00978         bitfield = bitfield << 1;
00979     }
00980 
00981     if (false == found4KEraseType) {
00982         QSPIF_LOG(QSPIF_DEBUG_WARNING, "WARNING: Couldn't find Erase Type for 4KB size");
00983     }
00984     return 0;
00985 }
00986 
00987 
00988 int QSPIFBlockDevice::_sfdpDetectBestBusReadMode(uint8_t *basicParamTablePtr, bool& setQuadEnable, bool& isQPIMode,
00989         unsigned int& readInst)
00990 {
00991 
00992     bool isDone = false;
00993 
00994     setQuadEnable = false;
00995     isQPIMode = false;
00996     int dummyCycles = 0;
00997     uint8_t examinedByte = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_QPI_READ_SUPPOR_BYTE];
00998 
00999     do { // compound statement is the loop body
01000 
01001 
01002 
01003         if (examinedByte & 0x10) {
01004             // QPI 4-4-4 Supported
01005             readInst = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_444_READ_INST_BYTE];
01006             setQuadEnable = true;
01007             isQPIMode = true;
01008             _dummy_and_mode_cycles = (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_444_READ_INST_BYTE - 1] >> 5)
01009                                      + (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_444_READ_INST_BYTE - 1] & 0x1F);
01010             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "/nDEBUG: Read Bus Mode set to 4-4-4, Instruction: 0x%xh", _readInstruction);
01011             //_inst_width = QSPI_CFG_BUS_QUAD;
01012             _address_width = QSPI_CFG_BUS_QUAD;
01013             _data_width = QSPI_CFG_BUS_QUAD;
01014 
01015             break;
01016         }
01017 
01018 
01019         examinedByte = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_FAST_READ_SUPPORT_BYTE];
01020         if (examinedByte & 0x40) {
01021             //  Fast Read 1-4-4 Supported
01022             readInst = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_144_READ_INST_BYTE];
01023             setQuadEnable = true;
01024             // dummy cycles + mode cycles = Dummy Cycles
01025             _dummy_and_mode_cycles = (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_144_READ_INST_BYTE - 1] >> 5)
01026                                      + (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_144_READ_INST_BYTE - 1] & 0x1F);
01027             _address_width = QSPI_CFG_BUS_QUAD;
01028             _data_width = QSPI_CFG_BUS_QUAD;
01029             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "/nDEBUG: Read Bus Mode set to 1-4-4, Instruction: 0x%xh", _readInstruction);
01030             break;
01031         }
01032         if (examinedByte & 0x80) {
01033             //  Fast Read 1-1-4 Supported
01034             readInst = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_114_READ_INST_BYTE];
01035             setQuadEnable = true;
01036             _dummy_and_mode_cycles = (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_114_READ_INST_BYTE - 1] >> 5)
01037                                      + (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_114_READ_INST_BYTE - 1] & 0x1F);
01038             _data_width = QSPI_CFG_BUS_QUAD;
01039             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "/nDEBUG: Read Bus Mode set to 1-1-4, Instruction: 0x%xh", _readInstruction);
01040             break;
01041         }
01042         examinedByte = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_QPI_READ_SUPPOR_BYTE];
01043         if (examinedByte & 0x01) {
01044             //  Fast Read 2-2-2 Supported
01045             readInst = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE];
01046             _dummy_and_mode_cycles = (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE - 1] >> 5)
01047                                      + (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE - 1] & 0x1F);
01048             _address_width = QSPI_CFG_BUS_DUAL;
01049             _data_width = QSPI_CFG_BUS_DUAL;
01050             QSPIF_LOG(QSPIF_DEBUG_INFO, "/nINFO: Read Bus Mode set to 2-2-2, Instruction: 0x%xh", _readInstruction);
01051             break;
01052         }
01053 
01054         examinedByte = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_FAST_READ_SUPPORT_BYTE];
01055         if (examinedByte & 0x20) {
01056             //  Fast Read 1-2-2 Supported
01057             readInst = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE];
01058             _dummy_and_mode_cycles = (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE - 1] >> 5)
01059                                      + (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE - 1] & 0x1F);
01060             _address_width = QSPI_CFG_BUS_DUAL;
01061             _data_width = QSPI_CFG_BUS_DUAL;
01062             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "/nDEBUG: Read Bus Mode set to 1-2-2, Instruction: 0x%xh", _readInstruction);
01063             break;
01064         }
01065         if (examinedByte & 0x01) {
01066             // Fast Read 1-1-2 Supported
01067             readInst = basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE];
01068             _dummy_and_mode_cycles = (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE - 1] >> 5)
01069                                      + (basicParamTablePtr[QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE - 1] & 0x1F);
01070             _data_width = QSPI_CFG_BUS_DUAL;
01071             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "/nDEBUG: Read Bus Mode set to 1-1-2, Instruction: 0x%xh", _readInstruction);
01072             break;
01073         }
01074         QSPIF_LOG(QSPIF_DEBUG_DEBUG, "/nDEBUG: Read Bus Mode set to 1-1-1, Instruction: 0x%xh", _readInstruction);
01075         isDone = true;
01076     } while (isDone == false);
01077 
01078     return 0;
01079 }
01080 
01081 
01082 int QSPIFBlockDevice::_resetFlashMem()
01083 {
01084     int status = 0;
01085     char status_value[2] = {0};
01086     QSPIF_LOG(QSPIF_DEBUG_ERROR, "INFO: _resetFlashMem:\n");
01087     //Read the Status Register from device
01088     if (QSPI_STATUS_OK == _qspiSendGeneralCommand(QSPIF_RDSR, -1, NULL, 0, status_value,
01089             1) ) {  // store received values in status_value
01090         QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Reading Status Register Success: value = 0x%x\n", (int)status_value[0]);
01091     } else {
01092         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Reading Status Register failed\n");
01093         status = -1;
01094     }
01095 
01096     if (0 == status) {
01097         //Send Reset Enable
01098         if (QSPI_STATUS_OK == _qspiSendGeneralCommand(QSPIF_RSTEN, -1, NULL, 0, NULL,
01099                 0) ) {   // store received values in status_value
01100             QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Sending RSTEN Success\n");
01101         } else {
01102             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Sending RSTEN failed\n");
01103             status = -1;
01104         }
01105 
01106 
01107         if (0 == status) {
01108             //Send Reset
01109             if (QSPI_STATUS_OK == _qspiSendGeneralCommand(QSPIF_RST, -1, NULL, 0, NULL,
01110                     0)) {   // store received values in status_value
01111                 QSPIF_LOG(QSPIF_DEBUG_DEBUG, "DEBUG: Sending RST Success\n");
01112             } else {
01113                 QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Sending RST failed\n");
01114                 status = -1;
01115             }
01116 
01117             _isMemReady();
01118         }
01119     }
01120 
01121     return status;
01122 }
01123 
01124 
01125 bool QSPIFBlockDevice::_isMemReady()
01126 {
01127     char status_value[2];
01128     int retries = 0;
01129     bool memReady = true;
01130 
01131     do {
01132         retries++;
01133         //Read the Status Register from device
01134         if (QSPI_STATUS_OK != _qspiSendGeneralCommand(QSPIF_RDSR, -1, NULL, 0, status_value,
01135                 2)) {   // store received values in status_value
01136             QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Reading Status Register failed\n");
01137         }
01138     } while ( (status_value[0] & 0x1) != 0 && retries < 10000 );
01139 
01140     if ((status_value[0] & 0x1) != 0) {
01141         QSPIF_LOG(QSPIF_DEBUG_DEBUG, "ERROR: _isMemReady FALSE\n");
01142         memReady = false;
01143     }
01144     return memReady;
01145 }
01146 
01147 
01148 int QSPIFBlockDevice::_setWriteEnable()
01149 {
01150     int status = 0;
01151     if (QSPI_STATUS_OK !=  _qspiSendGeneralCommand(QSPIF_WREN, -1, NULL, 0, NULL, 0)) {
01152         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR:Sending WREN command FAILED\n");
01153         status = -1;
01154     }
01155     return status;
01156 }
01157 
01158 
01159 
01160 /*********************************************/
01161 /************* Utility Functions *************/
01162 /*********************************************/
01163 int QSPIFBlockDevice::_utilsMathPower(int base, int exp)
01164 {
01165     int result = 1;
01166     while (exp) {
01167         result *= base;
01168         exp--;
01169     }
01170     return result;
01171 }
01172 
01173 
01174 int QSPIFBlockDevice::_utilsFindAddrRegion(int offset)
01175 {
01176     if ((offset > (int)_deviceSizeBytes) || (_regions_count == 0)) {
01177         return -1;
01178     }
01179 
01180     if (_regions_count == 1) {
01181         return 0;
01182     }
01183 
01184     for (int i_ind = _regions_count - 2; i_ind >= 0; i_ind--) {
01185 
01186         if (offset > _region_high_boundary[i_ind]) {
01187             return (i_ind + 1);
01188         }
01189     }
01190     return -1;
01191 
01192 }
01193 
01194 
01195 int QSPIFBlockDevice::_utilsIterateNextLargestEraseType(uint8_t& bitfield, int size, int offset, int boundry)
01196 {
01197     uint8_t type_mask = 0x08;
01198     int i_ind  = 0;
01199     int largestEraseType = 0;
01200     for (i_ind = 3; i_ind >= 0; i_ind--) {
01201         if (bitfield & type_mask) {
01202             largestEraseType = i_ind;
01203             if ( (size > _eraseTypeSizeArr[largestEraseType]) &&
01204                     ((boundry - offset) > _eraseTypeSizeArr[largestEraseType]) ) {
01205                 break;
01206             } else {
01207                 bitfield &= ~type_mask;
01208             }
01209         }
01210         type_mask = type_mask >> 1;
01211     }
01212 
01213     if (i_ind == 4) {
01214         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: no erase type was found for current region addr");
01215     }
01216     return largestEraseType;
01217 
01218 }
01219 
01220 
01221 /***************************************************/
01222 /*********** QSPI Driver API Functions *************/
01223 /***************************************************/
01224 
01225 qspi_status_t QSPIFBlockDevice::_qspiSetFrequency(int freq)
01226 {
01227     return _qspi.set_frequency(freq);
01228 }
01229 
01230 
01231 qspi_status_t QSPIFBlockDevice::_qspiSendReadCommand(unsigned int readInst, void *buffer, bd_addr_t addr,
01232         bd_size_t size)
01233 {
01234     // Check the address and size fit onto the chip.
01235 
01236     /* OFR_DBG */
01237     //MBED_ASSERT(is_valid_read(addr, size));
01238 
01239     size_t bufLen = size;
01240 
01241     if (_qspi.read( readInst, -1, (unsigned int )addr, (char *)buffer, &bufLen) != QSPI_STATUS_OK ) {
01242         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: Read failed");
01243         return QSPI_STATUS_ERROR;
01244     }
01245 
01246     return QSPI_STATUS_OK;
01247 
01248 }
01249 
01250 
01251 qspi_status_t QSPIFBlockDevice::_qspiSendProgramCommand(unsigned int progInst, const void *buffer, bd_addr_t addr,
01252         bd_size_t *size)
01253 {
01254     // Check the address and size fit onto the chip.
01255     //MBED_ASSERT(is_valid_program(addr, (*size)));
01256     qspi_status_t result = QSPI_STATUS_OK;
01257 
01258     result = _qspi.write( progInst, -1, addr/*(((unsigned int)addr) & 0x00FFFF00)*/, (char *)buffer, (size_t *)size);
01259     if (result != QSPI_STATUS_OK) {
01260         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: QSPI Write failed");
01261     }
01262 
01263     return result;
01264 }
01265 
01266 
01267 qspi_status_t QSPIFBlockDevice::_qspiSendEraseCommand(unsigned int eraseInst, bd_addr_t addr, bd_size_t size)
01268 {
01269     // Check the address and size fit onto the chip.
01270     //MBED_ASSERT(is_valid_erase(addr, size));
01271 
01272     qspi_status_t result = QSPI_STATUS_OK;
01273 
01274     result = _qspi.command_transfer(eraseInst, // command to send
01275                                     (((int)addr) & 0x00FFF000), // Align addr to 4096
01276                                     NULL,                 // do not transmit
01277                                     0,              // do not transmit
01278                                     NULL,                 // just receive two bytes of data
01279                                     0); // store received values in status_value
01280     if (QSPI_STATUS_OK != result) {
01281         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR: QSPI Erase failed");
01282     }
01283 
01284     return result;
01285 
01286 }
01287 
01288 
01289 qspi_status_t QSPIFBlockDevice::_qspiSendGeneralCommand(unsigned int instruction, bd_addr_t addr, const char *tx_buffer,
01290         size_t tx_length, const char *rx_buffer, size_t rx_length)
01291 {
01292 
01293 
01294     qspi_status_t status = _qspi.command_transfer(instruction, (int)addr, tx_buffer, tx_length, rx_buffer, rx_length);
01295 
01296     if (QSPI_STATUS_OK != status) {
01297         QSPIF_LOG(QSPIF_DEBUG_ERROR, "ERROR:Sending Generic command: %x", instruction);
01298     }
01299 
01300     return status;
01301 }
01302 
01303 
01304 qspi_status_t QSPIFBlockDevice::_qspiConfiureFormat(qspi_bus_width_t inst_width, qspi_bus_width_t address_width,
01305         qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width,
01306         int dummy_cycles)
01307 {
01308     _qspi.configure_format( inst_width, address_width, address_size, alt_width, alt_size, data_width, dummy_cycles);
01309 
01310     return QSPI_STATUS_OK;
01311 }
01312 
01313 
01314 
01315 
01316