sp

Dependents:   WAV

Committer:
phungductung
Date:
Fri Jun 07 05:06:42 2019 +0000
Revision:
0:4e245f4bc8ac
spkt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phungductung 0:4e245f4bc8ac 1 /**
phungductung 0:4e245f4bc8ac 2 ******************************************************************************
phungductung 0:4e245f4bc8ac 3 * @file stm32746g_discovery_qspi.c
phungductung 0:4e245f4bc8ac 4 * @author MCD Application Team
phungductung 0:4e245f4bc8ac 5 * @version V1.0.0
phungductung 0:4e245f4bc8ac 6 * @date 25-June-2015
phungductung 0:4e245f4bc8ac 7 * @brief This file includes a standard driver for the N25Q128A QSPI
phungductung 0:4e245f4bc8ac 8 * memory mounted on STM32746G-Discovery board.
phungductung 0:4e245f4bc8ac 9 @verbatim
phungductung 0:4e245f4bc8ac 10 ==============================================================================
phungductung 0:4e245f4bc8ac 11 ##### How to use this driver #####
phungductung 0:4e245f4bc8ac 12 ==============================================================================
phungductung 0:4e245f4bc8ac 13 [..]
phungductung 0:4e245f4bc8ac 14 (#) This driver is used to drive the N25Q128A QSPI external
phungductung 0:4e245f4bc8ac 15 memory mounted on STM32746G-Discovery board.
phungductung 0:4e245f4bc8ac 16
phungductung 0:4e245f4bc8ac 17 (#) This driver need a specific component driver (N25Q128A) to be included with.
phungductung 0:4e245f4bc8ac 18
phungductung 0:4e245f4bc8ac 19 (#) Initialization steps:
phungductung 0:4e245f4bc8ac 20 (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This
phungductung 0:4e245f4bc8ac 21 function includes the MSP layer hardware resources initialization and the
phungductung 0:4e245f4bc8ac 22 QSPI interface with the external memory.
phungductung 0:4e245f4bc8ac 23
phungductung 0:4e245f4bc8ac 24 (#) QSPI memory operations
phungductung 0:4e245f4bc8ac 25 (++) QSPI memory can be accessed with read/write operations once it is
phungductung 0:4e245f4bc8ac 26 initialized.
phungductung 0:4e245f4bc8ac 27 Read/write operation can be performed with AHB access using the functions
phungductung 0:4e245f4bc8ac 28 BSP_QSPI_Read()/BSP_QSPI_Write().
phungductung 0:4e245f4bc8ac 29 (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory.
phungductung 0:4e245f4bc8ac 30 (see the QSPI memory data sheet)
phungductung 0:4e245f4bc8ac 31 (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
phungductung 0:4e245f4bc8ac 32 specifying the block address. You can perform an erase operation of the whole
phungductung 0:4e245f4bc8ac 33 chip by calling the function BSP_QSPI_Erase_Chip().
phungductung 0:4e245f4bc8ac 34 (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory.
phungductung 0:4e245f4bc8ac 35 (see the QSPI memory data sheet)
phungductung 0:4e245f4bc8ac 36 @endverbatim
phungductung 0:4e245f4bc8ac 37 ******************************************************************************
phungductung 0:4e245f4bc8ac 38 * @attention
phungductung 0:4e245f4bc8ac 39 *
phungductung 0:4e245f4bc8ac 40 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
phungductung 0:4e245f4bc8ac 41 *
phungductung 0:4e245f4bc8ac 42 * Redistribution and use in source and binary forms, with or without modification,
phungductung 0:4e245f4bc8ac 43 * are permitted provided that the following conditions are met:
phungductung 0:4e245f4bc8ac 44 * 1. Redistributions of source code must retain the above copyright notice,
phungductung 0:4e245f4bc8ac 45 * this list of conditions and the following disclaimer.
phungductung 0:4e245f4bc8ac 46 * 2. Redistributions in binary form must reproduce the above copyright notice,
phungductung 0:4e245f4bc8ac 47 * this list of conditions and the following disclaimer in the documentation
phungductung 0:4e245f4bc8ac 48 * and/or other materials provided with the distribution.
phungductung 0:4e245f4bc8ac 49 * 3. Neither the name of STMicroelectronics nor the names of its contributors
phungductung 0:4e245f4bc8ac 50 * may be used to endorse or promote products derived from this software
phungductung 0:4e245f4bc8ac 51 * without specific prior written permission.
phungductung 0:4e245f4bc8ac 52 *
phungductung 0:4e245f4bc8ac 53 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
phungductung 0:4e245f4bc8ac 54 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
phungductung 0:4e245f4bc8ac 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
phungductung 0:4e245f4bc8ac 56 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
phungductung 0:4e245f4bc8ac 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
phungductung 0:4e245f4bc8ac 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
phungductung 0:4e245f4bc8ac 59 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
phungductung 0:4e245f4bc8ac 60 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
phungductung 0:4e245f4bc8ac 61 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
phungductung 0:4e245f4bc8ac 62 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
phungductung 0:4e245f4bc8ac 63 *
phungductung 0:4e245f4bc8ac 64 ******************************************************************************
phungductung 0:4e245f4bc8ac 65 */
phungductung 0:4e245f4bc8ac 66
phungductung 0:4e245f4bc8ac 67 /* Includes ------------------------------------------------------------------*/
phungductung 0:4e245f4bc8ac 68 #include "stm32746g_discovery_qspi.h"
phungductung 0:4e245f4bc8ac 69
phungductung 0:4e245f4bc8ac 70 /** @addtogroup BSP
phungductung 0:4e245f4bc8ac 71 * @{
phungductung 0:4e245f4bc8ac 72 */
phungductung 0:4e245f4bc8ac 73
phungductung 0:4e245f4bc8ac 74 /** @addtogroup STM32746G_DISCOVERY
phungductung 0:4e245f4bc8ac 75 * @{
phungductung 0:4e245f4bc8ac 76 */
phungductung 0:4e245f4bc8ac 77
phungductung 0:4e245f4bc8ac 78 /** @defgroup STM32746G_DISCOVERY_QSPI STM32746G-Discovery QSPI
phungductung 0:4e245f4bc8ac 79 * @{
phungductung 0:4e245f4bc8ac 80 */
phungductung 0:4e245f4bc8ac 81
phungductung 0:4e245f4bc8ac 82
phungductung 0:4e245f4bc8ac 83 /* Private variables ---------------------------------------------------------*/
phungductung 0:4e245f4bc8ac 84
phungductung 0:4e245f4bc8ac 85 /** @defgroup STM32746G_DISCOVERY_QSPI_Private_Variables STM32746G_DISCOVERY QSPI Private Variables
phungductung 0:4e245f4bc8ac 86 * @{
phungductung 0:4e245f4bc8ac 87 */
phungductung 0:4e245f4bc8ac 88 QSPI_HandleTypeDef QSPIHandle;
phungductung 0:4e245f4bc8ac 89
phungductung 0:4e245f4bc8ac 90 /**
phungductung 0:4e245f4bc8ac 91 * @}
phungductung 0:4e245f4bc8ac 92 */
phungductung 0:4e245f4bc8ac 93
phungductung 0:4e245f4bc8ac 94
phungductung 0:4e245f4bc8ac 95
phungductung 0:4e245f4bc8ac 96 /* Private functions ---------------------------------------------------------*/
phungductung 0:4e245f4bc8ac 97
phungductung 0:4e245f4bc8ac 98 /** @defgroup STM32746G_DISCOVERY_QSPI_Private_Functions STM32746G_DISCOVERY QSPI Private Functions
phungductung 0:4e245f4bc8ac 99 * @{
phungductung 0:4e245f4bc8ac 100 */
phungductung 0:4e245f4bc8ac 101 static uint8_t QSPI_ResetMemory (QSPI_HandleTypeDef *hqspi);
phungductung 0:4e245f4bc8ac 102 static uint8_t QSPI_DummyCyclesCfg (QSPI_HandleTypeDef *hqspi);
phungductung 0:4e245f4bc8ac 103 static uint8_t QSPI_WriteEnable (QSPI_HandleTypeDef *hqspi);
phungductung 0:4e245f4bc8ac 104 static uint8_t QSPI_AutoPollingMemReady (QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
phungductung 0:4e245f4bc8ac 105
phungductung 0:4e245f4bc8ac 106 /**
phungductung 0:4e245f4bc8ac 107 * @}
phungductung 0:4e245f4bc8ac 108 */
phungductung 0:4e245f4bc8ac 109
phungductung 0:4e245f4bc8ac 110 /** @defgroup STM32746G_DISCOVERY_QSPI_Exported_Functions STM32746G_DISCOVERY QSPI Exported Functions
phungductung 0:4e245f4bc8ac 111 * @{
phungductung 0:4e245f4bc8ac 112 */
phungductung 0:4e245f4bc8ac 113
phungductung 0:4e245f4bc8ac 114 /**
phungductung 0:4e245f4bc8ac 115 * @brief Initializes the QSPI interface.
phungductung 0:4e245f4bc8ac 116 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 117 */
phungductung 0:4e245f4bc8ac 118 uint8_t BSP_QSPI_Init(void)
phungductung 0:4e245f4bc8ac 119 {
phungductung 0:4e245f4bc8ac 120 QSPIHandle.Instance = QUADSPI;
phungductung 0:4e245f4bc8ac 121
phungductung 0:4e245f4bc8ac 122 /* Call the DeInit function to reset the driver */
phungductung 0:4e245f4bc8ac 123 if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
phungductung 0:4e245f4bc8ac 124 {
phungductung 0:4e245f4bc8ac 125 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 126 }
phungductung 0:4e245f4bc8ac 127
phungductung 0:4e245f4bc8ac 128 /* System level initialization */
phungductung 0:4e245f4bc8ac 129 BSP_QSPI_MspInit(&QSPIHandle, NULL);
phungductung 0:4e245f4bc8ac 130
phungductung 0:4e245f4bc8ac 131 /* QSPI initialization */
phungductung 0:4e245f4bc8ac 132 QSPIHandle.Init.ClockPrescaler = 1; /* QSPI freq = 216 MHz/(1+1) = 108 Mhz */
phungductung 0:4e245f4bc8ac 133 QSPIHandle.Init.FifoThreshold = 4;
phungductung 0:4e245f4bc8ac 134 QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
phungductung 0:4e245f4bc8ac 135 QSPIHandle.Init.FlashSize = POSITION_VAL(N25Q128A_FLASH_SIZE) - 1;
phungductung 0:4e245f4bc8ac 136 QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
phungductung 0:4e245f4bc8ac 137 QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;
phungductung 0:4e245f4bc8ac 138 QSPIHandle.Init.FlashID = QSPI_FLASH_ID_1;
phungductung 0:4e245f4bc8ac 139 QSPIHandle.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
phungductung 0:4e245f4bc8ac 140
phungductung 0:4e245f4bc8ac 141 if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
phungductung 0:4e245f4bc8ac 142 {
phungductung 0:4e245f4bc8ac 143 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 144 }
phungductung 0:4e245f4bc8ac 145
phungductung 0:4e245f4bc8ac 146 /* QSPI memory reset */
phungductung 0:4e245f4bc8ac 147 if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
phungductung 0:4e245f4bc8ac 148 {
phungductung 0:4e245f4bc8ac 149 return QSPI_NOT_SUPPORTED;
phungductung 0:4e245f4bc8ac 150 }
phungductung 0:4e245f4bc8ac 151
phungductung 0:4e245f4bc8ac 152 /* Configuration of the dummy cycles on QSPI memory side */
phungductung 0:4e245f4bc8ac 153 if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
phungductung 0:4e245f4bc8ac 154 {
phungductung 0:4e245f4bc8ac 155 return QSPI_NOT_SUPPORTED;
phungductung 0:4e245f4bc8ac 156 }
phungductung 0:4e245f4bc8ac 157
phungductung 0:4e245f4bc8ac 158 return QSPI_OK;
phungductung 0:4e245f4bc8ac 159 }
phungductung 0:4e245f4bc8ac 160
phungductung 0:4e245f4bc8ac 161 /**
phungductung 0:4e245f4bc8ac 162 * @brief De-Initializes the QSPI interface.
phungductung 0:4e245f4bc8ac 163 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 164 */
phungductung 0:4e245f4bc8ac 165 uint8_t BSP_QSPI_DeInit(void)
phungductung 0:4e245f4bc8ac 166 {
phungductung 0:4e245f4bc8ac 167 QSPIHandle.Instance = QUADSPI;
phungductung 0:4e245f4bc8ac 168
phungductung 0:4e245f4bc8ac 169 /* Call the DeInit function to reset the driver */
phungductung 0:4e245f4bc8ac 170 if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
phungductung 0:4e245f4bc8ac 171 {
phungductung 0:4e245f4bc8ac 172 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 173 }
phungductung 0:4e245f4bc8ac 174
phungductung 0:4e245f4bc8ac 175 /* System level De-initialization */
phungductung 0:4e245f4bc8ac 176 BSP_QSPI_MspDeInit(&QSPIHandle, NULL);
phungductung 0:4e245f4bc8ac 177
phungductung 0:4e245f4bc8ac 178 return QSPI_OK;
phungductung 0:4e245f4bc8ac 179 }
phungductung 0:4e245f4bc8ac 180
phungductung 0:4e245f4bc8ac 181 /**
phungductung 0:4e245f4bc8ac 182 * @brief Reads an amount of data from the QSPI memory.
phungductung 0:4e245f4bc8ac 183 * @param pData: Pointer to data to be read
phungductung 0:4e245f4bc8ac 184 * @param ReadAddr: Read start address
phungductung 0:4e245f4bc8ac 185 * @param Size: Size of data to read
phungductung 0:4e245f4bc8ac 186 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 187 */
phungductung 0:4e245f4bc8ac 188 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
phungductung 0:4e245f4bc8ac 189 {
phungductung 0:4e245f4bc8ac 190 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 191
phungductung 0:4e245f4bc8ac 192 /* Initialize the read command */
phungductung 0:4e245f4bc8ac 193 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 194 s_command.Instruction = QUAD_INOUT_FAST_READ_CMD;
phungductung 0:4e245f4bc8ac 195 s_command.AddressMode = QSPI_ADDRESS_4_LINES;
phungductung 0:4e245f4bc8ac 196 s_command.AddressSize = QSPI_ADDRESS_24_BITS;
phungductung 0:4e245f4bc8ac 197 s_command.Address = ReadAddr;
phungductung 0:4e245f4bc8ac 198 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 199 s_command.DataMode = QSPI_DATA_4_LINES;
phungductung 0:4e245f4bc8ac 200 s_command.DummyCycles = N25Q128A_DUMMY_CYCLES_READ_QUAD;
phungductung 0:4e245f4bc8ac 201 s_command.NbData = Size;
phungductung 0:4e245f4bc8ac 202 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 203 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 204 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 205
phungductung 0:4e245f4bc8ac 206 /* Configure the command */
phungductung 0:4e245f4bc8ac 207 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 208 {
phungductung 0:4e245f4bc8ac 209 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 210 }
phungductung 0:4e245f4bc8ac 211
phungductung 0:4e245f4bc8ac 212 /* Reception of the data */
phungductung 0:4e245f4bc8ac 213 if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 214 {
phungductung 0:4e245f4bc8ac 215 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 216 }
phungductung 0:4e245f4bc8ac 217
phungductung 0:4e245f4bc8ac 218 return QSPI_OK;
phungductung 0:4e245f4bc8ac 219 }
phungductung 0:4e245f4bc8ac 220
phungductung 0:4e245f4bc8ac 221 /**
phungductung 0:4e245f4bc8ac 222 * @brief Writes an amount of data to the QSPI memory.
phungductung 0:4e245f4bc8ac 223 * @param pData: Pointer to data to be written
phungductung 0:4e245f4bc8ac 224 * @param WriteAddr: Write start address
phungductung 0:4e245f4bc8ac 225 * @param Size: Size of data to write
phungductung 0:4e245f4bc8ac 226 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 227 */
phungductung 0:4e245f4bc8ac 228 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
phungductung 0:4e245f4bc8ac 229 {
phungductung 0:4e245f4bc8ac 230 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 231 uint32_t end_addr, current_size, current_addr;
phungductung 0:4e245f4bc8ac 232
phungductung 0:4e245f4bc8ac 233 /* Calculation of the size between the write address and the end of the page */
phungductung 0:4e245f4bc8ac 234 current_addr = 0;
phungductung 0:4e245f4bc8ac 235
phungductung 0:4e245f4bc8ac 236 while (current_addr <= WriteAddr)
phungductung 0:4e245f4bc8ac 237 {
phungductung 0:4e245f4bc8ac 238 current_addr += N25Q128A_PAGE_SIZE;
phungductung 0:4e245f4bc8ac 239 }
phungductung 0:4e245f4bc8ac 240 current_size = current_addr - WriteAddr;
phungductung 0:4e245f4bc8ac 241
phungductung 0:4e245f4bc8ac 242 /* Check if the size of the data is less than the remaining place in the page */
phungductung 0:4e245f4bc8ac 243 if (current_size > Size)
phungductung 0:4e245f4bc8ac 244 {
phungductung 0:4e245f4bc8ac 245 current_size = Size;
phungductung 0:4e245f4bc8ac 246 }
phungductung 0:4e245f4bc8ac 247
phungductung 0:4e245f4bc8ac 248 /* Initialize the adress variables */
phungductung 0:4e245f4bc8ac 249 current_addr = WriteAddr;
phungductung 0:4e245f4bc8ac 250 end_addr = WriteAddr + Size;
phungductung 0:4e245f4bc8ac 251
phungductung 0:4e245f4bc8ac 252 /* Initialize the program command */
phungductung 0:4e245f4bc8ac 253 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 254 s_command.Instruction = EXT_QUAD_IN_FAST_PROG_CMD;
phungductung 0:4e245f4bc8ac 255 s_command.AddressMode = QSPI_ADDRESS_4_LINES;
phungductung 0:4e245f4bc8ac 256 s_command.AddressSize = QSPI_ADDRESS_24_BITS;
phungductung 0:4e245f4bc8ac 257 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 258 s_command.DataMode = QSPI_DATA_4_LINES;
phungductung 0:4e245f4bc8ac 259 s_command.DummyCycles = 0;
phungductung 0:4e245f4bc8ac 260 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 261 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 262 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 263
phungductung 0:4e245f4bc8ac 264 /* Perform the write page by page */
phungductung 0:4e245f4bc8ac 265 do
phungductung 0:4e245f4bc8ac 266 {
phungductung 0:4e245f4bc8ac 267 s_command.Address = current_addr;
phungductung 0:4e245f4bc8ac 268 s_command.NbData = current_size;
phungductung 0:4e245f4bc8ac 269
phungductung 0:4e245f4bc8ac 270 /* Enable write operations */
phungductung 0:4e245f4bc8ac 271 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
phungductung 0:4e245f4bc8ac 272 {
phungductung 0:4e245f4bc8ac 273 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 274 }
phungductung 0:4e245f4bc8ac 275
phungductung 0:4e245f4bc8ac 276 /* Configure the command */
phungductung 0:4e245f4bc8ac 277 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 278 {
phungductung 0:4e245f4bc8ac 279 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 280 }
phungductung 0:4e245f4bc8ac 281
phungductung 0:4e245f4bc8ac 282 /* Transmission of the data */
phungductung 0:4e245f4bc8ac 283 if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 284 {
phungductung 0:4e245f4bc8ac 285 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 286 }
phungductung 0:4e245f4bc8ac 287
phungductung 0:4e245f4bc8ac 288 /* Configure automatic polling mode to wait for end of program */
phungductung 0:4e245f4bc8ac 289 if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
phungductung 0:4e245f4bc8ac 290 {
phungductung 0:4e245f4bc8ac 291 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 292 }
phungductung 0:4e245f4bc8ac 293
phungductung 0:4e245f4bc8ac 294 /* Update the address and size variables for next page programming */
phungductung 0:4e245f4bc8ac 295 current_addr += current_size;
phungductung 0:4e245f4bc8ac 296 pData += current_size;
phungductung 0:4e245f4bc8ac 297 current_size = ((current_addr + N25Q128A_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : N25Q128A_PAGE_SIZE;
phungductung 0:4e245f4bc8ac 298 } while (current_addr < end_addr);
phungductung 0:4e245f4bc8ac 299
phungductung 0:4e245f4bc8ac 300 return QSPI_OK;
phungductung 0:4e245f4bc8ac 301 }
phungductung 0:4e245f4bc8ac 302
phungductung 0:4e245f4bc8ac 303 /**
phungductung 0:4e245f4bc8ac 304 * @brief Erases the specified block of the QSPI memory.
phungductung 0:4e245f4bc8ac 305 * @param BlockAddress: Block address to erase
phungductung 0:4e245f4bc8ac 306 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 307 */
phungductung 0:4e245f4bc8ac 308 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
phungductung 0:4e245f4bc8ac 309 {
phungductung 0:4e245f4bc8ac 310 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 311
phungductung 0:4e245f4bc8ac 312 /* Initialize the erase command */
phungductung 0:4e245f4bc8ac 313 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 314 s_command.Instruction = SUBSECTOR_ERASE_CMD;
phungductung 0:4e245f4bc8ac 315 s_command.AddressMode = QSPI_ADDRESS_1_LINE;
phungductung 0:4e245f4bc8ac 316 s_command.AddressSize = QSPI_ADDRESS_24_BITS;
phungductung 0:4e245f4bc8ac 317 s_command.Address = BlockAddress;
phungductung 0:4e245f4bc8ac 318 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 319 s_command.DataMode = QSPI_DATA_NONE;
phungductung 0:4e245f4bc8ac 320 s_command.DummyCycles = 0;
phungductung 0:4e245f4bc8ac 321 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 322 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 323 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 324
phungductung 0:4e245f4bc8ac 325 /* Enable write operations */
phungductung 0:4e245f4bc8ac 326 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
phungductung 0:4e245f4bc8ac 327 {
phungductung 0:4e245f4bc8ac 328 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 329 }
phungductung 0:4e245f4bc8ac 330
phungductung 0:4e245f4bc8ac 331 /* Send the command */
phungductung 0:4e245f4bc8ac 332 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 333 {
phungductung 0:4e245f4bc8ac 334 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 335 }
phungductung 0:4e245f4bc8ac 336
phungductung 0:4e245f4bc8ac 337 /* Configure automatic polling mode to wait for end of erase */
phungductung 0:4e245f4bc8ac 338 if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
phungductung 0:4e245f4bc8ac 339 {
phungductung 0:4e245f4bc8ac 340 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 341 }
phungductung 0:4e245f4bc8ac 342
phungductung 0:4e245f4bc8ac 343 return QSPI_OK;
phungductung 0:4e245f4bc8ac 344 }
phungductung 0:4e245f4bc8ac 345
phungductung 0:4e245f4bc8ac 346 /**
phungductung 0:4e245f4bc8ac 347 * @brief Erases the entire QSPI memory.
phungductung 0:4e245f4bc8ac 348 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 349 */
phungductung 0:4e245f4bc8ac 350 uint8_t BSP_QSPI_Erase_Chip(void)
phungductung 0:4e245f4bc8ac 351 {
phungductung 0:4e245f4bc8ac 352 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 353
phungductung 0:4e245f4bc8ac 354 /* Initialize the erase command */
phungductung 0:4e245f4bc8ac 355 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 356 s_command.Instruction = BULK_ERASE_CMD;
phungductung 0:4e245f4bc8ac 357 s_command.AddressMode = QSPI_ADDRESS_NONE;
phungductung 0:4e245f4bc8ac 358 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 359 s_command.DataMode = QSPI_DATA_NONE;
phungductung 0:4e245f4bc8ac 360 s_command.DummyCycles = 0;
phungductung 0:4e245f4bc8ac 361 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 362 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 363 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 364
phungductung 0:4e245f4bc8ac 365 /* Enable write operations */
phungductung 0:4e245f4bc8ac 366 if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
phungductung 0:4e245f4bc8ac 367 {
phungductung 0:4e245f4bc8ac 368 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 369 }
phungductung 0:4e245f4bc8ac 370
phungductung 0:4e245f4bc8ac 371 /* Send the command */
phungductung 0:4e245f4bc8ac 372 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 373 {
phungductung 0:4e245f4bc8ac 374 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 375 }
phungductung 0:4e245f4bc8ac 376
phungductung 0:4e245f4bc8ac 377 /* Configure automatic polling mode to wait for end of erase */
phungductung 0:4e245f4bc8ac 378 if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_BULK_ERASE_MAX_TIME) != QSPI_OK)
phungductung 0:4e245f4bc8ac 379 {
phungductung 0:4e245f4bc8ac 380 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 381 }
phungductung 0:4e245f4bc8ac 382
phungductung 0:4e245f4bc8ac 383 return QSPI_OK;
phungductung 0:4e245f4bc8ac 384 }
phungductung 0:4e245f4bc8ac 385
phungductung 0:4e245f4bc8ac 386 /**
phungductung 0:4e245f4bc8ac 387 * @brief Reads current status of the QSPI memory.
phungductung 0:4e245f4bc8ac 388 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 389 */
phungductung 0:4e245f4bc8ac 390 uint8_t BSP_QSPI_GetStatus(void)
phungductung 0:4e245f4bc8ac 391 {
phungductung 0:4e245f4bc8ac 392 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 393 uint8_t reg;
phungductung 0:4e245f4bc8ac 394
phungductung 0:4e245f4bc8ac 395 /* Initialize the read flag status register command */
phungductung 0:4e245f4bc8ac 396 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 397 s_command.Instruction = READ_FLAG_STATUS_REG_CMD;
phungductung 0:4e245f4bc8ac 398 s_command.AddressMode = QSPI_ADDRESS_NONE;
phungductung 0:4e245f4bc8ac 399 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 400 s_command.DataMode = QSPI_DATA_1_LINE;
phungductung 0:4e245f4bc8ac 401 s_command.DummyCycles = 0;
phungductung 0:4e245f4bc8ac 402 s_command.NbData = 1;
phungductung 0:4e245f4bc8ac 403 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 404 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 405 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 406
phungductung 0:4e245f4bc8ac 407 /* Configure the command */
phungductung 0:4e245f4bc8ac 408 if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 409 {
phungductung 0:4e245f4bc8ac 410 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 411 }
phungductung 0:4e245f4bc8ac 412
phungductung 0:4e245f4bc8ac 413 /* Reception of the data */
phungductung 0:4e245f4bc8ac 414 if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 415 {
phungductung 0:4e245f4bc8ac 416 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 417 }
phungductung 0:4e245f4bc8ac 418
phungductung 0:4e245f4bc8ac 419 /* Check the value of the register */
phungductung 0:4e245f4bc8ac 420 if ((reg & (N25Q128A_FSR_PRERR | N25Q128A_FSR_VPPERR | N25Q128A_FSR_PGERR | N25Q128A_FSR_ERERR)) != 0)
phungductung 0:4e245f4bc8ac 421 {
phungductung 0:4e245f4bc8ac 422 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 423 }
phungductung 0:4e245f4bc8ac 424 else if ((reg & (N25Q128A_FSR_PGSUS | N25Q128A_FSR_ERSUS)) != 0)
phungductung 0:4e245f4bc8ac 425 {
phungductung 0:4e245f4bc8ac 426 return QSPI_SUSPENDED;
phungductung 0:4e245f4bc8ac 427 }
phungductung 0:4e245f4bc8ac 428 else if ((reg & N25Q128A_FSR_READY) != 0)
phungductung 0:4e245f4bc8ac 429 {
phungductung 0:4e245f4bc8ac 430 return QSPI_OK;
phungductung 0:4e245f4bc8ac 431 }
phungductung 0:4e245f4bc8ac 432 else
phungductung 0:4e245f4bc8ac 433 {
phungductung 0:4e245f4bc8ac 434 return QSPI_BUSY;
phungductung 0:4e245f4bc8ac 435 }
phungductung 0:4e245f4bc8ac 436 }
phungductung 0:4e245f4bc8ac 437
phungductung 0:4e245f4bc8ac 438 /**
phungductung 0:4e245f4bc8ac 439 * @brief Return the configuration of the QSPI memory.
phungductung 0:4e245f4bc8ac 440 * @param pInfo: pointer on the configuration structure
phungductung 0:4e245f4bc8ac 441 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 442 */
phungductung 0:4e245f4bc8ac 443 uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo)
phungductung 0:4e245f4bc8ac 444 {
phungductung 0:4e245f4bc8ac 445 /* Configure the structure with the memory configuration */
phungductung 0:4e245f4bc8ac 446 pInfo->FlashSize = N25Q128A_FLASH_SIZE;
phungductung 0:4e245f4bc8ac 447 pInfo->EraseSectorSize = N25Q128A_SUBSECTOR_SIZE;
phungductung 0:4e245f4bc8ac 448 pInfo->EraseSectorsNumber = (N25Q128A_FLASH_SIZE/N25Q128A_SUBSECTOR_SIZE);
phungductung 0:4e245f4bc8ac 449 pInfo->ProgPageSize = N25Q128A_PAGE_SIZE;
phungductung 0:4e245f4bc8ac 450 pInfo->ProgPagesNumber = (N25Q128A_FLASH_SIZE/N25Q128A_PAGE_SIZE);
phungductung 0:4e245f4bc8ac 451
phungductung 0:4e245f4bc8ac 452 return QSPI_OK;
phungductung 0:4e245f4bc8ac 453 }
phungductung 0:4e245f4bc8ac 454
phungductung 0:4e245f4bc8ac 455 /**
phungductung 0:4e245f4bc8ac 456 * @brief Configure the QSPI in memory-mapped mode
phungductung 0:4e245f4bc8ac 457 * @retval QSPI memory status
phungductung 0:4e245f4bc8ac 458 */
phungductung 0:4e245f4bc8ac 459 uint8_t BSP_QSPI_MemoryMappedMode(void)
phungductung 0:4e245f4bc8ac 460 {
phungductung 0:4e245f4bc8ac 461 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 462 QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
phungductung 0:4e245f4bc8ac 463
phungductung 0:4e245f4bc8ac 464 /* Configure the command for the read instruction */
phungductung 0:4e245f4bc8ac 465 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 466 s_command.Instruction = QUAD_INOUT_FAST_READ_CMD;
phungductung 0:4e245f4bc8ac 467 s_command.AddressMode = QSPI_ADDRESS_4_LINES;
phungductung 0:4e245f4bc8ac 468 s_command.AddressSize = QSPI_ADDRESS_24_BITS;
phungductung 0:4e245f4bc8ac 469 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 470 s_command.DataMode = QSPI_DATA_4_LINES;
phungductung 0:4e245f4bc8ac 471 s_command.DummyCycles = N25Q128A_DUMMY_CYCLES_READ_QUAD;
phungductung 0:4e245f4bc8ac 472 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 473 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 474 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 475
phungductung 0:4e245f4bc8ac 476 /* Configure the memory mapped mode */
phungductung 0:4e245f4bc8ac 477 s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_ENABLE;
phungductung 0:4e245f4bc8ac 478 s_mem_mapped_cfg.TimeOutPeriod = 1;
phungductung 0:4e245f4bc8ac 479
phungductung 0:4e245f4bc8ac 480 if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
phungductung 0:4e245f4bc8ac 481 {
phungductung 0:4e245f4bc8ac 482 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 483 }
phungductung 0:4e245f4bc8ac 484
phungductung 0:4e245f4bc8ac 485 return QSPI_OK;
phungductung 0:4e245f4bc8ac 486 }
phungductung 0:4e245f4bc8ac 487
phungductung 0:4e245f4bc8ac 488 /**
phungductung 0:4e245f4bc8ac 489 * @}
phungductung 0:4e245f4bc8ac 490 */
phungductung 0:4e245f4bc8ac 491
phungductung 0:4e245f4bc8ac 492 /** @addtogroup STM32746G_DISCOVERY_QSPI_Private_Functions
phungductung 0:4e245f4bc8ac 493 * @{
phungductung 0:4e245f4bc8ac 494 */
phungductung 0:4e245f4bc8ac 495
phungductung 0:4e245f4bc8ac 496 /**
phungductung 0:4e245f4bc8ac 497 * @brief QSPI MSP Initialization
phungductung 0:4e245f4bc8ac 498 * This function configures the hardware resources used in this example:
phungductung 0:4e245f4bc8ac 499 * - Peripheral's clock enable
phungductung 0:4e245f4bc8ac 500 * - Peripheral's GPIO Configuration
phungductung 0:4e245f4bc8ac 501 * - NVIC configuration for QSPI interrupt
phungductung 0:4e245f4bc8ac 502 * @retval None
phungductung 0:4e245f4bc8ac 503 */
phungductung 0:4e245f4bc8ac 504 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
phungductung 0:4e245f4bc8ac 505 {
phungductung 0:4e245f4bc8ac 506 GPIO_InitTypeDef gpio_init_structure;
phungductung 0:4e245f4bc8ac 507
phungductung 0:4e245f4bc8ac 508 /*##-1- Enable peripherals and GPIO Clocks #################################*/
phungductung 0:4e245f4bc8ac 509 /* Enable the QuadSPI memory interface clock */
phungductung 0:4e245f4bc8ac 510 QSPI_CLK_ENABLE();
phungductung 0:4e245f4bc8ac 511 /* Reset the QuadSPI memory interface */
phungductung 0:4e245f4bc8ac 512 QSPI_FORCE_RESET();
phungductung 0:4e245f4bc8ac 513 QSPI_RELEASE_RESET();
phungductung 0:4e245f4bc8ac 514 /* Enable GPIO clocks */
phungductung 0:4e245f4bc8ac 515 QSPI_CS_GPIO_CLK_ENABLE();
phungductung 0:4e245f4bc8ac 516 QSPI_CLK_GPIO_CLK_ENABLE();
phungductung 0:4e245f4bc8ac 517 QSPI_D0_GPIO_CLK_ENABLE();
phungductung 0:4e245f4bc8ac 518 QSPI_D1_GPIO_CLK_ENABLE();
phungductung 0:4e245f4bc8ac 519 QSPI_D2_GPIO_CLK_ENABLE();
phungductung 0:4e245f4bc8ac 520 QSPI_D3_GPIO_CLK_ENABLE();
phungductung 0:4e245f4bc8ac 521
phungductung 0:4e245f4bc8ac 522 /*##-2- Configure peripheral GPIO ##########################################*/
phungductung 0:4e245f4bc8ac 523 /* QSPI CS GPIO pin configuration */
phungductung 0:4e245f4bc8ac 524 gpio_init_structure.Pin = QSPI_CS_PIN;
phungductung 0:4e245f4bc8ac 525 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
phungductung 0:4e245f4bc8ac 526 gpio_init_structure.Pull = GPIO_PULLUP;
phungductung 0:4e245f4bc8ac 527 gpio_init_structure.Speed = GPIO_SPEED_HIGH;
phungductung 0:4e245f4bc8ac 528 gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
phungductung 0:4e245f4bc8ac 529 HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
phungductung 0:4e245f4bc8ac 530
phungductung 0:4e245f4bc8ac 531 /* QSPI CLK GPIO pin configuration */
phungductung 0:4e245f4bc8ac 532 gpio_init_structure.Pin = QSPI_CLK_PIN;
phungductung 0:4e245f4bc8ac 533 gpio_init_structure.Pull = GPIO_NOPULL;
phungductung 0:4e245f4bc8ac 534 gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
phungductung 0:4e245f4bc8ac 535 HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
phungductung 0:4e245f4bc8ac 536
phungductung 0:4e245f4bc8ac 537 /* QSPI D0 GPIO pin configuration */
phungductung 0:4e245f4bc8ac 538 gpio_init_structure.Pin = QSPI_D0_PIN;
phungductung 0:4e245f4bc8ac 539 gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
phungductung 0:4e245f4bc8ac 540 HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure);
phungductung 0:4e245f4bc8ac 541
phungductung 0:4e245f4bc8ac 542 /* QSPI D1 GPIO pin configuration */
phungductung 0:4e245f4bc8ac 543 gpio_init_structure.Pin = QSPI_D1_PIN;
phungductung 0:4e245f4bc8ac 544 gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
phungductung 0:4e245f4bc8ac 545 HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure);
phungductung 0:4e245f4bc8ac 546
phungductung 0:4e245f4bc8ac 547 /* QSPI D2 GPIO pin configuration */
phungductung 0:4e245f4bc8ac 548 gpio_init_structure.Pin = QSPI_D2_PIN;
phungductung 0:4e245f4bc8ac 549 gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
phungductung 0:4e245f4bc8ac 550 HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure);
phungductung 0:4e245f4bc8ac 551
phungductung 0:4e245f4bc8ac 552 /* QSPI D3 GPIO pin configuration */
phungductung 0:4e245f4bc8ac 553 gpio_init_structure.Pin = QSPI_D3_PIN;
phungductung 0:4e245f4bc8ac 554 gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
phungductung 0:4e245f4bc8ac 555 HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure);
phungductung 0:4e245f4bc8ac 556
phungductung 0:4e245f4bc8ac 557 /*##-3- Configure the NVIC for QSPI #########################################*/
phungductung 0:4e245f4bc8ac 558 /* NVIC configuration for QSPI interrupt */
phungductung 0:4e245f4bc8ac 559 HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
phungductung 0:4e245f4bc8ac 560 HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
phungductung 0:4e245f4bc8ac 561 }
phungductung 0:4e245f4bc8ac 562
phungductung 0:4e245f4bc8ac 563 /**
phungductung 0:4e245f4bc8ac 564 * @brief QSPI MSP De-Initialization
phungductung 0:4e245f4bc8ac 565 * This function frees the hardware resources used in this example:
phungductung 0:4e245f4bc8ac 566 * - Disable the Peripheral's clock
phungductung 0:4e245f4bc8ac 567 * - Revert GPIO and NVIC configuration to their default state
phungductung 0:4e245f4bc8ac 568 * @retval None
phungductung 0:4e245f4bc8ac 569 */
phungductung 0:4e245f4bc8ac 570 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
phungductung 0:4e245f4bc8ac 571 {
phungductung 0:4e245f4bc8ac 572 /*##-1- Disable the NVIC for QSPI ###########################################*/
phungductung 0:4e245f4bc8ac 573 HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
phungductung 0:4e245f4bc8ac 574
phungductung 0:4e245f4bc8ac 575 /*##-2- Disable peripherals and GPIO Clocks ################################*/
phungductung 0:4e245f4bc8ac 576 /* De-Configure QSPI pins */
phungductung 0:4e245f4bc8ac 577 HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN);
phungductung 0:4e245f4bc8ac 578 HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
phungductung 0:4e245f4bc8ac 579 HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN);
phungductung 0:4e245f4bc8ac 580 HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN);
phungductung 0:4e245f4bc8ac 581 HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN);
phungductung 0:4e245f4bc8ac 582 HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN);
phungductung 0:4e245f4bc8ac 583
phungductung 0:4e245f4bc8ac 584 /*##-3- Reset peripherals ##################################################*/
phungductung 0:4e245f4bc8ac 585 /* Reset the QuadSPI memory interface */
phungductung 0:4e245f4bc8ac 586 QSPI_FORCE_RESET();
phungductung 0:4e245f4bc8ac 587 QSPI_RELEASE_RESET();
phungductung 0:4e245f4bc8ac 588
phungductung 0:4e245f4bc8ac 589 /* Disable the QuadSPI memory interface clock */
phungductung 0:4e245f4bc8ac 590 QSPI_CLK_DISABLE();
phungductung 0:4e245f4bc8ac 591 }
phungductung 0:4e245f4bc8ac 592
phungductung 0:4e245f4bc8ac 593 /**
phungductung 0:4e245f4bc8ac 594 * @brief This function reset the QSPI memory.
phungductung 0:4e245f4bc8ac 595 * @param hqspi: QSPI handle
phungductung 0:4e245f4bc8ac 596 * @retval None
phungductung 0:4e245f4bc8ac 597 */
phungductung 0:4e245f4bc8ac 598 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
phungductung 0:4e245f4bc8ac 599 {
phungductung 0:4e245f4bc8ac 600 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 601
phungductung 0:4e245f4bc8ac 602 /* Initialize the reset enable command */
phungductung 0:4e245f4bc8ac 603 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 604 s_command.Instruction = RESET_ENABLE_CMD;
phungductung 0:4e245f4bc8ac 605 s_command.AddressMode = QSPI_ADDRESS_NONE;
phungductung 0:4e245f4bc8ac 606 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 607 s_command.DataMode = QSPI_DATA_NONE;
phungductung 0:4e245f4bc8ac 608 s_command.DummyCycles = 0;
phungductung 0:4e245f4bc8ac 609 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 610 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 611 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 612
phungductung 0:4e245f4bc8ac 613 /* Send the command */
phungductung 0:4e245f4bc8ac 614 if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 615 {
phungductung 0:4e245f4bc8ac 616 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 617 }
phungductung 0:4e245f4bc8ac 618
phungductung 0:4e245f4bc8ac 619 /* Send the reset memory command */
phungductung 0:4e245f4bc8ac 620 s_command.Instruction = RESET_MEMORY_CMD;
phungductung 0:4e245f4bc8ac 621 if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 622 {
phungductung 0:4e245f4bc8ac 623 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 624 }
phungductung 0:4e245f4bc8ac 625
phungductung 0:4e245f4bc8ac 626 /* Configure automatic polling mode to wait the memory is ready */
phungductung 0:4e245f4bc8ac 627 if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
phungductung 0:4e245f4bc8ac 628 {
phungductung 0:4e245f4bc8ac 629 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 630 }
phungductung 0:4e245f4bc8ac 631
phungductung 0:4e245f4bc8ac 632 return QSPI_OK;
phungductung 0:4e245f4bc8ac 633 }
phungductung 0:4e245f4bc8ac 634
phungductung 0:4e245f4bc8ac 635 /**
phungductung 0:4e245f4bc8ac 636 * @brief This function configure the dummy cycles on memory side.
phungductung 0:4e245f4bc8ac 637 * @param hqspi: QSPI handle
phungductung 0:4e245f4bc8ac 638 * @retval None
phungductung 0:4e245f4bc8ac 639 */
phungductung 0:4e245f4bc8ac 640 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
phungductung 0:4e245f4bc8ac 641 {
phungductung 0:4e245f4bc8ac 642 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 643 uint8_t reg;
phungductung 0:4e245f4bc8ac 644
phungductung 0:4e245f4bc8ac 645 /* Initialize the read volatile configuration register command */
phungductung 0:4e245f4bc8ac 646 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 647 s_command.Instruction = READ_VOL_CFG_REG_CMD;
phungductung 0:4e245f4bc8ac 648 s_command.AddressMode = QSPI_ADDRESS_NONE;
phungductung 0:4e245f4bc8ac 649 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 650 s_command.DataMode = QSPI_DATA_1_LINE;
phungductung 0:4e245f4bc8ac 651 s_command.DummyCycles = 0;
phungductung 0:4e245f4bc8ac 652 s_command.NbData = 1;
phungductung 0:4e245f4bc8ac 653 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 654 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 655 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 656
phungductung 0:4e245f4bc8ac 657 /* Configure the command */
phungductung 0:4e245f4bc8ac 658 if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 659 {
phungductung 0:4e245f4bc8ac 660 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 661 }
phungductung 0:4e245f4bc8ac 662
phungductung 0:4e245f4bc8ac 663 /* Reception of the data */
phungductung 0:4e245f4bc8ac 664 if (HAL_QSPI_Receive(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 665 {
phungductung 0:4e245f4bc8ac 666 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 667 }
phungductung 0:4e245f4bc8ac 668
phungductung 0:4e245f4bc8ac 669 /* Enable write operations */
phungductung 0:4e245f4bc8ac 670 if (QSPI_WriteEnable(hqspi) != QSPI_OK)
phungductung 0:4e245f4bc8ac 671 {
phungductung 0:4e245f4bc8ac 672 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 673 }
phungductung 0:4e245f4bc8ac 674
phungductung 0:4e245f4bc8ac 675 /* Update volatile configuration register (with new dummy cycles) */
phungductung 0:4e245f4bc8ac 676 s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
phungductung 0:4e245f4bc8ac 677 MODIFY_REG(reg, N25Q128A_VCR_NB_DUMMY, (N25Q128A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q128A_VCR_NB_DUMMY)));
phungductung 0:4e245f4bc8ac 678
phungductung 0:4e245f4bc8ac 679 /* Configure the write volatile configuration register command */
phungductung 0:4e245f4bc8ac 680 if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 681 {
phungductung 0:4e245f4bc8ac 682 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 683 }
phungductung 0:4e245f4bc8ac 684
phungductung 0:4e245f4bc8ac 685 /* Transmission of the data */
phungductung 0:4e245f4bc8ac 686 if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 687 {
phungductung 0:4e245f4bc8ac 688 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 689 }
phungductung 0:4e245f4bc8ac 690
phungductung 0:4e245f4bc8ac 691 return QSPI_OK;
phungductung 0:4e245f4bc8ac 692 }
phungductung 0:4e245f4bc8ac 693
phungductung 0:4e245f4bc8ac 694 /**
phungductung 0:4e245f4bc8ac 695 * @brief This function send a Write Enable and wait it is effective.
phungductung 0:4e245f4bc8ac 696 * @param hqspi: QSPI handle
phungductung 0:4e245f4bc8ac 697 * @retval None
phungductung 0:4e245f4bc8ac 698 */
phungductung 0:4e245f4bc8ac 699 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
phungductung 0:4e245f4bc8ac 700 {
phungductung 0:4e245f4bc8ac 701 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 702 QSPI_AutoPollingTypeDef s_config;
phungductung 0:4e245f4bc8ac 703
phungductung 0:4e245f4bc8ac 704 /* Enable write operations */
phungductung 0:4e245f4bc8ac 705 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 706 s_command.Instruction = WRITE_ENABLE_CMD;
phungductung 0:4e245f4bc8ac 707 s_command.AddressMode = QSPI_ADDRESS_NONE;
phungductung 0:4e245f4bc8ac 708 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 709 s_command.DataMode = QSPI_DATA_NONE;
phungductung 0:4e245f4bc8ac 710 s_command.DummyCycles = 0;
phungductung 0:4e245f4bc8ac 711 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 712 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 713 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 714
phungductung 0:4e245f4bc8ac 715 if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 716 {
phungductung 0:4e245f4bc8ac 717 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 718 }
phungductung 0:4e245f4bc8ac 719
phungductung 0:4e245f4bc8ac 720 /* Configure automatic polling mode to wait for write enabling */
phungductung 0:4e245f4bc8ac 721 s_config.Match = N25Q128A_SR_WREN;
phungductung 0:4e245f4bc8ac 722 s_config.Mask = N25Q128A_SR_WREN;
phungductung 0:4e245f4bc8ac 723 s_config.MatchMode = QSPI_MATCH_MODE_AND;
phungductung 0:4e245f4bc8ac 724 s_config.StatusBytesSize = 1;
phungductung 0:4e245f4bc8ac 725 s_config.Interval = 0x10;
phungductung 0:4e245f4bc8ac 726 s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
phungductung 0:4e245f4bc8ac 727
phungductung 0:4e245f4bc8ac 728 s_command.Instruction = READ_STATUS_REG_CMD;
phungductung 0:4e245f4bc8ac 729 s_command.DataMode = QSPI_DATA_1_LINE;
phungductung 0:4e245f4bc8ac 730
phungductung 0:4e245f4bc8ac 731 if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
phungductung 0:4e245f4bc8ac 732 {
phungductung 0:4e245f4bc8ac 733 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 734 }
phungductung 0:4e245f4bc8ac 735
phungductung 0:4e245f4bc8ac 736 return QSPI_OK;
phungductung 0:4e245f4bc8ac 737 }
phungductung 0:4e245f4bc8ac 738
phungductung 0:4e245f4bc8ac 739 /**
phungductung 0:4e245f4bc8ac 740 * @brief This function read the SR of the memory and wait the EOP.
phungductung 0:4e245f4bc8ac 741 * @param hqspi: QSPI handle
phungductung 0:4e245f4bc8ac 742 * @param Timeout
phungductung 0:4e245f4bc8ac 743 * @retval None
phungductung 0:4e245f4bc8ac 744 */
phungductung 0:4e245f4bc8ac 745 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
phungductung 0:4e245f4bc8ac 746 {
phungductung 0:4e245f4bc8ac 747 QSPI_CommandTypeDef s_command;
phungductung 0:4e245f4bc8ac 748 QSPI_AutoPollingTypeDef s_config;
phungductung 0:4e245f4bc8ac 749
phungductung 0:4e245f4bc8ac 750 /* Configure automatic polling mode to wait for memory ready */
phungductung 0:4e245f4bc8ac 751 s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
phungductung 0:4e245f4bc8ac 752 s_command.Instruction = READ_STATUS_REG_CMD;
phungductung 0:4e245f4bc8ac 753 s_command.AddressMode = QSPI_ADDRESS_NONE;
phungductung 0:4e245f4bc8ac 754 s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
phungductung 0:4e245f4bc8ac 755 s_command.DataMode = QSPI_DATA_1_LINE;
phungductung 0:4e245f4bc8ac 756 s_command.DummyCycles = 0;
phungductung 0:4e245f4bc8ac 757 s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
phungductung 0:4e245f4bc8ac 758 s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
phungductung 0:4e245f4bc8ac 759 s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
phungductung 0:4e245f4bc8ac 760
phungductung 0:4e245f4bc8ac 761 s_config.Match = 0;
phungductung 0:4e245f4bc8ac 762 s_config.Mask = N25Q128A_SR_WIP;
phungductung 0:4e245f4bc8ac 763 s_config.MatchMode = QSPI_MATCH_MODE_AND;
phungductung 0:4e245f4bc8ac 764 s_config.StatusBytesSize = 1;
phungductung 0:4e245f4bc8ac 765 s_config.Interval = 0x10;
phungductung 0:4e245f4bc8ac 766 s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
phungductung 0:4e245f4bc8ac 767
phungductung 0:4e245f4bc8ac 768 if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
phungductung 0:4e245f4bc8ac 769 {
phungductung 0:4e245f4bc8ac 770 return QSPI_ERROR;
phungductung 0:4e245f4bc8ac 771 }
phungductung 0:4e245f4bc8ac 772
phungductung 0:4e245f4bc8ac 773 return QSPI_OK;
phungductung 0:4e245f4bc8ac 774 }
phungductung 0:4e245f4bc8ac 775 /**
phungductung 0:4e245f4bc8ac 776 * @}
phungductung 0:4e245f4bc8ac 777 */
phungductung 0:4e245f4bc8ac 778
phungductung 0:4e245f4bc8ac 779 /**
phungductung 0:4e245f4bc8ac 780 * @}
phungductung 0:4e245f4bc8ac 781 */
phungductung 0:4e245f4bc8ac 782
phungductung 0:4e245f4bc8ac 783 /**
phungductung 0:4e245f4bc8ac 784 * @}
phungductung 0:4e245f4bc8ac 785 */
phungductung 0:4e245f4bc8ac 786
phungductung 0:4e245f4bc8ac 787 /**
phungductung 0:4e245f4bc8ac 788 * @}
phungductung 0:4e245f4bc8ac 789 */
phungductung 0:4e245f4bc8ac 790
phungductung 0:4e245f4bc8ac 791 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
phungductung 0:4e245f4bc8ac 792