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