STM32469I_EVAL BSP User Manual
|
stm32469i_eval_qspi.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm32469i_eval_qspi.c 00004 * @author MCD Application Team 00005 * @version V1.0.2 00006 * @date 12-January-2016 00007 * @brief This file includes a standard driver for the N25Q256A QSPI 00008 * memory mounted on STM32469I-EVAL board. 00009 @verbatim 00010 ============================================================================== 00011 ##### How to use this driver ##### 00012 ============================================================================== 00013 [..] 00014 (#) This driver is used to drive the S25FL512SAGMFI01 and N25Q512A QSPI external 00015 memory mounted on STM32469I-EVAL evaluation board. 00016 00017 (#) This driver need a specific component driver (FL512SAGMFI01 and N25Q512A) to be included with. 00018 00019 (#) Initialization steps: 00020 (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This 00021 function includes the MSP layer hardware resources initialization and the 00022 QSPI interface with the external memory. 00023 00024 (#) QSPI memory operations 00025 (++) QSPI memory can be accessed with read/write operations once it is 00026 initialized. 00027 Read/write operation can be performed with AHB access using the functions 00028 BSP_QSPI_Read()/BSP_QSPI_Write(). 00029 (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. 00030 (see the QSPI memory data sheet) 00031 (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by 00032 specifying the block address. You can perform an erase operation of the whole 00033 chip by calling the function BSP_QSPI_Erase_Chip(). 00034 (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. 00035 (see the QSPI memory data sheet) 00036 @endverbatim 00037 ****************************************************************************** 00038 * @attention 00039 * 00040 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00041 * 00042 * Redistribution and use in source and binary forms, with or without modification, 00043 * are permitted provided that the following conditions are met: 00044 * 1. Redistributions of source code must retain the above copyright notice, 00045 * this list of conditions and the following disclaimer. 00046 * 2. Redistributions in binary form must reproduce the above copyright notice, 00047 * this list of conditions and the following disclaimer in the documentation 00048 * and/or other materials provided with the distribution. 00049 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00050 * may be used to endorse or promote products derived from this software 00051 * without specific prior written permission. 00052 * 00053 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00054 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00055 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00056 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00057 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00058 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00059 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00060 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00061 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00062 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00063 * 00064 ****************************************************************************** 00065 */ 00066 00067 /* Includes ------------------------------------------------------------------*/ 00068 #include "stm32469i_eval_qspi.h" 00069 00070 /** @addtogroup BSP 00071 * @{ 00072 */ 00073 00074 /** @addtogroup STM32469I_EVAL 00075 * @{ 00076 */ 00077 00078 /** @defgroup STM32469I_EVAL_QSPI STM32469I EVAL QSPI 00079 * @{ 00080 */ 00081 00082 00083 /* Private variables ---------------------------------------------------------*/ 00084 #define JEDEC_MANUF_ID_MICRON ((uint8_t) 0x20) 00085 #define JEDEC_MANUF_ID_SPANSION ((uint8_t) 0x01) 00086 /** @defgroup STM32469I_EVAL_QSPI_Private_Variables Private Variables 00087 * @{ 00088 */ 00089 QSPI_HandleTypeDef QSPIHandle; 00090 QSPI_InfoTypeDef QspiInfo; 00091 00092 /** 00093 * @} 00094 */ 00095 00096 00097 00098 /* Private functions ---------------------------------------------------------*/ 00099 00100 /** @defgroup STM32469I_EVAL_QSPI_Private_Functions STM32469I EVAL QSPI Private Functions 00101 * @{ 00102 */ 00103 static uint8_t QSPI_ResetMemory (QSPI_HandleTypeDef *hqspi); 00104 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi); 00105 static uint8_t QSPI_DummyCyclesCfg (QSPI_HandleTypeDef *hqspi); 00106 static uint8_t QSPI_WriteEnable (QSPI_HandleTypeDef *hqspi); 00107 static uint8_t QSPI_AutoPollingMemReady (QSPI_HandleTypeDef *hqspi, uint32_t Timeout); 00108 static uint8_t QSPI_ReadID (QSPI_InfoTypeDef *pqspi_info); 00109 00110 /** 00111 * @} 00112 */ 00113 00114 /** @defgroup STM32469I_EVAL_QSPI_Exported_Functions STM32469I EVAL QSPI Exported Functions 00115 * @{ 00116 */ 00117 00118 /** 00119 * @brief Initializes the QSPI interface. 00120 * @retval QSPI memory status 00121 */ 00122 uint8_t BSP_QSPI_Init(void) 00123 { 00124 QSPIHandle.Instance = QUADSPI; 00125 00126 /* Call the DeInit function to reset the driver */ 00127 if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) 00128 { 00129 return QSPI_ERROR; 00130 } 00131 00132 /* System level initialization */ 00133 BSP_QSPI_MspInit(&QSPIHandle, NULL); 00134 00135 /* QSPI initialization */ 00136 /* Init typedef is the same for both S25FL512S and N25Q512A memories, as they have the same FLASH size */ 00137 QSPIHandle.Init.ClockPrescaler = 1; /* QSPI Freq= 180 MHz / (1+1) = 90 MHz */ 00138 QSPIHandle.Init.FifoThreshold = 1; 00139 QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; 00140 QSPIHandle.Init.FlashSize = POSITION_VAL(S25FL512S_FLASH_SIZE) - 1; /* same size on both memory types */ 00141 QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE; 00142 QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0; 00143 QSPIHandle.Init.FlashID = QSPI_FLASH_ID_1; 00144 QSPIHandle.Init.DualFlash = QSPI_DUALFLASH_DISABLE; 00145 00146 if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) 00147 { 00148 return QSPI_ERROR; 00149 } 00150 00151 /* Detect the memory ID */ 00152 if (QSPI_ReadID(&QspiInfo) != QSPI_OK) 00153 { 00154 return QSPI_NOT_SUPPORTED; 00155 } 00156 00157 /* QSPI memory reset */ 00158 if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK) 00159 { 00160 return QSPI_NOT_SUPPORTED; 00161 } 00162 00163 /* Set the QSPI memory in 4-bytes address mode */ 00164 if (QSPI_EnterFourBytesAddress(&QSPIHandle) != QSPI_OK) 00165 { 00166 return QSPI_NOT_SUPPORTED; 00167 } 00168 00169 /* Configuration of the dummy cucles on QSPI memory side */ 00170 if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK) 00171 { 00172 return QSPI_NOT_SUPPORTED; 00173 } 00174 00175 return QSPI_OK; 00176 } 00177 00178 /** 00179 * @brief De-Initializes the QSPI interface. 00180 * @retval QSPI memory status 00181 */ 00182 uint8_t BSP_QSPI_DeInit(void) 00183 { 00184 QSPIHandle.Instance = QUADSPI; 00185 00186 /* Call the DeInit function to reset the driver */ 00187 if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) 00188 { 00189 return QSPI_ERROR; 00190 } 00191 00192 /* System level De-initialization */ 00193 BSP_QSPI_MspDeInit(&QSPIHandle, NULL); 00194 00195 return QSPI_OK; 00196 } 00197 00198 /** 00199 * @brief Reads an amount of data from the QSPI memory. 00200 * @param pData: Pointer to data to be read 00201 * @param ReadAddr: Read start address 00202 * @param Size: Size of data to read 00203 * @retval QSPI memory status 00204 */ 00205 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) 00206 { 00207 QSPI_CommandTypeDef s_command; 00208 00209 /* Initialize the read command */ 00210 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00211 s_command.Instruction = QUAD_OUT_FAST_READ_CMD; /* same value on both memory types */ 00212 s_command.AddressMode = QSPI_ADDRESS_1_LINE; 00213 s_command.AddressSize = QSPI_ADDRESS_32_BITS; 00214 s_command.Address = ReadAddr; 00215 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00216 s_command.DataMode = QSPI_DATA_4_LINES; 00217 s_command.DummyCycles = QspiInfo.DummyCyclesRead; 00218 s_command.NbData = Size; 00219 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00220 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00221 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00222 00223 /* Configure the command */ 00224 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00225 { 00226 return QSPI_ERROR; 00227 } 00228 00229 /* Reception of the data */ 00230 if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00231 { 00232 return QSPI_ERROR; 00233 } 00234 00235 return QSPI_OK; 00236 } 00237 00238 /** 00239 * @brief Writes an amount of data to the QSPI memory. 00240 * @param pData: Pointer to data to be written 00241 * @param WriteAddr: Write start address 00242 * @param Size: Size of data to write 00243 * @retval QSPI memory status 00244 */ 00245 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) 00246 { 00247 QSPI_CommandTypeDef s_command; 00248 uint32_t end_addr, current_size, current_addr; 00249 00250 /* Calculation of the size between the write address and the end of the page */ 00251 current_addr = 0; 00252 00253 while (current_addr <= WriteAddr) 00254 { 00255 current_addr += QspiInfo.ProgPageSize; 00256 } 00257 current_size = current_addr - WriteAddr; 00258 00259 /* Check if the size of the data is less than the remaining place in the page */ 00260 if (current_size > Size) 00261 { 00262 current_size = Size; 00263 } 00264 00265 /* Initialize the adress variables */ 00266 current_addr = WriteAddr; 00267 end_addr = WriteAddr + Size; 00268 00269 /* Initialize the program command */ 00270 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00271 s_command.Instruction = QUAD_IN_FAST_PROG_CMD; /* same value on both memory types */ 00272 s_command.AddressMode = QSPI_ADDRESS_1_LINE; 00273 s_command.AddressSize = QSPI_ADDRESS_32_BITS; 00274 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00275 s_command.DataMode = QSPI_DATA_4_LINES; 00276 s_command.DummyCycles = 0; 00277 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00278 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00279 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00280 00281 /* Perform the write page by page */ 00282 do 00283 { 00284 s_command.Address = current_addr; 00285 s_command.NbData = current_size; 00286 00287 /* Enable write operations */ 00288 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00289 { 00290 return QSPI_ERROR; 00291 } 00292 00293 /* Configure the command */ 00294 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00295 { 00296 return QSPI_ERROR; 00297 } 00298 00299 /* Transmission of the data */ 00300 if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00301 { 00302 return QSPI_ERROR; 00303 } 00304 00305 /* Configure automatic polling mode to wait for end of program */ 00306 if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) 00307 { 00308 return QSPI_ERROR; 00309 } 00310 00311 /* Update the address and size variables for next page programming */ 00312 current_addr += current_size; 00313 pData += current_size; 00314 current_size = ((current_addr + QspiInfo.ProgPageSize) > end_addr) ? (end_addr - current_addr) : QspiInfo.ProgPageSize; 00315 } while (current_addr < end_addr); 00316 00317 return QSPI_OK; 00318 } 00319 00320 /** 00321 * @brief Erases the specified block of the QSPI memory. 00322 * @param BlockAddress: Block address to erase 00323 * @retval QSPI memory status 00324 */ 00325 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) 00326 { 00327 QSPI_CommandTypeDef s_command; 00328 00329 /* Initialize the erase command */ 00330 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00331 s_command.Instruction = SECTOR_ERASE_CMD; /* same value on both memory types */ 00332 s_command.AddressMode = QSPI_ADDRESS_1_LINE; 00333 s_command.AddressSize = QSPI_ADDRESS_32_BITS; 00334 s_command.Address = BlockAddress; 00335 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00336 s_command.DataMode = QSPI_DATA_NONE; 00337 s_command.DummyCycles = 0; 00338 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00339 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00340 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00341 00342 /* Enable write operations */ 00343 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00344 { 00345 return QSPI_ERROR; 00346 } 00347 00348 /* Send the command */ 00349 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00350 { 00351 return QSPI_ERROR; 00352 } 00353 00354 /* Configure automatic polling mode to wait for end of erase */ 00355 if (QSPI_AutoPollingMemReady(&QSPIHandle, QspiInfo.SectorEraseMaxTime) != QSPI_OK) 00356 { 00357 return QSPI_ERROR; 00358 } 00359 00360 return QSPI_OK; 00361 } 00362 00363 /** 00364 * @brief Erases the entire QSPI memory. 00365 * @retval QSPI memory status 00366 */ 00367 uint8_t BSP_QSPI_Erase_Chip(void) 00368 { 00369 QSPI_CommandTypeDef s_command; 00370 00371 /* Initialize the erase command */ 00372 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00373 s_command.Instruction = BULK_ERASE_CMD; /* same value on both memory types */ 00374 s_command.AddressMode = QSPI_ADDRESS_NONE; 00375 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00376 s_command.DataMode = QSPI_DATA_NONE; 00377 s_command.DummyCycles = 0; 00378 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00379 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00380 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00381 00382 /* Enable write operations */ 00383 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00384 { 00385 return QSPI_ERROR; 00386 } 00387 00388 /* Send the command */ 00389 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00390 { 00391 return QSPI_ERROR; 00392 } 00393 00394 /* Configure automatic polling mode to wait for end of erase */ 00395 if (QSPI_AutoPollingMemReady(&QSPIHandle, QspiInfo.BulkEraseMaxTime) != QSPI_OK) 00396 { 00397 return QSPI_ERROR; 00398 } 00399 00400 return QSPI_OK; 00401 } 00402 00403 /** 00404 * @brief Reads current status of the QSPI memory. 00405 * @retval QSPI memory status 00406 */ 00407 uint8_t BSP_QSPI_GetStatus(void) 00408 { 00409 QSPI_CommandTypeDef s_command; 00410 uint8_t reg1, reg2; 00411 00412 if (QspiInfo.ManufID == QSPI_N25Q512A) 00413 { 00414 /* Initialize the read flag status register command */ 00415 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00416 s_command.Instruction = READ_FLAG_STATUS_REG_CMD; /* same value on both memory types */ 00417 s_command.AddressMode = QSPI_ADDRESS_NONE; 00418 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00419 s_command.DataMode = QSPI_DATA_1_LINE; 00420 s_command.DummyCycles = 0; 00421 s_command.NbData = 1; 00422 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00423 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00424 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00425 00426 /* Configure the command */ 00427 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00428 { 00429 return QSPI_ERROR; 00430 } 00431 00432 /* Reception of the data */ 00433 if (HAL_QSPI_Receive(&QSPIHandle, ®1, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00434 { 00435 return QSPI_ERROR; 00436 } 00437 00438 /* Check the value of the register */ 00439 if ((reg1 & (N25Q512A_FSR_PRERR | N25Q512A_FSR_VPPERR | N25Q512A_FSR_PGERR | N25Q512A_FSR_ERERR)) != 0) 00440 { 00441 return QSPI_ERROR; 00442 } 00443 else if ((reg1 & (N25Q512A_FSR_PGSUS | N25Q512A_FSR_ERSUS)) != 0) 00444 { 00445 return QSPI_SUSPENDED; 00446 } 00447 else if ((reg1 & N25Q512A_FSR_READY) != 0) 00448 { 00449 return QSPI_OK; 00450 } 00451 else 00452 { 00453 return QSPI_BUSY; 00454 } 00455 } 00456 else 00457 { 00458 /* Initialize the read flag status register1 command */ 00459 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00460 s_command.Instruction = S25FL512S_READ_STATUS_REG1_CMD; 00461 s_command.AddressMode = QSPI_ADDRESS_NONE; 00462 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00463 s_command.DataMode = QSPI_DATA_1_LINE; 00464 s_command.DummyCycles = 0; 00465 s_command.NbData = 1; 00466 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00467 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00468 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00469 00470 /* Configure the command */ 00471 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00472 { 00473 return QSPI_ERROR; 00474 } 00475 00476 /* Reception of the data */ 00477 if (HAL_QSPI_Receive(&QSPIHandle, ®1, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00478 { 00479 return QSPI_ERROR; 00480 } 00481 00482 00483 /* Initialize the read flag status register2 command */ 00484 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00485 s_command.Instruction = S25FL512S_READ_STATUS_REG2_CMD; 00486 s_command.AddressMode = QSPI_ADDRESS_NONE; 00487 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00488 s_command.DataMode = QSPI_DATA_1_LINE; 00489 s_command.DummyCycles = 0; 00490 s_command.NbData = 1; 00491 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00492 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00493 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00494 00495 /* Configure the command */ 00496 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00497 { 00498 return QSPI_ERROR; 00499 } 00500 00501 /* Reception of the data */ 00502 if (HAL_QSPI_Receive(&QSPIHandle, ®2, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00503 { 00504 return QSPI_ERROR; 00505 } 00506 00507 /* Check the value of the register */ 00508 if ((reg1 & (S25FL512S_SR1_ERERR | S25FL512S_SR1_PGERR | S25FL512S_SR1_SRWD )) != 0) 00509 { 00510 return QSPI_ERROR; 00511 } 00512 if ((reg1 & (S25FL512S_SR1_BP0 | S25FL512S_SR1_BP1 | S25FL512S_SR1_BP2)) != 0) 00513 { 00514 return QSPI_PROTECTED; 00515 } 00516 00517 if ((reg2 & (S25FL512S_SR2_PS | S25FL512S_SR2_ES)) != 0) 00518 { 00519 return QSPI_SUSPENDED; 00520 } 00521 if ((reg1 & (S25FL512S_SR1_WIP | S25FL512S_SR1_WREN)) == 0) 00522 { 00523 return QSPI_OK; 00524 } 00525 else 00526 { 00527 return QSPI_BUSY; 00528 } 00529 } 00530 } 00531 00532 /** 00533 * @brief Reads the configuration of the memory and fills QspiInfo struct 00534 * @param pInfo pointer to Info structure 00535 * @retval QSPI memory status 00536 */ 00537 uint8_t BSP_QSPI_GetInfo(QSPI_InfoTypeDef* pInfo) 00538 { 00539 00540 if (QSPI_ReadID(pInfo) != QSPI_OK) 00541 { 00542 return QSPI_ERROR; 00543 } 00544 00545 return QSPI_OK; 00546 } 00547 00548 /** 00549 * @brief Configure the QSPI in memory-mapped mode 00550 * @retval QSPI memory status 00551 */ 00552 uint8_t BSP_QSPI_MemoryMappedMode(void) 00553 { 00554 QSPI_CommandTypeDef s_command; 00555 QSPI_MemoryMappedTypeDef s_mem_mapped_cfg; 00556 00557 /* Configure the command for the read instruction */ 00558 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00559 s_command.Instruction = QUAD_OUT_FAST_READ_CMD; 00560 s_command.AddressMode = QSPI_ADDRESS_1_LINE; 00561 s_command.AddressSize = QSPI_ADDRESS_32_BITS; 00562 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00563 s_command.DataMode = QSPI_DATA_4_LINES; 00564 s_command.DummyCycles = QspiInfo.DummyCyclesRead; 00565 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00566 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00567 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00568 00569 /* Configure the memory mapped mode */ 00570 s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; 00571 s_mem_mapped_cfg.TimeOutPeriod = 0; //1; 00572 00573 if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK) 00574 { 00575 return QSPI_ERROR; 00576 } 00577 00578 return QSPI_OK; 00579 } 00580 00581 /** 00582 * @} 00583 */ 00584 00585 /** @addtogroup STM32469I_EVAL_QSPI_Private_Functions 00586 * @{ 00587 */ 00588 00589 /** 00590 * @brief QSPI MSP Initialization 00591 * This function configures the hardware resources used in this example: 00592 * - Peripheral's clock enable 00593 * - Peripheral's GPIO Configuration 00594 * - NVIC configuration for QSPI interrupt 00595 */ 00596 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params) 00597 { 00598 GPIO_InitTypeDef gpio_init_structure; 00599 00600 /*##-1- Enable peripherals and GPIO Clocks #################################*/ 00601 /* Enable the QuadSPI memory interface clock */ 00602 QSPI_CLK_ENABLE(); 00603 /* Reset the QuadSPI memory interface */ 00604 QSPI_FORCE_RESET(); 00605 QSPI_RELEASE_RESET(); 00606 /* Enable GPIO clocks */ 00607 QSPI_CS_GPIO_CLK_ENABLE(); 00608 QSPI_DX_CLK_GPIO_CLK_ENABLE(); 00609 00610 /*##-2- Configure peripheral GPIO ##########################################*/ 00611 /* QSPI CS GPIO pin configuration */ 00612 gpio_init_structure.Pin = QSPI_CS_PIN; 00613 gpio_init_structure.Mode = GPIO_MODE_AF_PP; 00614 gpio_init_structure.Pull = GPIO_PULLUP; 00615 gpio_init_structure.Speed = GPIO_SPEED_HIGH; 00616 gpio_init_structure.Alternate = GPIO_AF10_QSPI; 00617 HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure); 00618 00619 /* QSPI CLK GPIO pin configuration */ 00620 gpio_init_structure.Pin = QSPI_CLK_PIN; 00621 gpio_init_structure.Pull = GPIO_NOPULL; 00622 gpio_init_structure.Alternate = GPIO_AF9_QSPI; 00623 HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure); 00624 00625 /* QSPI D0 and D1 GPIO pin configuration */ 00626 gpio_init_structure.Pin = (QSPI_D0_PIN | QSPI_D1_PIN); 00627 gpio_init_structure.Alternate = GPIO_AF10_QSPI; 00628 HAL_GPIO_Init(QSPI_DX_GPIO_PORT, &gpio_init_structure); 00629 00630 /* QSPI D2 and D3 GPIO pin configuration */ 00631 gpio_init_structure.Pin = (QSPI_D2_PIN | QSPI_D3_PIN) ; 00632 gpio_init_structure.Alternate = GPIO_AF9_QSPI; 00633 HAL_GPIO_Init(QSPI_DX_GPIO_PORT, &gpio_init_structure); 00634 00635 /*##-3- Configure the NVIC for QSPI #########################################*/ 00636 /* NVIC configuration for QSPI interrupt */ 00637 HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0); 00638 HAL_NVIC_EnableIRQ(QUADSPI_IRQn); 00639 00640 } 00641 00642 /** 00643 * @brief QSPI MSP De-Initialization 00644 * This function frees the hardware resources used in this example: 00645 * - Disable the Peripheral's clock 00646 * - Revert GPIO and NVIC configuration to their default state 00647 */ 00648 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params) 00649 { 00650 /*##-1- Disable the NVIC for QSPI ###########################################*/ 00651 HAL_NVIC_DisableIRQ(QUADSPI_IRQn); 00652 00653 /*##-2- Disable peripherals and GPIO Clocks ################################*/ 00654 /* De-Configure QSPI pins */ 00655 HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN); 00656 HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN); 00657 HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D0_PIN); 00658 HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D1_PIN); 00659 HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D2_PIN); 00660 HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D3_PIN); 00661 00662 /*##-3- Reset peripherals ##################################################*/ 00663 /* Reset the QuadSPI memory interface */ 00664 QSPI_FORCE_RESET(); 00665 QSPI_RELEASE_RESET(); 00666 00667 /* Disable the QuadSPI memory interface clock */ 00668 QSPI_CLK_DISABLE(); 00669 } 00670 00671 /** 00672 * @brief This function reset the QSPI memory. 00673 * @param hqspi: QSPI handle 00674 */ 00675 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi) 00676 { 00677 QSPI_CommandTypeDef s_command; 00678 uint32_t instruction1, instruction2; 00679 00680 /* Command ID differs between N25Q512A and S25FL512S memories */ 00681 if (QspiInfo.ManufID == QSPI_N25Q512A) 00682 { 00683 instruction1 = RESET_ENABLE_CMD; 00684 instruction2 = RESET_MEMORY_CMD; 00685 } 00686 else 00687 { 00688 instruction1 = S25FL512S_MODE_BIT_RESET_CMD; 00689 instruction2 = S25FL512S_SOFTWARE_RESET_CMD; 00690 } 00691 00692 /* Initialize the Mode Bit Reset command */ 00693 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00694 s_command.Instruction = instruction1; 00695 s_command.AddressMode = QSPI_ADDRESS_NONE; 00696 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00697 s_command.DataMode = QSPI_DATA_NONE; 00698 s_command.DummyCycles = 0; 00699 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00700 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00701 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00702 00703 /* Send the command */ 00704 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00705 { 00706 return QSPI_ERROR; 00707 } 00708 00709 /* Send the SW reset command */ 00710 s_command.Instruction = instruction2; 00711 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00712 { 00713 return QSPI_ERROR; 00714 } 00715 00716 /* Configure automatic polling mode to wait the memory is ready */ 00717 if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) 00718 { 00719 return QSPI_ERROR; 00720 } 00721 return QSPI_OK; 00722 } 00723 00724 /** 00725 * @brief This function set the QSPI memory in 4-byte address mode 00726 * @param hqspi: QSPI handle 00727 */ 00728 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi) 00729 { 00730 QSPI_CommandTypeDef s_command; 00731 uint8_t reg1; 00732 00733 /* Command ID differs between N25Q512A and S25FL512S memories */ 00734 if (QspiInfo.ManufID == QSPI_N25Q512A) 00735 { 00736 /* Initialize the command */ 00737 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00738 s_command.Instruction = ENTER_4_BYTE_ADDR_MODE_CMD; 00739 s_command.AddressMode = QSPI_ADDRESS_NONE; 00740 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00741 s_command.DataMode = QSPI_DATA_NONE; 00742 s_command.DummyCycles = 0; 00743 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00744 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00745 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00746 00747 /* Enable write operations */ 00748 if (QSPI_WriteEnable(hqspi) != QSPI_OK) 00749 { 00750 return QSPI_ERROR; 00751 } 00752 00753 /* Send the command */ 00754 if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00755 { 00756 return QSPI_ERROR; 00757 } 00758 00759 /* Configure automatic polling mode to wait the memory is ready */ 00760 if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) 00761 { 00762 return QSPI_ERROR; 00763 } 00764 00765 return QSPI_OK; 00766 } 00767 else 00768 { 00769 /* Initialize the read bank register command */ 00770 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00771 s_command.Instruction = S25FL512S_READ_BANK_REG_CMD; 00772 s_command.AddressMode = QSPI_ADDRESS_NONE; 00773 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00774 s_command.DataMode = QSPI_DATA_1_LINE; 00775 s_command.DummyCycles = 0; 00776 s_command.NbData = 1; 00777 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00778 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00779 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00780 00781 /* Configure the command */ 00782 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00783 { 00784 return QSPI_ERROR; 00785 } 00786 00787 /* Reception of the data */ 00788 if (HAL_QSPI_Receive(&QSPIHandle, ®1, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00789 { 00790 return QSPI_ERROR; 00791 } 00792 00793 /* Enable write operations */ 00794 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00795 { 00796 return QSPI_ERROR; 00797 } 00798 00799 /* Update Bank address register (with 4byte addressing bit) */ 00800 s_command.Instruction = S25FL512S_WRITE_BANK_REG_CMD; 00801 MODIFY_REG(reg1, S25FL512S_BA_EXTADD, S25FL512S_BA_EXTADD); 00802 00803 /* Configure the write volatile configuration register command */ 00804 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00805 { 00806 return QSPI_ERROR; 00807 } 00808 00809 /* Transmission of the data Status Register 1 */ 00810 if (HAL_QSPI_Transmit(&QSPIHandle, ®1, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00811 { 00812 return QSPI_ERROR; 00813 } 00814 return QSPI_OK; 00815 } 00816 } 00817 00818 /** 00819 * @brief This function configure the dummy cycles on memory side. 00820 * @param hqspi: QSPI handle 00821 */ 00822 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi) 00823 { 00824 QSPI_CommandTypeDef s_command; 00825 uint8_t reg[2]; 00826 /* Command ID differs between N25Q512A and S25FL512S memories */ 00827 if (QspiInfo.ManufID == QSPI_N25Q512A) 00828 { 00829 /* Initialize the read volatile configuration register command */ 00830 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00831 s_command.Instruction = READ_VOL_CFG_REG_CMD; 00832 s_command.AddressMode = QSPI_ADDRESS_NONE; 00833 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00834 s_command.DataMode = QSPI_DATA_1_LINE; 00835 s_command.DummyCycles = 0; 00836 s_command.NbData = 1; 00837 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00838 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00839 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00840 00841 /* Configure the command */ 00842 if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00843 { 00844 return QSPI_ERROR; 00845 } 00846 00847 /* Reception of the data */ 00848 if (HAL_QSPI_Receive(hqspi, ®[0], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00849 { 00850 return QSPI_ERROR; 00851 } 00852 00853 /* Enable write operations */ 00854 if (QSPI_WriteEnable(hqspi) != QSPI_OK) 00855 { 00856 return QSPI_ERROR; 00857 } 00858 00859 /* Update volatile configuration register (with new dummy cycles) */ 00860 s_command.Instruction = WRITE_VOL_CFG_REG_CMD; 00861 MODIFY_REG(reg[0], N25Q512A_VCR_NB_DUMMY, (N25Q512A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q512A_VCR_NB_DUMMY))); 00862 00863 /* Configure the write volatile configuration register command */ 00864 if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00865 { 00866 return QSPI_ERROR; 00867 } 00868 00869 /* Transmission of the data */ 00870 if (HAL_QSPI_Transmit(hqspi, ®[0], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00871 { 00872 return QSPI_ERROR; 00873 } 00874 } 00875 else 00876 { 00877 /* Initialize the read configuration register command */ 00878 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00879 s_command.Instruction = S25FL512S_READ_CONFIGURATION_REG1_CMD; 00880 s_command.AddressMode = QSPI_ADDRESS_NONE; 00881 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00882 s_command.DataMode = QSPI_DATA_1_LINE; 00883 s_command.DummyCycles = 0; 00884 s_command.NbData = 1; 00885 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00886 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00887 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00888 00889 /* Configure the command */ 00890 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00891 { 00892 return QSPI_ERROR; 00893 } 00894 00895 /* Reception of the data */ 00896 if (HAL_QSPI_Receive(&QSPIHandle, ®[1], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00897 { 00898 return QSPI_ERROR; 00899 } 00900 00901 /* Initialize the read status register1 command */ 00902 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00903 s_command.Instruction = S25FL512S_READ_STATUS_REG1_CMD; 00904 s_command.AddressMode = QSPI_ADDRESS_NONE; 00905 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00906 s_command.DataMode = QSPI_DATA_1_LINE; 00907 s_command.DummyCycles = 0; 00908 s_command.NbData = 1; 00909 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00910 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00911 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00912 00913 /* Configure the command */ 00914 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00915 { 00916 return QSPI_ERROR; 00917 } 00918 00919 /* Reception of the data */ 00920 if (HAL_QSPI_Receive(&QSPIHandle, ®[0], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00921 { 00922 return QSPI_ERROR; 00923 } 00924 00925 /* Enable write operations */ 00926 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00927 { 00928 return QSPI_ERROR; 00929 } 00930 00931 /* Update configuration register (with new Latency Code) */ 00932 s_command.Instruction = S25FL512S_WRITE_STATUS_CMD_REG_CMD; 00933 s_command.NbData = 2; 00934 MODIFY_REG(reg[1], S25FL512S_CR1_LC_MASK, S25FL512S_CR1_LC1); 00935 00936 /* Configure the write volatile configuration register command */ 00937 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00938 { 00939 return QSPI_ERROR; 00940 } 00941 00942 /* Transmission of the data Status Register 1 */ 00943 if (HAL_QSPI_Transmit(&QSPIHandle, reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00944 { 00945 return QSPI_ERROR; 00946 } 00947 } 00948 return QSPI_OK; 00949 } 00950 00951 /** 00952 * @brief This function send a Write Enable and wait it is effective. 00953 * @param hqspi: QSPI handle 00954 */ 00955 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi) 00956 { 00957 QSPI_CommandTypeDef s_command; 00958 QSPI_AutoPollingTypeDef sConfig; 00959 00960 /* Enable write operations */ 00961 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00962 s_command.Instruction = WRITE_ENABLE_CMD; /* equal on both memory types */ 00963 s_command.AddressMode = QSPI_ADDRESS_NONE; 00964 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00965 s_command.DataMode = QSPI_DATA_NONE; 00966 s_command.DummyCycles = 0; 00967 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 00968 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00969 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00970 00971 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00972 { 00973 return QSPI_ERROR; 00974 } 00975 00976 /* Configure automatic polling mode to wait for write enabling */ 00977 sConfig.Match = S25FL512S_SR1_WREN; 00978 sConfig.Mask = S25FL512S_SR1_WREN; /* equal on both memory types */ 00979 sConfig.MatchMode = QSPI_MATCH_MODE_AND; 00980 sConfig.StatusBytesSize = 1; 00981 sConfig.Interval = 0x10; 00982 sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; 00983 00984 s_command.Instruction = READ_STATUS_REG_CMD; /* equal on both memory types */ 00985 s_command.DataMode = QSPI_DATA_1_LINE; 00986 00987 if (HAL_QSPI_AutoPolling(&QSPIHandle, &s_command, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00988 { 00989 return QSPI_ERROR; 00990 } 00991 00992 return QSPI_OK; 00993 } 00994 00995 /** 00996 * @brief This function read the SR of the memory and wait the EOP. 00997 * @param hqspi: QSPI handle 00998 * @param Timeout: timeout value before returning an error 00999 */ 01000 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout) 01001 { 01002 QSPI_CommandTypeDef s_command; 01003 QSPI_AutoPollingTypeDef sConfig; 01004 01005 /* Configure automatic polling mode to wait for memory ready */ 01006 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 01007 s_command.Instruction = READ_STATUS_REG_CMD; /* same value on both memory types */ 01008 s_command.AddressMode = QSPI_ADDRESS_NONE; 01009 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 01010 s_command.DataMode = QSPI_DATA_1_LINE; 01011 s_command.DummyCycles = 0; 01012 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 01013 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 01014 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 01015 01016 sConfig.Match = 0; 01017 sConfig.Mask = S25FL512S_SR1_WIP; /* same value on both memory types */ 01018 sConfig.MatchMode = QSPI_MATCH_MODE_AND; 01019 sConfig.StatusBytesSize = 1; 01020 sConfig.Interval = 0x10; 01021 sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; 01022 01023 if (HAL_QSPI_AutoPolling(&QSPIHandle, &s_command, &sConfig, Timeout) != HAL_OK) 01024 { 01025 return QSPI_ERROR; 01026 } 01027 01028 return QSPI_OK; 01029 } 01030 01031 /** 01032 * @brief This function reads the ID of the QSPI Memory and fills the info struct 01033 * @param pqspi_info: pointer to the Info Typedef strcture 01034 */ 01035 static uint8_t QSPI_ReadID(QSPI_InfoTypeDef *pqspi_info) 01036 { 01037 QSPI_CommandTypeDef s_command; 01038 uint8_t reg[6]; 01039 01040 /* Configure automatic polling mode to wait for memory ready */ 01041 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; 01042 s_command.Instruction = READ_ID_CMD2; /* same value on both memory types */ 01043 s_command.AddressMode = QSPI_ADDRESS_NONE; 01044 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 01045 s_command.DataMode = QSPI_DATA_1_LINE; 01046 s_command.NbData = 6; 01047 s_command.DummyCycles = 0; 01048 s_command.DdrMode = QSPI_DDR_MODE_DISABLE; 01049 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 01050 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 01051 01052 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01053 { 01054 return QSPI_ERROR; 01055 } 01056 01057 /* Reception of the data */ 01058 if (HAL_QSPI_Receive(&QSPIHandle, reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01059 { 01060 return QSPI_ERROR; 01061 } 01062 01063 /* Check the received ID of the QSPI Memory */ 01064 if (reg[0] == JEDEC_MANUF_ID_MICRON) 01065 { 01066 pqspi_info->ManufID = QSPI_N25Q512A; 01067 pqspi_info->FlashSize = (reg[2]<<21) & 0xFFFFFFFF; 01068 pqspi_info->EraseSectorSize = N25Q512A_SECTOR_SIZE; 01069 pqspi_info->EraseSectorsNumber = (N25Q512A_FLASH_SIZE/N25Q512A_SECTOR_SIZE); 01070 pqspi_info->ProgPageSize = N25Q512A_PAGE_SIZE; 01071 pqspi_info->ProgPagesNumber = (N25Q512A_FLASH_SIZE/N25Q512A_PAGE_SIZE); 01072 pqspi_info->DummyCyclesRead = 10; 01073 pqspi_info->SectorEraseMaxTime = N25Q512A_SECTOR_ERASE_MAX_TIME; 01074 pqspi_info->BulkEraseMaxTime = N25Q512A_BULK_ERASE_MAX_TIME; 01075 } 01076 if (reg[0] == JEDEC_MANUF_ID_SPANSION) 01077 { 01078 pqspi_info->ManufID = QSPI_S25FL512S; 01079 pqspi_info->FlashSize = (reg[2]<<21) & 0xFFFFFFFF; 01080 pqspi_info->EraseSectorSize = S25FL512S_SECTOR_SIZE; 01081 pqspi_info->EraseSectorsNumber = (S25FL512S_FLASH_SIZE/S25FL512S_SECTOR_SIZE); 01082 pqspi_info->ProgPageSize = S25FL512S_PAGE_SIZE; 01083 pqspi_info->ProgPagesNumber = (S25FL512S_FLASH_SIZE/S25FL512S_PAGE_SIZE); 01084 pqspi_info->DummyCyclesRead = 8; 01085 pqspi_info->SectorEraseMaxTime = S25FL512S_SECTOR_ERASE_MAX_TIME; 01086 pqspi_info->BulkEraseMaxTime = S25FL512S_BULK_ERASE_MAX_TIME; 01087 } 01088 01089 return QSPI_OK; 01090 01091 } 01092 /** 01093 * @} 01094 */ 01095 01096 /** 01097 * @} 01098 */ 01099 01100 /** 01101 * @} 01102 */ 01103 01104 /** 01105 * @} 01106 */ 01107 01108 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 01109
Generated on Tue Jan 12 2016 17:51:25 for STM32469I_EVAL BSP User Manual by
