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