Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
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 *)§or_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
Generated on Tue Jul 12 2022 19:12:15 by 1.7.2