B-L475E-IOT01 BSP User Manual
|
stm32l475e_iot01_qspi.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l475e_iot01_qspi.c 00004 * @author MCD Application Team 00005 * @version V1.0.0 00006 * @date 17-March-2017 00007 * @brief This file includes a standard driver for the MX25R6435F QSPI 00008 * memory mounted on STM32L475E IOT01 board. 00009 @verbatim 00010 ============================================================================== 00011 ##### How to use this driver ##### 00012 ============================================================================== 00013 [..] 00014 (#) This driver is used to drive the MX25R6435F QSPI external 00015 memory mounted on STM32L475E IOT01 board. 00016 00017 (#) This driver need a specific component driver (MX25R6435F) 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. The BSP_QSPI_DeInit() can be used 00023 to deactivate the QSPI interface. 00024 00025 (#) QSPI memory operations 00026 (++) QSPI memory can be accessed with read/write operations once it is 00027 initialized. 00028 Read/write operation can be performed with AHB access using the functions 00029 BSP_QSPI_Read()/BSP_QSPI_Write(). 00030 (++) The function to the QSPI memory in memory-mapped mode is possible after 00031 the call of the function BSP_QSPI_EnableMemoryMappedMode(). 00032 (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. 00033 (see the QSPI memory data sheet) 00034 (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by 00035 specifying the block address. You can perform an erase operation of the whole 00036 chip by calling the function BSP_QSPI_Erase_Chip(). 00037 (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. 00038 (see the QSPI memory data sheet) 00039 (++) Perform erase sector operation using the function BSP_QSPI_Erase_Sector() 00040 which is not blocking. So the function BSP_QSPI_GetStatus() should be used 00041 to check if the memory is busy, and the functions BSP_QSPI_SuspendErase()/ 00042 BSP_QSPI_ResumeErase() can be used to perform other operations during the 00043 sector erase. 00044 (++) Deep power down of the QSPI memory is managed with the call of the functions 00045 BSP_QSPI_EnterDeepPowerDown()/BSP_QSPI_LeaveDeepPowerDown() 00046 @endverbatim 00047 ****************************************************************************** 00048 * @attention 00049 * 00050 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00051 * 00052 * Redistribution and use in source and binary forms, with or without modification, 00053 * are permitted provided that the following conditions are met: 00054 * 1. Redistributions of source code must retain the above copyright notice, 00055 * this list of conditions and the following disclaimer. 00056 * 2. Redistributions in binary form must reproduce the above copyright notice, 00057 * this list of conditions and the following disclaimer in the documentation 00058 * and/or other materials provided with the distribution. 00059 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00060 * may be used to endorse or promote products derived from this software 00061 * without specific prior written permission. 00062 * 00063 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00064 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00065 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00066 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00067 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00068 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00069 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00070 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00071 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00072 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00073 * 00074 ****************************************************************************** 00075 */ 00076 00077 /* Includes ------------------------------------------------------------------*/ 00078 #include "stm32l475e_iot01_qspi.h" 00079 00080 /** @addtogroup BSP 00081 * @{ 00082 */ 00083 00084 /** @addtogroup STM32L475E_IOT01 00085 * @{ 00086 */ 00087 00088 /** @defgroup STM32L475E_IOT01_QSPI QSPI 00089 * @{ 00090 */ 00091 00092 /* Private constants --------------------------------------------------------*/ 00093 /** @defgroup STM32L475E_IOT01_QSPI_Private_Constants QSPI Private Constants 00094 * @{ 00095 */ 00096 #define QSPI_QUAD_DISABLE 0x0 00097 #define QSPI_QUAD_ENABLE 0x1 00098 00099 #define QSPI_HIGH_PERF_DISABLE 0x0 00100 #define QSPI_HIGH_PERF_ENABLE 0x1 00101 /** 00102 * @} 00103 */ 00104 /* Private variables ---------------------------------------------------------*/ 00105 00106 /** @defgroup STM32L475E_IOT01_QSPI_Private_Variables QSPI Private Variables 00107 * @{ 00108 */ 00109 QSPI_HandleTypeDef QSPIHandle; 00110 00111 /** 00112 * @} 00113 */ 00114 00115 00116 /* Private functions ---------------------------------------------------------*/ 00117 00118 /** @defgroup STM32L475E_IOT01_QSPI_Private_Functions QSPI Private Functions 00119 * @{ 00120 */ 00121 static uint8_t QSPI_ResetMemory (QSPI_HandleTypeDef *hqspi); 00122 static uint8_t QSPI_WriteEnable (QSPI_HandleTypeDef *hqspi); 00123 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout); 00124 static uint8_t QSPI_QuadMode (QSPI_HandleTypeDef *hqspi, uint8_t Operation); 00125 static uint8_t QSPI_HighPerfMode (QSPI_HandleTypeDef *hqspi, uint8_t Operation); 00126 00127 /** 00128 * @} 00129 */ 00130 00131 /* Exported functions ---------------------------------------------------------*/ 00132 00133 /** @addtogroup STM32L475E_IOT01_QSPI_Exported_Functions 00134 * @{ 00135 */ 00136 00137 /** 00138 * @brief Initializes the QSPI interface. 00139 * @retval QSPI memory status 00140 */ 00141 uint8_t BSP_QSPI_Init(void) 00142 { 00143 QSPIHandle.Instance = QUADSPI; 00144 00145 /* Call the DeInit function to reset the driver */ 00146 if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) 00147 { 00148 return QSPI_ERROR; 00149 } 00150 00151 /* System level initialization */ 00152 BSP_QSPI_MspInit(); 00153 00154 /* QSPI initialization */ 00155 QSPIHandle.Init.ClockPrescaler = 2; /* QSPI clock = 80MHz / (ClockPrescaler+1) = 26.67MHz */ 00156 QSPIHandle.Init.FifoThreshold = 4; 00157 QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; 00158 QSPIHandle.Init.FlashSize = POSITION_VAL(MX25R6435F_FLASH_SIZE) - 1; 00159 QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; 00160 QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0; 00161 00162 if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) 00163 { 00164 return QSPI_ERROR; 00165 } 00166 00167 /* QSPI memory reset */ 00168 if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK) 00169 { 00170 return QSPI_NOT_SUPPORTED; 00171 } 00172 00173 /* QSPI quad enable */ 00174 if (QSPI_QuadMode(&QSPIHandle, QSPI_QUAD_ENABLE) != QSPI_OK) 00175 { 00176 return QSPI_ERROR; 00177 } 00178 00179 /* High performance mode enable */ 00180 if (QSPI_HighPerfMode(&QSPIHandle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK) 00181 { 00182 return QSPI_ERROR; 00183 } 00184 00185 /* Re-configure the clock for the high performance mode */ 00186 QSPIHandle.Init.ClockPrescaler = 1; /* QSPI clock = 80MHz / (ClockPrescaler+1) = 40MHz */ 00187 00188 if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) 00189 { 00190 return QSPI_ERROR; 00191 } 00192 00193 return QSPI_OK; 00194 } 00195 00196 /** 00197 * @brief De-Initializes the QSPI interface. 00198 * @retval QSPI memory status 00199 */ 00200 uint8_t BSP_QSPI_DeInit(void) 00201 { 00202 QSPIHandle.Instance = QUADSPI; 00203 00204 /* Call the DeInit function to reset the driver */ 00205 if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) 00206 { 00207 return QSPI_ERROR; 00208 } 00209 00210 /* System level De-initialization */ 00211 BSP_QSPI_MspDeInit(); 00212 00213 return QSPI_OK; 00214 } 00215 00216 /** 00217 * @brief Reads an amount of data from the QSPI memory. 00218 * @param pData : Pointer to data to be read 00219 * @param ReadAddr : Read start address 00220 * @param Size : Size of data to read 00221 * @retval QSPI memory status 00222 */ 00223 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) 00224 { 00225 QSPI_CommandTypeDef sCommand; 00226 00227 /* Initialize the read command */ 00228 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00229 sCommand.Instruction = QUAD_INOUT_READ_CMD; 00230 sCommand.AddressMode = QSPI_ADDRESS_4_LINES; 00231 sCommand.AddressSize = QSPI_ADDRESS_24_BITS; 00232 sCommand.Address = ReadAddr; 00233 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES; 00234 sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; 00235 sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; 00236 sCommand.DataMode = QSPI_DATA_4_LINES; 00237 sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; 00238 sCommand.NbData = Size; 00239 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00240 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00241 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00242 00243 /* Configure the command */ 00244 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00245 { 00246 return QSPI_ERROR; 00247 } 00248 00249 /* Reception of the data */ 00250 if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00251 { 00252 return QSPI_ERROR; 00253 } 00254 00255 return QSPI_OK; 00256 } 00257 00258 /** 00259 * @brief Writes an amount of data to the QSPI memory. 00260 * @param pData : Pointer to data to be written 00261 * @param WriteAddr : Write start address 00262 * @param Size : Size of data to write 00263 * @retval QSPI memory status 00264 */ 00265 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) 00266 { 00267 QSPI_CommandTypeDef sCommand; 00268 uint32_t end_addr, current_size, current_addr; 00269 00270 /* Calculation of the size between the write address and the end of the page */ 00271 current_size = MX25R6435F_PAGE_SIZE - (WriteAddr % MX25R6435F_PAGE_SIZE); 00272 00273 /* Check if the size of the data is less than the remaining place in the page */ 00274 if (current_size > Size) 00275 { 00276 current_size = Size; 00277 } 00278 00279 /* Initialize the adress variables */ 00280 current_addr = WriteAddr; 00281 end_addr = WriteAddr + Size; 00282 00283 /* Initialize the program command */ 00284 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00285 sCommand.Instruction = QUAD_PAGE_PROG_CMD; 00286 sCommand.AddressMode = QSPI_ADDRESS_4_LINES; 00287 sCommand.AddressSize = QSPI_ADDRESS_24_BITS; 00288 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00289 sCommand.DataMode = QSPI_DATA_4_LINES; 00290 sCommand.DummyCycles = 0; 00291 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00292 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00293 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00294 00295 /* Perform the write page by page */ 00296 do 00297 { 00298 sCommand.Address = current_addr; 00299 sCommand.NbData = current_size; 00300 00301 /* Enable write operations */ 00302 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00303 { 00304 return QSPI_ERROR; 00305 } 00306 00307 /* Configure the command */ 00308 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00309 { 00310 return QSPI_ERROR; 00311 } 00312 00313 /* Transmission of the data */ 00314 if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00315 { 00316 return QSPI_ERROR; 00317 } 00318 00319 /* Configure automatic polling mode to wait for end of program */ 00320 if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) 00321 { 00322 return QSPI_ERROR; 00323 } 00324 00325 /* Update the address and size variables for next page programming */ 00326 current_addr += current_size; 00327 pData += current_size; 00328 current_size = ((current_addr + MX25R6435F_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MX25R6435F_PAGE_SIZE; 00329 } while (current_addr < end_addr); 00330 00331 return QSPI_OK; 00332 } 00333 00334 /** 00335 * @brief Erases the specified block of the QSPI memory. 00336 * @param BlockAddress : Block address to erase 00337 * @retval QSPI memory status 00338 */ 00339 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) 00340 { 00341 QSPI_CommandTypeDef sCommand; 00342 00343 /* Initialize the erase command */ 00344 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00345 sCommand.Instruction = BLOCK_ERASE_CMD; 00346 sCommand.AddressMode = QSPI_ADDRESS_1_LINE; 00347 sCommand.AddressSize = QSPI_ADDRESS_24_BITS; 00348 sCommand.Address = BlockAddress; 00349 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00350 sCommand.DataMode = QSPI_DATA_NONE; 00351 sCommand.DummyCycles = 0; 00352 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00353 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00354 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00355 00356 /* Enable write operations */ 00357 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00358 { 00359 return QSPI_ERROR; 00360 } 00361 00362 /* Send the command */ 00363 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00364 { 00365 return QSPI_ERROR; 00366 } 00367 00368 /* Configure automatic polling mode to wait for end of erase */ 00369 if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) 00370 { 00371 return QSPI_ERROR; 00372 } 00373 00374 return QSPI_OK; 00375 } 00376 00377 /** 00378 * @brief Erases the specified sector of the QSPI memory. 00379 * @param Sector : Sector address to erase (0 to 255) 00380 * @retval QSPI memory status 00381 * @note This function is non blocking meaning that sector erase 00382 * operation is started but not completed when the function 00383 * returns. Application has to call BSP_QSPI_GetStatus() 00384 * to know when the device is available again (i.e. erase operation 00385 * completed). 00386 */ 00387 uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) 00388 { 00389 QSPI_CommandTypeDef sCommand; 00390 00391 if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE)) 00392 { 00393 return QSPI_ERROR; 00394 } 00395 00396 /* Initialize the erase command */ 00397 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00398 sCommand.Instruction = SECTOR_ERASE_CMD; 00399 sCommand.AddressMode = QSPI_ADDRESS_1_LINE; 00400 sCommand.AddressSize = QSPI_ADDRESS_24_BITS; 00401 sCommand.Address = (Sector * MX25R6435F_SECTOR_SIZE); 00402 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00403 sCommand.DataMode = QSPI_DATA_NONE; 00404 sCommand.DummyCycles = 0; 00405 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00406 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00407 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00408 00409 /* Enable write operations */ 00410 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00411 { 00412 return QSPI_ERROR; 00413 } 00414 00415 /* Send the command */ 00416 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00417 { 00418 return QSPI_ERROR; 00419 } 00420 00421 return QSPI_OK; 00422 } 00423 00424 /** 00425 * @brief Erases the entire QSPI memory. 00426 * @retval QSPI memory status 00427 */ 00428 uint8_t BSP_QSPI_Erase_Chip(void) 00429 { 00430 QSPI_CommandTypeDef sCommand; 00431 00432 /* Initialize the erase command */ 00433 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00434 sCommand.Instruction = CHIP_ERASE_CMD; 00435 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00436 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00437 sCommand.DataMode = QSPI_DATA_NONE; 00438 sCommand.DummyCycles = 0; 00439 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00440 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00441 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00442 00443 /* Enable write operations */ 00444 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00445 { 00446 return QSPI_ERROR; 00447 } 00448 00449 /* Send the command */ 00450 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00451 { 00452 return QSPI_ERROR; 00453 } 00454 00455 /* Configure automatic polling mode to wait for end of erase */ 00456 if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) 00457 { 00458 return QSPI_ERROR; 00459 } 00460 00461 return QSPI_OK; 00462 } 00463 00464 /** 00465 * @brief Reads current status of the QSPI memory. 00466 * @retval QSPI memory status 00467 */ 00468 uint8_t BSP_QSPI_GetStatus(void) 00469 { 00470 QSPI_CommandTypeDef sCommand; 00471 uint8_t reg; 00472 00473 /* Initialize the read security register command */ 00474 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00475 sCommand.Instruction = READ_SEC_REG_CMD; 00476 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00477 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00478 sCommand.DataMode = QSPI_DATA_1_LINE; 00479 sCommand.DummyCycles = 0; 00480 sCommand.NbData = 1; 00481 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00482 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00483 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00484 00485 /* Configure the command */ 00486 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00487 { 00488 return QSPI_ERROR; 00489 } 00490 00491 /* Reception of the data */ 00492 if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00493 { 00494 return QSPI_ERROR; 00495 } 00496 00497 /* Check the value of the register */ 00498 if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0) 00499 { 00500 return QSPI_ERROR; 00501 } 00502 else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0) 00503 { 00504 return QSPI_SUSPENDED; 00505 } 00506 00507 /* Initialize the read status register command */ 00508 sCommand.Instruction = READ_STATUS_REG_CMD; 00509 00510 /* Configure the command */ 00511 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00512 { 00513 return QSPI_ERROR; 00514 } 00515 00516 /* Reception of the data */ 00517 if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00518 { 00519 return QSPI_ERROR; 00520 } 00521 00522 /* Check the value of the register */ 00523 if ((reg & MX25R6435F_SR_WIP) != 0) 00524 { 00525 return QSPI_BUSY; 00526 } 00527 else 00528 { 00529 return QSPI_OK; 00530 } 00531 } 00532 00533 /** 00534 * @brief Return the configuration of the QSPI memory. 00535 * @param pInfo : pointer on the configuration structure 00536 * @retval QSPI memory status 00537 */ 00538 uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo) 00539 { 00540 /* Configure the structure with the memory configuration */ 00541 pInfo->FlashSize = MX25R6435F_FLASH_SIZE; 00542 pInfo->EraseSectorSize = MX25R6435F_SECTOR_SIZE; 00543 pInfo->EraseSectorsNumber = (MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE); 00544 pInfo->ProgPageSize = MX25R6435F_PAGE_SIZE; 00545 pInfo->ProgPagesNumber = (MX25R6435F_FLASH_SIZE/MX25R6435F_PAGE_SIZE); 00546 00547 return QSPI_OK; 00548 } 00549 00550 /** 00551 * @brief Configure the QSPI in memory-mapped mode 00552 * @retval QSPI memory status 00553 */ 00554 uint8_t BSP_QSPI_EnableMemoryMappedMode(void) 00555 { 00556 QSPI_CommandTypeDef sCommand; 00557 QSPI_MemoryMappedTypeDef sMemMappedCfg; 00558 00559 /* Configure the command for the read instruction */ 00560 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00561 sCommand.Instruction = QUAD_INOUT_READ_CMD; 00562 sCommand.AddressMode = QSPI_ADDRESS_4_LINES; 00563 sCommand.AddressSize = QSPI_ADDRESS_24_BITS; 00564 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES; 00565 sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; 00566 sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; 00567 sCommand.DataMode = QSPI_DATA_4_LINES; 00568 sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; 00569 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00570 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00571 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00572 00573 /* Configure the memory mapped mode */ 00574 sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; 00575 00576 if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK) 00577 { 00578 return QSPI_ERROR; 00579 } 00580 00581 return QSPI_OK; 00582 } 00583 00584 /** 00585 * @brief This function suspends an ongoing erase command. 00586 * @retval QSPI memory status 00587 */ 00588 uint8_t BSP_QSPI_SuspendErase(void) 00589 { 00590 QSPI_CommandTypeDef sCommand; 00591 00592 /* Check whether the device is busy (erase operation is 00593 in progress). 00594 */ 00595 if (BSP_QSPI_GetStatus() == QSPI_BUSY) 00596 { 00597 /* Initialize the erase command */ 00598 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00599 sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; 00600 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00601 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00602 sCommand.DataMode = QSPI_DATA_NONE; 00603 sCommand.DummyCycles = 0; 00604 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00605 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00606 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00607 00608 /* Send the command */ 00609 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00610 { 00611 return QSPI_ERROR; 00612 } 00613 00614 if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) 00615 { 00616 return QSPI_OK; 00617 } 00618 00619 return QSPI_ERROR; 00620 } 00621 00622 return QSPI_OK; 00623 } 00624 00625 /** 00626 * @brief This function resumes a paused erase command. 00627 * @retval QSPI memory status 00628 */ 00629 uint8_t BSP_QSPI_ResumeErase(void) 00630 { 00631 QSPI_CommandTypeDef sCommand; 00632 00633 /* Check whether the device is in suspended state */ 00634 if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) 00635 { 00636 /* Initialize the erase command */ 00637 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00638 sCommand.Instruction = PROG_ERASE_RESUME_CMD; 00639 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00640 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00641 sCommand.DataMode = QSPI_DATA_NONE; 00642 sCommand.DummyCycles = 0; 00643 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00644 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00645 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00646 00647 /* Send the command */ 00648 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00649 { 00650 return QSPI_ERROR; 00651 } 00652 00653 /* 00654 When this command is executed, the status register write in progress bit is set to 1, and 00655 the flag status register program erase controller bit is set to 0. This command is ignored 00656 if the device is not in a suspended state. 00657 */ 00658 00659 if (BSP_QSPI_GetStatus() == QSPI_BUSY) 00660 { 00661 return QSPI_OK; 00662 } 00663 00664 return QSPI_ERROR; 00665 } 00666 00667 return QSPI_OK; 00668 } 00669 00670 /** 00671 * @brief This function enter the QSPI memory in deep power down mode. 00672 * @retval QSPI memory status 00673 */ 00674 uint8_t BSP_QSPI_EnterDeepPowerDown(void) 00675 { 00676 QSPI_CommandTypeDef sCommand; 00677 00678 /* Initialize the deep power down command */ 00679 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00680 sCommand.Instruction = DEEP_POWER_DOWN_CMD; 00681 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00682 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00683 sCommand.DataMode = QSPI_DATA_NONE; 00684 sCommand.DummyCycles = 0; 00685 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00686 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00687 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00688 00689 /* Send the command */ 00690 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00691 { 00692 return QSPI_ERROR; 00693 } 00694 00695 /* --- Memory takes 10us max to enter deep power down --- */ 00696 /* --- At least 30us should be respected before leaving deep power down --- */ 00697 00698 return QSPI_OK; 00699 } 00700 00701 /** 00702 * @brief This function leave the QSPI memory from deep power down mode. 00703 * @retval QSPI memory status 00704 */ 00705 uint8_t BSP_QSPI_LeaveDeepPowerDown(void) 00706 { 00707 QSPI_CommandTypeDef sCommand; 00708 00709 /* Initialize the erase command */ 00710 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00711 sCommand.Instruction = NO_OPERATION_CMD; 00712 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00713 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00714 sCommand.DataMode = QSPI_DATA_NONE; 00715 sCommand.DummyCycles = 0; 00716 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00717 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00718 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00719 00720 /* Send the command */ 00721 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00722 { 00723 return QSPI_ERROR; 00724 } 00725 00726 /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */ 00727 /* --- Memory takes 35us min to leave deep power down --- */ 00728 00729 return QSPI_OK; 00730 } 00731 00732 /** 00733 * @brief Initializes the QSPI MSP. 00734 * @retval None 00735 */ 00736 __weak void BSP_QSPI_MspInit(void) 00737 { 00738 GPIO_InitTypeDef GPIO_InitStruct; 00739 00740 /* Enable the QuadSPI memory interface clock */ 00741 __HAL_RCC_QSPI_CLK_ENABLE(); 00742 00743 /* Reset the QuadSPI memory interface */ 00744 __HAL_RCC_QSPI_FORCE_RESET(); 00745 __HAL_RCC_QSPI_RELEASE_RESET(); 00746 00747 /* Enable GPIO clocks */ 00748 __HAL_RCC_GPIOE_CLK_ENABLE(); 00749 00750 /* QSPI CLK, CS, D0, D1, D2 and D3 GPIO pins configuration */ 00751 GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |\ 00752 GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 00753 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 00754 GPIO_InitStruct.Pull = GPIO_NOPULL; 00755 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; 00756 GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; 00757 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); 00758 } 00759 00760 /** 00761 * @brief De-Initializes the QSPI MSP. 00762 * @retval None 00763 */ 00764 __weak void BSP_QSPI_MspDeInit(void) 00765 { 00766 GPIO_InitTypeDef GPIO_InitStruct; 00767 00768 /* QSPI CLK, CS, D0-D3 GPIO pins de-configuration */ 00769 __HAL_RCC_GPIOE_CLK_ENABLE(); 00770 GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |\ 00771 GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 00772 00773 HAL_GPIO_DeInit(GPIOE, GPIO_InitStruct.Pin); 00774 00775 /* Reset the QuadSPI memory interface */ 00776 __HAL_RCC_QSPI_FORCE_RESET(); 00777 __HAL_RCC_QSPI_RELEASE_RESET(); 00778 00779 /* Disable the QuadSPI memory interface clock */ 00780 __HAL_RCC_QSPI_CLK_DISABLE(); 00781 } 00782 00783 /** 00784 * @} 00785 */ 00786 00787 /** @addtogroup STM32L475E_IOT01_QSPI_Private_Functions 00788 * @{ 00789 */ 00790 00791 /** 00792 * @brief This function reset the QSPI memory. 00793 * @param hqspi : QSPI handle 00794 * @retval None 00795 */ 00796 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi) 00797 { 00798 QSPI_CommandTypeDef sCommand; 00799 00800 /* Initialize the reset enable command */ 00801 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00802 sCommand.Instruction = RESET_ENABLE_CMD; 00803 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00804 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00805 sCommand.DataMode = QSPI_DATA_NONE; 00806 sCommand.DummyCycles = 0; 00807 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00808 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00809 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00810 00811 /* Send the command */ 00812 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00813 { 00814 return QSPI_ERROR; 00815 } 00816 00817 /* Send the reset memory command */ 00818 sCommand.Instruction = RESET_MEMORY_CMD; 00819 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00820 { 00821 return QSPI_ERROR; 00822 } 00823 00824 /* Configure automatic polling mode to wait the memory is ready */ 00825 if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) 00826 { 00827 return QSPI_ERROR; 00828 } 00829 00830 return QSPI_OK; 00831 } 00832 00833 /** 00834 * @brief This function send a Write Enable and wait it is effective. 00835 * @param hqspi : QSPI handle 00836 * @retval None 00837 */ 00838 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi) 00839 { 00840 QSPI_CommandTypeDef sCommand; 00841 QSPI_AutoPollingTypeDef sConfig; 00842 00843 /* Enable write operations */ 00844 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00845 sCommand.Instruction = WRITE_ENABLE_CMD; 00846 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00847 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00848 sCommand.DataMode = QSPI_DATA_NONE; 00849 sCommand.DummyCycles = 0; 00850 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00851 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00852 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00853 00854 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00855 { 00856 return QSPI_ERROR; 00857 } 00858 00859 /* Configure automatic polling mode to wait for write enabling */ 00860 sConfig.Match = MX25R6435F_SR_WEL; 00861 sConfig.Mask = MX25R6435F_SR_WEL; 00862 sConfig.MatchMode = QSPI_MATCH_MODE_AND; 00863 sConfig.StatusBytesSize = 1; 00864 sConfig.Interval = 0x10; 00865 sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; 00866 00867 sCommand.Instruction = READ_STATUS_REG_CMD; 00868 sCommand.DataMode = QSPI_DATA_1_LINE; 00869 00870 if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00871 { 00872 return QSPI_ERROR; 00873 } 00874 00875 return QSPI_OK; 00876 } 00877 00878 /** 00879 * @brief This function read the SR of the memory and wait the EOP. 00880 * @param hqspi : QSPI handle 00881 * @param Timeout : Timeout for auto-polling 00882 * @retval None 00883 */ 00884 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout) 00885 { 00886 QSPI_CommandTypeDef sCommand; 00887 QSPI_AutoPollingTypeDef sConfig; 00888 00889 /* Configure automatic polling mode to wait for memory ready */ 00890 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00891 sCommand.Instruction = READ_STATUS_REG_CMD; 00892 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00893 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00894 sCommand.DataMode = QSPI_DATA_1_LINE; 00895 sCommand.DummyCycles = 0; 00896 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00897 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00898 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00899 00900 sConfig.Match = 0; 00901 sConfig.Mask = MX25R6435F_SR_WIP; 00902 sConfig.MatchMode = QSPI_MATCH_MODE_AND; 00903 sConfig.StatusBytesSize = 1; 00904 sConfig.Interval = 0x10; 00905 sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; 00906 00907 if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, Timeout) != HAL_OK) 00908 { 00909 return QSPI_ERROR; 00910 } 00911 00912 return QSPI_OK; 00913 } 00914 00915 /** 00916 * @brief This function enables/disables the Quad mode of the memory. 00917 * @param hqspi : QSPI handle 00918 * @param Operation : QSPI_QUAD_ENABLE or QSPI_QUAD_DISABLE mode 00919 * @retval None 00920 */ 00921 static uint8_t QSPI_QuadMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation) 00922 { 00923 QSPI_CommandTypeDef sCommand; 00924 uint8_t reg; 00925 00926 /* Read status register */ 00927 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 00928 sCommand.Instruction = READ_STATUS_REG_CMD; 00929 sCommand.AddressMode = QSPI_ADDRESS_NONE; 00930 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 00931 sCommand.DataMode = QSPI_DATA_1_LINE; 00932 sCommand.DummyCycles = 0; 00933 sCommand.NbData = 1; 00934 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 00935 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 00936 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 00937 00938 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00939 { 00940 return QSPI_ERROR; 00941 } 00942 00943 if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00944 { 00945 return QSPI_ERROR; 00946 } 00947 00948 /* Enable write operations */ 00949 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 00950 { 00951 return QSPI_ERROR; 00952 } 00953 00954 /* Activate/deactivate the Quad mode */ 00955 if (Operation == QSPI_QUAD_ENABLE) 00956 { 00957 SET_BIT(reg, MX25R6435F_SR_QE); 00958 } 00959 else 00960 { 00961 CLEAR_BIT(reg, MX25R6435F_SR_QE); 00962 } 00963 00964 sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; 00965 00966 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00967 { 00968 return QSPI_ERROR; 00969 } 00970 00971 if (HAL_QSPI_Transmit(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00972 { 00973 return QSPI_ERROR; 00974 } 00975 00976 /* Wait that memory is ready */ 00977 if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) 00978 { 00979 return QSPI_ERROR; 00980 } 00981 00982 /* Check the configuration has been correctly done */ 00983 sCommand.Instruction = READ_STATUS_REG_CMD; 00984 00985 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00986 { 00987 return QSPI_ERROR; 00988 } 00989 00990 if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 00991 { 00992 return QSPI_ERROR; 00993 } 00994 00995 if ((((reg & MX25R6435F_SR_QE) == 0) && (Operation == QSPI_QUAD_ENABLE)) || 00996 (((reg & MX25R6435F_SR_QE) != 0) && (Operation == QSPI_QUAD_DISABLE))) 00997 { 00998 return QSPI_ERROR; 00999 } 01000 01001 return QSPI_OK; 01002 } 01003 01004 /** 01005 * @brief This function enables/disables the high performance mode of the memory. 01006 * @param hqspi : QSPI handle 01007 * @param Operation : QSPI_HIGH_PERF_ENABLE or QSPI_HIGH_PERF_DISABLE high performance mode 01008 * @retval None 01009 */ 01010 static uint8_t QSPI_HighPerfMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation) 01011 { 01012 QSPI_CommandTypeDef sCommand; 01013 uint8_t reg[3]; 01014 01015 /* Read status register */ 01016 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; 01017 sCommand.Instruction = READ_STATUS_REG_CMD; 01018 sCommand.AddressMode = QSPI_ADDRESS_NONE; 01019 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; 01020 sCommand.DataMode = QSPI_DATA_1_LINE; 01021 sCommand.DummyCycles = 0; 01022 sCommand.NbData = 1; 01023 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; 01024 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; 01025 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; 01026 01027 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01028 { 01029 return QSPI_ERROR; 01030 } 01031 01032 if (HAL_QSPI_Receive(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01033 { 01034 return QSPI_ERROR; 01035 } 01036 01037 /* Read configuration registers */ 01038 sCommand.Instruction = READ_CFG_REG_CMD; 01039 sCommand.NbData = 2; 01040 01041 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01042 { 01043 return QSPI_ERROR; 01044 } 01045 01046 if (HAL_QSPI_Receive(&QSPIHandle, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01047 { 01048 return QSPI_ERROR; 01049 } 01050 01051 /* Enable write operations */ 01052 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) 01053 { 01054 return QSPI_ERROR; 01055 } 01056 01057 /* Activate/deactivate the Quad mode */ 01058 if (Operation == QSPI_HIGH_PERF_ENABLE) 01059 { 01060 SET_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); 01061 } 01062 else 01063 { 01064 CLEAR_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); 01065 } 01066 01067 sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; 01068 sCommand.NbData = 3; 01069 01070 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01071 { 01072 return QSPI_ERROR; 01073 } 01074 01075 if (HAL_QSPI_Transmit(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01076 { 01077 return QSPI_ERROR; 01078 } 01079 01080 /* Wait that memory is ready */ 01081 if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) 01082 { 01083 return QSPI_ERROR; 01084 } 01085 01086 /* Check the configuration has been correctly done */ 01087 sCommand.Instruction = READ_CFG_REG_CMD; 01088 sCommand.NbData = 2; 01089 01090 if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01091 { 01092 return QSPI_ERROR; 01093 } 01094 01095 if (HAL_QSPI_Receive(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) 01096 { 01097 return QSPI_ERROR; 01098 } 01099 01100 if ((((reg[1] & MX25R6435F_CR2_LH_SWITCH) == 0) && (Operation == QSPI_HIGH_PERF_ENABLE)) || 01101 (((reg[1] & MX25R6435F_CR2_LH_SWITCH) != 0) && (Operation == QSPI_HIGH_PERF_DISABLE))) 01102 { 01103 return QSPI_ERROR; 01104 } 01105 01106 return QSPI_OK; 01107 } 01108 01109 /** 01110 * @} 01111 */ 01112 01113 /** 01114 * @} 01115 */ 01116 01117 /** 01118 * @} 01119 */ 01120 01121 /** 01122 * @} 01123 */ 01124 01125 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 01126
Generated on Thu Mar 16 2017 10:38:32 for B-L475E-IOT01 BSP User Manual by
