Mylène Bouquillon / BSP_DISCO_F746NG
Committer:
jeromecoutant
Date:
Wed Nov 27 08:29:42 2019 +0000
Revision:
13:85dbcff443aa
Parent:
10:1050c589b2ad
Fix OV9655 Camera Driver

Who changed what in which revision?

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