BSP library for DISCO-STM32F746NG board. Added support for on-board QSPI Flash memory MICRO N25Q128A. Ported from library BSP_DISCO_L476VG.
Fork of BSP_DISCO_F746NG by
stm32f746g_discovery_qspi.c@1:6c23a7cf204c, 2015-11-15 (annotated)
- Committer:
- capsavon
- Date:
- Sun Nov 15 11:37:54 2015 +0000
- Revision:
- 1:6c23a7cf204c
Added support for quad SPI and Flash SPI IC.; Ported from the DISCO-STM32L476VG library.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
capsavon | 1:6c23a7cf204c | 1 | /** |
capsavon | 1:6c23a7cf204c | 2 | ****************************************************************************** |
capsavon | 1:6c23a7cf204c | 3 | * @file stm32f746g_discovery_qspi.c |
capsavon | 1:6c23a7cf204c | 4 | * @author MCD Application Team |
capsavon | 1:6c23a7cf204c | 5 | * @version V1.0.0 |
capsavon | 1:6c23a7cf204c | 6 | * @date 15-november-2015 |
capsavon | 1:6c23a7cf204c | 7 | * @brief This file includes a standard driver for the N25Q128A QSPI |
capsavon | 1:6c23a7cf204c | 8 | * memory mounted on STM32F746G-Discovery board. |
capsavon | 1:6c23a7cf204c | 9 | @verbatim |
capsavon | 1:6c23a7cf204c | 10 | ============================================================================== |
capsavon | 1:6c23a7cf204c | 11 | ##### How to use this driver ##### |
capsavon | 1:6c23a7cf204c | 12 | ============================================================================== |
capsavon | 1:6c23a7cf204c | 13 | [..] |
capsavon | 1:6c23a7cf204c | 14 | (#) This driver is used to drive the N25Q128A QSPI external |
capsavon | 1:6c23a7cf204c | 15 | memory mounted on STM32F746G-DISCO evaluation board. |
capsavon | 1:6c23a7cf204c | 16 | |
capsavon | 1:6c23a7cf204c | 17 | (#) This driver need a specific component driver (N25Q128A) to be included with. |
capsavon | 1:6c23a7cf204c | 18 | |
capsavon | 1:6c23a7cf204c | 19 | (#) Initialization steps: |
capsavon | 1:6c23a7cf204c | 20 | (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This |
capsavon | 1:6c23a7cf204c | 21 | function includes the MSP layer hardware resources initialization and the |
capsavon | 1:6c23a7cf204c | 22 | QSPI interface with the external memory. |
capsavon | 1:6c23a7cf204c | 23 | |
capsavon | 1:6c23a7cf204c | 24 | (#) QSPI memory operations |
capsavon | 1:6c23a7cf204c | 25 | (++) QSPI memory can be accessed with read/write operations once it is |
capsavon | 1:6c23a7cf204c | 26 | initialized. |
capsavon | 1:6c23a7cf204c | 27 | Read/write operation can be performed with AHB access using the functions |
capsavon | 1:6c23a7cf204c | 28 | BSP_QSPI_Read()/BSP_QSPI_Write(). |
capsavon | 1:6c23a7cf204c | 29 | (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. |
capsavon | 1:6c23a7cf204c | 30 | (see the QSPI memory data sheet) |
capsavon | 1:6c23a7cf204c | 31 | (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by |
capsavon | 1:6c23a7cf204c | 32 | specifying the block address. You can perform an erase operation of the whole |
capsavon | 1:6c23a7cf204c | 33 | chip by calling the function BSP_QSPI_Erase_Chip(). |
capsavon | 1:6c23a7cf204c | 34 | (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. |
capsavon | 1:6c23a7cf204c | 35 | (see the QSPI memory data sheet) |
capsavon | 1:6c23a7cf204c | 36 | @endverbatim |
capsavon | 1:6c23a7cf204c | 37 | ****************************************************************************** |
capsavon | 1:6c23a7cf204c | 38 | * @attention |
capsavon | 1:6c23a7cf204c | 39 | * |
capsavon | 1:6c23a7cf204c | 40 | * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> |
capsavon | 1:6c23a7cf204c | 41 | * |
capsavon | 1:6c23a7cf204c | 42 | * Redistribution and use in source and binary forms, with or without modification, |
capsavon | 1:6c23a7cf204c | 43 | * are permitted provided that the following conditions are met: |
capsavon | 1:6c23a7cf204c | 44 | * 1. Redistributions of source code must retain the above copyright notice, |
capsavon | 1:6c23a7cf204c | 45 | * this list of conditions and the following disclaimer. |
capsavon | 1:6c23a7cf204c | 46 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
capsavon | 1:6c23a7cf204c | 47 | * this list of conditions and the following disclaimer in the documentation |
capsavon | 1:6c23a7cf204c | 48 | * and/or other materials provided with the distribution. |
capsavon | 1:6c23a7cf204c | 49 | * 3. Neither the name of STMicroelectronics nor the names of its contributors |
capsavon | 1:6c23a7cf204c | 50 | * may be used to endorse or promote products derived from this software |
capsavon | 1:6c23a7cf204c | 51 | * without specific prior written permission. |
capsavon | 1:6c23a7cf204c | 52 | * |
capsavon | 1:6c23a7cf204c | 53 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
capsavon | 1:6c23a7cf204c | 54 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
capsavon | 1:6c23a7cf204c | 55 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
capsavon | 1:6c23a7cf204c | 56 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
capsavon | 1:6c23a7cf204c | 57 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
capsavon | 1:6c23a7cf204c | 58 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
capsavon | 1:6c23a7cf204c | 59 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
capsavon | 1:6c23a7cf204c | 60 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
capsavon | 1:6c23a7cf204c | 61 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
capsavon | 1:6c23a7cf204c | 62 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
capsavon | 1:6c23a7cf204c | 63 | * |
capsavon | 1:6c23a7cf204c | 64 | ****************************************************************************** |
capsavon | 1:6c23a7cf204c | 65 | */ |
capsavon | 1:6c23a7cf204c | 66 | |
capsavon | 1:6c23a7cf204c | 67 | /* Includes ------------------------------------------------------------------*/ |
capsavon | 1:6c23a7cf204c | 68 | #include "stm32f746g_discovery_qspi.h" |
capsavon | 1:6c23a7cf204c | 69 | |
capsavon | 1:6c23a7cf204c | 70 | /** @addtogroup BSP |
capsavon | 1:6c23a7cf204c | 71 | * @{ |
capsavon | 1:6c23a7cf204c | 72 | */ |
capsavon | 1:6c23a7cf204c | 73 | |
capsavon | 1:6c23a7cf204c | 74 | /** @addtogroup STM32F746G_DISCOVERY |
capsavon | 1:6c23a7cf204c | 75 | * @{ |
capsavon | 1:6c23a7cf204c | 76 | */ |
capsavon | 1:6c23a7cf204c | 77 | |
capsavon | 1:6c23a7cf204c | 78 | /** @defgroup STM32F746G_DISCOVERY_QSPI STM32F746G-DISCOVERY QSPI |
capsavon | 1:6c23a7cf204c | 79 | * @{ |
capsavon | 1:6c23a7cf204c | 80 | */ |
capsavon | 1:6c23a7cf204c | 81 | |
capsavon | 1:6c23a7cf204c | 82 | /* Private variables ---------------------------------------------------------*/ |
capsavon | 1:6c23a7cf204c | 83 | |
capsavon | 1:6c23a7cf204c | 84 | /** @defgroup STM32F746G_DISCOVERY_QSPI_Private_Variables Private Variables |
capsavon | 1:6c23a7cf204c | 85 | * @{ |
capsavon | 1:6c23a7cf204c | 86 | */ |
capsavon | 1:6c23a7cf204c | 87 | QSPI_HandleTypeDef QSPIHandle; |
capsavon | 1:6c23a7cf204c | 88 | |
capsavon | 1:6c23a7cf204c | 89 | /** |
capsavon | 1:6c23a7cf204c | 90 | * @} |
capsavon | 1:6c23a7cf204c | 91 | */ |
capsavon | 1:6c23a7cf204c | 92 | |
capsavon | 1:6c23a7cf204c | 93 | |
capsavon | 1:6c23a7cf204c | 94 | /* Private functions ---------------------------------------------------------*/ |
capsavon | 1:6c23a7cf204c | 95 | |
capsavon | 1:6c23a7cf204c | 96 | /** @defgroup STM32F746G_DISCOVERY_QSPI_Private_Functions Private Functions |
capsavon | 1:6c23a7cf204c | 97 | * @{ |
capsavon | 1:6c23a7cf204c | 98 | */ |
capsavon | 1:6c23a7cf204c | 99 | static void QSPI_MspInit (void); |
capsavon | 1:6c23a7cf204c | 100 | static void QSPI_MspDeInit (void); |
capsavon | 1:6c23a7cf204c | 101 | static uint8_t QSPI_ResetMemory (QSPI_HandleTypeDef *hqspi); |
capsavon | 1:6c23a7cf204c | 102 | static uint8_t QSPI_DummyCyclesCfg (QSPI_HandleTypeDef *hqspi); |
capsavon | 1:6c23a7cf204c | 103 | static uint8_t QSPI_WriteEnable (QSPI_HandleTypeDef *hqspi); |
capsavon | 1:6c23a7cf204c | 104 | static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout); |
capsavon | 1:6c23a7cf204c | 105 | |
capsavon | 1:6c23a7cf204c | 106 | /** |
capsavon | 1:6c23a7cf204c | 107 | * @} |
capsavon | 1:6c23a7cf204c | 108 | */ |
capsavon | 1:6c23a7cf204c | 109 | |
capsavon | 1:6c23a7cf204c | 110 | /* Exported functions ---------------------------------------------------------*/ |
capsavon | 1:6c23a7cf204c | 111 | |
capsavon | 1:6c23a7cf204c | 112 | /** @addtogroup STM32F746G_DISCOVERY_QSPI_Exported_Functions |
capsavon | 1:6c23a7cf204c | 113 | * @{ |
capsavon | 1:6c23a7cf204c | 114 | */ |
capsavon | 1:6c23a7cf204c | 115 | |
capsavon | 1:6c23a7cf204c | 116 | /** |
capsavon | 1:6c23a7cf204c | 117 | * @brief Initializes the QSPI interface. |
capsavon | 1:6c23a7cf204c | 118 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 119 | */ |
capsavon | 1:6c23a7cf204c | 120 | uint8_t BSP_QSPI_Init(void) |
capsavon | 1:6c23a7cf204c | 121 | { |
capsavon | 1:6c23a7cf204c | 122 | QSPIHandle.Instance = QUADSPI; |
capsavon | 1:6c23a7cf204c | 123 | |
capsavon | 1:6c23a7cf204c | 124 | /* Call the DeInit function to reset the driver */ |
capsavon | 1:6c23a7cf204c | 125 | if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 126 | { |
capsavon | 1:6c23a7cf204c | 127 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 128 | } |
capsavon | 1:6c23a7cf204c | 129 | |
capsavon | 1:6c23a7cf204c | 130 | /* System level initialization */ |
capsavon | 1:6c23a7cf204c | 131 | QSPI_MspInit(); |
capsavon | 1:6c23a7cf204c | 132 | |
capsavon | 1:6c23a7cf204c | 133 | /* QSPI initialization */ |
capsavon | 1:6c23a7cf204c | 134 | QSPIHandle.Init.ClockPrescaler = 0; /* Clock = Fahb = 80 MHz */ |
capsavon | 1:6c23a7cf204c | 135 | QSPIHandle.Init.FifoThreshold = 4; |
capsavon | 1:6c23a7cf204c | 136 | QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; |
capsavon | 1:6c23a7cf204c | 137 | QSPIHandle.Init.FlashSize = POSITION_VAL(N25Q128A_FLASH_SIZE) - 1; |
capsavon | 1:6c23a7cf204c | 138 | QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; |
capsavon | 1:6c23a7cf204c | 139 | QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0; |
capsavon | 1:6c23a7cf204c | 140 | |
capsavon | 1:6c23a7cf204c | 141 | if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 142 | { |
capsavon | 1:6c23a7cf204c | 143 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 144 | } |
capsavon | 1:6c23a7cf204c | 145 | |
capsavon | 1:6c23a7cf204c | 146 | /* QSPI memory reset */ |
capsavon | 1:6c23a7cf204c | 147 | if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 148 | { |
capsavon | 1:6c23a7cf204c | 149 | return QSPI_NOT_SUPPORTED; |
capsavon | 1:6c23a7cf204c | 150 | } |
capsavon | 1:6c23a7cf204c | 151 | |
capsavon | 1:6c23a7cf204c | 152 | /* Configuration of the dummy cucles on QSPI memory side */ |
capsavon | 1:6c23a7cf204c | 153 | if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 154 | { |
capsavon | 1:6c23a7cf204c | 155 | return QSPI_NOT_SUPPORTED; |
capsavon | 1:6c23a7cf204c | 156 | } |
capsavon | 1:6c23a7cf204c | 157 | |
capsavon | 1:6c23a7cf204c | 158 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 159 | } |
capsavon | 1:6c23a7cf204c | 160 | |
capsavon | 1:6c23a7cf204c | 161 | /** |
capsavon | 1:6c23a7cf204c | 162 | * @brief De-Initializes the QSPI interface. |
capsavon | 1:6c23a7cf204c | 163 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 164 | */ |
capsavon | 1:6c23a7cf204c | 165 | uint8_t BSP_QSPI_DeInit(void) |
capsavon | 1:6c23a7cf204c | 166 | { |
capsavon | 1:6c23a7cf204c | 167 | QSPIHandle.Instance = QUADSPI; |
capsavon | 1:6c23a7cf204c | 168 | |
capsavon | 1:6c23a7cf204c | 169 | /* Call the DeInit function to reset the driver */ |
capsavon | 1:6c23a7cf204c | 170 | if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 171 | { |
capsavon | 1:6c23a7cf204c | 172 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 173 | } |
capsavon | 1:6c23a7cf204c | 174 | |
capsavon | 1:6c23a7cf204c | 175 | /* System level De-initialization */ |
capsavon | 1:6c23a7cf204c | 176 | QSPI_MspDeInit(); |
capsavon | 1:6c23a7cf204c | 177 | |
capsavon | 1:6c23a7cf204c | 178 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 179 | } |
capsavon | 1:6c23a7cf204c | 180 | |
capsavon | 1:6c23a7cf204c | 181 | /** |
capsavon | 1:6c23a7cf204c | 182 | * @brief Reads an amount of data from the QSPI memory. |
capsavon | 1:6c23a7cf204c | 183 | * @param pData: Pointer to data to be read |
capsavon | 1:6c23a7cf204c | 184 | * @param ReadAddr: Read start address |
capsavon | 1:6c23a7cf204c | 185 | * @param Size: Size of data to read |
capsavon | 1:6c23a7cf204c | 186 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 187 | */ |
capsavon | 1:6c23a7cf204c | 188 | uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) |
capsavon | 1:6c23a7cf204c | 189 | { |
capsavon | 1:6c23a7cf204c | 190 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 191 | |
capsavon | 1:6c23a7cf204c | 192 | /* Initialize the read command */ |
capsavon | 1:6c23a7cf204c | 193 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 194 | sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD; |
capsavon | 1:6c23a7cf204c | 195 | sCommand.AddressMode = QSPI_ADDRESS_4_LINES; |
capsavon | 1:6c23a7cf204c | 196 | sCommand.AddressSize = QSPI_ADDRESS_24_BITS; |
capsavon | 1:6c23a7cf204c | 197 | sCommand.Address = ReadAddr; |
capsavon | 1:6c23a7cf204c | 198 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 199 | sCommand.DataMode = QSPI_DATA_4_LINES; |
capsavon | 1:6c23a7cf204c | 200 | sCommand.DummyCycles = N25Q128A_DUMMY_CYCLES_READ_QUAD; |
capsavon | 1:6c23a7cf204c | 201 | sCommand.NbData = Size; |
capsavon | 1:6c23a7cf204c | 202 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 203 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 204 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 205 | |
capsavon | 1:6c23a7cf204c | 206 | /* Configure the command */ |
capsavon | 1:6c23a7cf204c | 207 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 208 | { |
capsavon | 1:6c23a7cf204c | 209 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 210 | } |
capsavon | 1:6c23a7cf204c | 211 | |
capsavon | 1:6c23a7cf204c | 212 | /* Reception of the data */ |
capsavon | 1:6c23a7cf204c | 213 | if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 214 | { |
capsavon | 1:6c23a7cf204c | 215 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 216 | } |
capsavon | 1:6c23a7cf204c | 217 | |
capsavon | 1:6c23a7cf204c | 218 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 219 | } |
capsavon | 1:6c23a7cf204c | 220 | |
capsavon | 1:6c23a7cf204c | 221 | /** |
capsavon | 1:6c23a7cf204c | 222 | * @brief Writes an amount of data to the QSPI memory. |
capsavon | 1:6c23a7cf204c | 223 | * @param pData: Pointer to data to be written |
capsavon | 1:6c23a7cf204c | 224 | * @param WriteAddr: Write start address |
capsavon | 1:6c23a7cf204c | 225 | * @param Size: Size of data to write |
capsavon | 1:6c23a7cf204c | 226 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 227 | */ |
capsavon | 1:6c23a7cf204c | 228 | uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) |
capsavon | 1:6c23a7cf204c | 229 | { |
capsavon | 1:6c23a7cf204c | 230 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 231 | uint32_t end_addr, current_size, current_addr; |
capsavon | 1:6c23a7cf204c | 232 | |
capsavon | 1:6c23a7cf204c | 233 | /* Calculation of the size between the write address and the end of the page */ |
capsavon | 1:6c23a7cf204c | 234 | current_addr = 0; |
capsavon | 1:6c23a7cf204c | 235 | |
capsavon | 1:6c23a7cf204c | 236 | while (current_addr <= WriteAddr) |
capsavon | 1:6c23a7cf204c | 237 | { |
capsavon | 1:6c23a7cf204c | 238 | current_addr += N25Q128A_PAGE_SIZE; |
capsavon | 1:6c23a7cf204c | 239 | } |
capsavon | 1:6c23a7cf204c | 240 | current_size = current_addr - WriteAddr; |
capsavon | 1:6c23a7cf204c | 241 | |
capsavon | 1:6c23a7cf204c | 242 | /* Check if the size of the data is less than the remaining place in the page */ |
capsavon | 1:6c23a7cf204c | 243 | if (current_size > Size) |
capsavon | 1:6c23a7cf204c | 244 | { |
capsavon | 1:6c23a7cf204c | 245 | current_size = Size; |
capsavon | 1:6c23a7cf204c | 246 | } |
capsavon | 1:6c23a7cf204c | 247 | |
capsavon | 1:6c23a7cf204c | 248 | /* Initialize the adress variables */ |
capsavon | 1:6c23a7cf204c | 249 | current_addr = WriteAddr; |
capsavon | 1:6c23a7cf204c | 250 | end_addr = WriteAddr + Size; |
capsavon | 1:6c23a7cf204c | 251 | |
capsavon | 1:6c23a7cf204c | 252 | /* Initialize the program command */ |
capsavon | 1:6c23a7cf204c | 253 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 254 | sCommand.Instruction = EXT_QUAD_IN_FAST_PROG_CMD; |
capsavon | 1:6c23a7cf204c | 255 | sCommand.AddressMode = QSPI_ADDRESS_4_LINES; |
capsavon | 1:6c23a7cf204c | 256 | sCommand.AddressSize = QSPI_ADDRESS_24_BITS; |
capsavon | 1:6c23a7cf204c | 257 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 258 | sCommand.DataMode = QSPI_DATA_4_LINES; |
capsavon | 1:6c23a7cf204c | 259 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 260 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 261 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 262 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 263 | |
capsavon | 1:6c23a7cf204c | 264 | /* Perform the write page by page */ |
capsavon | 1:6c23a7cf204c | 265 | do |
capsavon | 1:6c23a7cf204c | 266 | { |
capsavon | 1:6c23a7cf204c | 267 | sCommand.Address = current_addr; |
capsavon | 1:6c23a7cf204c | 268 | sCommand.NbData = current_size; |
capsavon | 1:6c23a7cf204c | 269 | |
capsavon | 1:6c23a7cf204c | 270 | /* Enable write operations */ |
capsavon | 1:6c23a7cf204c | 271 | if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 272 | { |
capsavon | 1:6c23a7cf204c | 273 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 274 | } |
capsavon | 1:6c23a7cf204c | 275 | |
capsavon | 1:6c23a7cf204c | 276 | /* Configure the command */ |
capsavon | 1:6c23a7cf204c | 277 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 278 | { |
capsavon | 1:6c23a7cf204c | 279 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 280 | } |
capsavon | 1:6c23a7cf204c | 281 | |
capsavon | 1:6c23a7cf204c | 282 | /* Transmission of the data */ |
capsavon | 1:6c23a7cf204c | 283 | if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 284 | { |
capsavon | 1:6c23a7cf204c | 285 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 286 | } |
capsavon | 1:6c23a7cf204c | 287 | |
capsavon | 1:6c23a7cf204c | 288 | /* Configure automatic polling mode to wait for end of program */ |
capsavon | 1:6c23a7cf204c | 289 | if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 290 | { |
capsavon | 1:6c23a7cf204c | 291 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 292 | } |
capsavon | 1:6c23a7cf204c | 293 | |
capsavon | 1:6c23a7cf204c | 294 | /* Update the address and size variables for next page programming */ |
capsavon | 1:6c23a7cf204c | 295 | current_addr += current_size; |
capsavon | 1:6c23a7cf204c | 296 | pData += current_size; |
capsavon | 1:6c23a7cf204c | 297 | current_size = ((current_addr + N25Q128A_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : N25Q128A_PAGE_SIZE; |
capsavon | 1:6c23a7cf204c | 298 | } while (current_addr < end_addr); |
capsavon | 1:6c23a7cf204c | 299 | |
capsavon | 1:6c23a7cf204c | 300 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 301 | } |
capsavon | 1:6c23a7cf204c | 302 | |
capsavon | 1:6c23a7cf204c | 303 | /** |
capsavon | 1:6c23a7cf204c | 304 | * @brief Erases the specified block of the QSPI memory. |
capsavon | 1:6c23a7cf204c | 305 | * @param BlockAddress: Block address to erase |
capsavon | 1:6c23a7cf204c | 306 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 307 | */ |
capsavon | 1:6c23a7cf204c | 308 | uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) |
capsavon | 1:6c23a7cf204c | 309 | { |
capsavon | 1:6c23a7cf204c | 310 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 311 | |
capsavon | 1:6c23a7cf204c | 312 | /* Initialize the erase command */ |
capsavon | 1:6c23a7cf204c | 313 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 314 | sCommand.Instruction = SUBSECTOR_ERASE_CMD; |
capsavon | 1:6c23a7cf204c | 315 | sCommand.AddressMode = QSPI_ADDRESS_1_LINE; |
capsavon | 1:6c23a7cf204c | 316 | sCommand.AddressSize = QSPI_ADDRESS_24_BITS; |
capsavon | 1:6c23a7cf204c | 317 | sCommand.Address = BlockAddress; |
capsavon | 1:6c23a7cf204c | 318 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 319 | sCommand.DataMode = QSPI_DATA_NONE; |
capsavon | 1:6c23a7cf204c | 320 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 321 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 322 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 323 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 324 | |
capsavon | 1:6c23a7cf204c | 325 | /* Enable write operations */ |
capsavon | 1:6c23a7cf204c | 326 | if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 327 | { |
capsavon | 1:6c23a7cf204c | 328 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 329 | } |
capsavon | 1:6c23a7cf204c | 330 | |
capsavon | 1:6c23a7cf204c | 331 | /* Send the command */ |
capsavon | 1:6c23a7cf204c | 332 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 333 | { |
capsavon | 1:6c23a7cf204c | 334 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 335 | } |
capsavon | 1:6c23a7cf204c | 336 | |
capsavon | 1:6c23a7cf204c | 337 | /* Configure automatic polling mode to wait for end of erase */ |
capsavon | 1:6c23a7cf204c | 338 | if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 339 | { |
capsavon | 1:6c23a7cf204c | 340 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 341 | } |
capsavon | 1:6c23a7cf204c | 342 | |
capsavon | 1:6c23a7cf204c | 343 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 344 | } |
capsavon | 1:6c23a7cf204c | 345 | |
capsavon | 1:6c23a7cf204c | 346 | /** |
capsavon | 1:6c23a7cf204c | 347 | * @brief Erases the specified sector of the QSPI memory. |
capsavon | 1:6c23a7cf204c | 348 | * @param Sector: Sector address to erase (0 to 255) |
capsavon | 1:6c23a7cf204c | 349 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 350 | * @note This function is non blocking meaning that sector erase |
capsavon | 1:6c23a7cf204c | 351 | * operation is started but not completed when the function |
capsavon | 1:6c23a7cf204c | 352 | * returns. Application has to call BSP_QSPI_GetStatus() |
capsavon | 1:6c23a7cf204c | 353 | * to know when the device is available again (i.e. erase operation |
capsavon | 1:6c23a7cf204c | 354 | * completed). |
capsavon | 1:6c23a7cf204c | 355 | */ |
capsavon | 1:6c23a7cf204c | 356 | uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) |
capsavon | 1:6c23a7cf204c | 357 | { |
capsavon | 1:6c23a7cf204c | 358 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 359 | |
capsavon | 1:6c23a7cf204c | 360 | if (Sector >= (uint32_t)(N25Q128A_FLASH_SIZE/N25Q128A_SECTOR_SIZE)) |
capsavon | 1:6c23a7cf204c | 361 | { |
capsavon | 1:6c23a7cf204c | 362 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 363 | } |
capsavon | 1:6c23a7cf204c | 364 | |
capsavon | 1:6c23a7cf204c | 365 | /* Initialize the erase command */ |
capsavon | 1:6c23a7cf204c | 366 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 367 | sCommand.Instruction = SECTOR_ERASE_CMD; |
capsavon | 1:6c23a7cf204c | 368 | sCommand.AddressMode = QSPI_ADDRESS_1_LINE; |
capsavon | 1:6c23a7cf204c | 369 | sCommand.AddressSize = QSPI_ADDRESS_24_BITS; |
capsavon | 1:6c23a7cf204c | 370 | sCommand.Address = (Sector * N25Q128A_SECTOR_SIZE); |
capsavon | 1:6c23a7cf204c | 371 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 372 | sCommand.DataMode = QSPI_DATA_NONE; |
capsavon | 1:6c23a7cf204c | 373 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 374 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 375 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 376 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 377 | |
capsavon | 1:6c23a7cf204c | 378 | /* Enable write operations */ |
capsavon | 1:6c23a7cf204c | 379 | if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 380 | { |
capsavon | 1:6c23a7cf204c | 381 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 382 | } |
capsavon | 1:6c23a7cf204c | 383 | |
capsavon | 1:6c23a7cf204c | 384 | /* Send the command */ |
capsavon | 1:6c23a7cf204c | 385 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 386 | { |
capsavon | 1:6c23a7cf204c | 387 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 388 | } |
capsavon | 1:6c23a7cf204c | 389 | |
capsavon | 1:6c23a7cf204c | 390 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 391 | } |
capsavon | 1:6c23a7cf204c | 392 | |
capsavon | 1:6c23a7cf204c | 393 | /** |
capsavon | 1:6c23a7cf204c | 394 | * @brief Erases the entire QSPI memory. |
capsavon | 1:6c23a7cf204c | 395 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 396 | */ |
capsavon | 1:6c23a7cf204c | 397 | uint8_t BSP_QSPI_Erase_Chip(void) |
capsavon | 1:6c23a7cf204c | 398 | { |
capsavon | 1:6c23a7cf204c | 399 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 400 | |
capsavon | 1:6c23a7cf204c | 401 | /* Initialize the erase command */ |
capsavon | 1:6c23a7cf204c | 402 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 403 | sCommand.Instruction = BULK_ERASE_CMD; |
capsavon | 1:6c23a7cf204c | 404 | sCommand.AddressMode = QSPI_ADDRESS_NONE; |
capsavon | 1:6c23a7cf204c | 405 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 406 | sCommand.DataMode = QSPI_DATA_NONE; |
capsavon | 1:6c23a7cf204c | 407 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 408 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 409 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 410 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 411 | |
capsavon | 1:6c23a7cf204c | 412 | /* Enable write operations */ |
capsavon | 1:6c23a7cf204c | 413 | if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 414 | { |
capsavon | 1:6c23a7cf204c | 415 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 416 | } |
capsavon | 1:6c23a7cf204c | 417 | |
capsavon | 1:6c23a7cf204c | 418 | /* Send the command */ |
capsavon | 1:6c23a7cf204c | 419 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 420 | { |
capsavon | 1:6c23a7cf204c | 421 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 422 | } |
capsavon | 1:6c23a7cf204c | 423 | |
capsavon | 1:6c23a7cf204c | 424 | /* Configure automatic polling mode to wait for end of erase */ |
capsavon | 1:6c23a7cf204c | 425 | if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_BULK_ERASE_MAX_TIME) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 426 | { |
capsavon | 1:6c23a7cf204c | 427 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 428 | } |
capsavon | 1:6c23a7cf204c | 429 | |
capsavon | 1:6c23a7cf204c | 430 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 431 | } |
capsavon | 1:6c23a7cf204c | 432 | |
capsavon | 1:6c23a7cf204c | 433 | /** |
capsavon | 1:6c23a7cf204c | 434 | * @brief Reads current status of the QSPI memory. |
capsavon | 1:6c23a7cf204c | 435 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 436 | */ |
capsavon | 1:6c23a7cf204c | 437 | uint8_t BSP_QSPI_GetStatus(void) |
capsavon | 1:6c23a7cf204c | 438 | { |
capsavon | 1:6c23a7cf204c | 439 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 440 | uint8_t reg; |
capsavon | 1:6c23a7cf204c | 441 | |
capsavon | 1:6c23a7cf204c | 442 | /* Initialize the read flag status register command */ |
capsavon | 1:6c23a7cf204c | 443 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 444 | sCommand.Instruction = READ_FLAG_STATUS_REG_CMD; |
capsavon | 1:6c23a7cf204c | 445 | sCommand.AddressMode = QSPI_ADDRESS_NONE; |
capsavon | 1:6c23a7cf204c | 446 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 447 | sCommand.DataMode = QSPI_DATA_1_LINE; |
capsavon | 1:6c23a7cf204c | 448 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 449 | sCommand.NbData = 1; |
capsavon | 1:6c23a7cf204c | 450 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 451 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 452 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 453 | |
capsavon | 1:6c23a7cf204c | 454 | /* Configure the command */ |
capsavon | 1:6c23a7cf204c | 455 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 456 | { |
capsavon | 1:6c23a7cf204c | 457 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 458 | } |
capsavon | 1:6c23a7cf204c | 459 | |
capsavon | 1:6c23a7cf204c | 460 | /* Reception of the data */ |
capsavon | 1:6c23a7cf204c | 461 | if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 462 | { |
capsavon | 1:6c23a7cf204c | 463 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 464 | } |
capsavon | 1:6c23a7cf204c | 465 | |
capsavon | 1:6c23a7cf204c | 466 | /* Check the value of the register */ |
capsavon | 1:6c23a7cf204c | 467 | if ((reg & (N25Q128A_FSR_PRERR | N25Q128A_FSR_VPPERR | N25Q128A_FSR_PGERR | N25Q128A_FSR_ERERR)) != 0) |
capsavon | 1:6c23a7cf204c | 468 | { |
capsavon | 1:6c23a7cf204c | 469 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 470 | } |
capsavon | 1:6c23a7cf204c | 471 | else if ((reg & (N25Q128A_FSR_PGSUS | N25Q128A_FSR_ERSUS)) != 0) |
capsavon | 1:6c23a7cf204c | 472 | { |
capsavon | 1:6c23a7cf204c | 473 | return QSPI_SUSPENDED; |
capsavon | 1:6c23a7cf204c | 474 | } |
capsavon | 1:6c23a7cf204c | 475 | else if ((reg & N25Q128A_FSR_READY) != 0) |
capsavon | 1:6c23a7cf204c | 476 | { |
capsavon | 1:6c23a7cf204c | 477 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 478 | } |
capsavon | 1:6c23a7cf204c | 479 | else |
capsavon | 1:6c23a7cf204c | 480 | { |
capsavon | 1:6c23a7cf204c | 481 | return QSPI_BUSY; |
capsavon | 1:6c23a7cf204c | 482 | } |
capsavon | 1:6c23a7cf204c | 483 | } |
capsavon | 1:6c23a7cf204c | 484 | |
capsavon | 1:6c23a7cf204c | 485 | /** |
capsavon | 1:6c23a7cf204c | 486 | * @brief Return the configuration of the QSPI memory. |
capsavon | 1:6c23a7cf204c | 487 | * @param pInfo: pointer on the configuration structure |
capsavon | 1:6c23a7cf204c | 488 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 489 | */ |
capsavon | 1:6c23a7cf204c | 490 | uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo) |
capsavon | 1:6c23a7cf204c | 491 | { |
capsavon | 1:6c23a7cf204c | 492 | /* Configure the structure with the memory configuration */ |
capsavon | 1:6c23a7cf204c | 493 | pInfo->FlashSize = N25Q128A_FLASH_SIZE; |
capsavon | 1:6c23a7cf204c | 494 | pInfo->EraseSectorSize = N25Q128A_SUBSECTOR_SIZE; |
capsavon | 1:6c23a7cf204c | 495 | pInfo->EraseSectorsNumber = (N25Q128A_FLASH_SIZE/N25Q128A_SUBSECTOR_SIZE); |
capsavon | 1:6c23a7cf204c | 496 | pInfo->ProgPageSize = N25Q128A_PAGE_SIZE; |
capsavon | 1:6c23a7cf204c | 497 | pInfo->ProgPagesNumber = (N25Q128A_FLASH_SIZE/N25Q128A_PAGE_SIZE); |
capsavon | 1:6c23a7cf204c | 498 | |
capsavon | 1:6c23a7cf204c | 499 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 500 | } |
capsavon | 1:6c23a7cf204c | 501 | |
capsavon | 1:6c23a7cf204c | 502 | /** |
capsavon | 1:6c23a7cf204c | 503 | * @brief Configure the QSPI in memory-mapped mode |
capsavon | 1:6c23a7cf204c | 504 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 505 | */ |
capsavon | 1:6c23a7cf204c | 506 | uint8_t BSP_QSPI_EnableMemoryMappedMode(void) |
capsavon | 1:6c23a7cf204c | 507 | { |
capsavon | 1:6c23a7cf204c | 508 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 509 | QSPI_MemoryMappedTypeDef sMemMappedCfg; |
capsavon | 1:6c23a7cf204c | 510 | |
capsavon | 1:6c23a7cf204c | 511 | /* Configure the command for the read instruction */ |
capsavon | 1:6c23a7cf204c | 512 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 513 | sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD; |
capsavon | 1:6c23a7cf204c | 514 | sCommand.AddressMode = QSPI_ADDRESS_4_LINES; |
capsavon | 1:6c23a7cf204c | 515 | sCommand.AddressSize = QSPI_ADDRESS_24_BITS; |
capsavon | 1:6c23a7cf204c | 516 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 517 | sCommand.DataMode = QSPI_DATA_4_LINES; |
capsavon | 1:6c23a7cf204c | 518 | sCommand.DummyCycles = N25Q128A_DUMMY_CYCLES_READ_QUAD; |
capsavon | 1:6c23a7cf204c | 519 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 520 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 521 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 522 | |
capsavon | 1:6c23a7cf204c | 523 | /* Configure the memory mapped mode */ |
capsavon | 1:6c23a7cf204c | 524 | sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_ENABLE; |
capsavon | 1:6c23a7cf204c | 525 | sMemMappedCfg.TimeOutPeriod = 4; /* 50 ns (4 periods of a 80 MHz clock) */ |
capsavon | 1:6c23a7cf204c | 526 | |
capsavon | 1:6c23a7cf204c | 527 | if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 528 | { |
capsavon | 1:6c23a7cf204c | 529 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 530 | } |
capsavon | 1:6c23a7cf204c | 531 | |
capsavon | 1:6c23a7cf204c | 532 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 533 | } |
capsavon | 1:6c23a7cf204c | 534 | |
capsavon | 1:6c23a7cf204c | 535 | /** |
capsavon | 1:6c23a7cf204c | 536 | * @brief This function suspends an ongoing erase command. |
capsavon | 1:6c23a7cf204c | 537 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 538 | */ |
capsavon | 1:6c23a7cf204c | 539 | uint8_t BSP_QSPI_SuspendErase(void) |
capsavon | 1:6c23a7cf204c | 540 | { |
capsavon | 1:6c23a7cf204c | 541 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 542 | |
capsavon | 1:6c23a7cf204c | 543 | /* Check whether the device is busy (erase operation is |
capsavon | 1:6c23a7cf204c | 544 | in progress). |
capsavon | 1:6c23a7cf204c | 545 | */ |
capsavon | 1:6c23a7cf204c | 546 | if (BSP_QSPI_GetStatus() == QSPI_BUSY) |
capsavon | 1:6c23a7cf204c | 547 | { |
capsavon | 1:6c23a7cf204c | 548 | /* Initialize the erase command */ |
capsavon | 1:6c23a7cf204c | 549 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 550 | sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; |
capsavon | 1:6c23a7cf204c | 551 | sCommand.AddressMode = QSPI_ADDRESS_NONE; |
capsavon | 1:6c23a7cf204c | 552 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 553 | sCommand.DataMode = QSPI_DATA_NONE; |
capsavon | 1:6c23a7cf204c | 554 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 555 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 556 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 557 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 558 | |
capsavon | 1:6c23a7cf204c | 559 | /* Enable write operations */ |
capsavon | 1:6c23a7cf204c | 560 | if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 561 | { |
capsavon | 1:6c23a7cf204c | 562 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 563 | } |
capsavon | 1:6c23a7cf204c | 564 | |
capsavon | 1:6c23a7cf204c | 565 | /* Send the command */ |
capsavon | 1:6c23a7cf204c | 566 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 567 | { |
capsavon | 1:6c23a7cf204c | 568 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 569 | } |
capsavon | 1:6c23a7cf204c | 570 | |
capsavon | 1:6c23a7cf204c | 571 | if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) |
capsavon | 1:6c23a7cf204c | 572 | { |
capsavon | 1:6c23a7cf204c | 573 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 574 | } |
capsavon | 1:6c23a7cf204c | 575 | |
capsavon | 1:6c23a7cf204c | 576 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 577 | } |
capsavon | 1:6c23a7cf204c | 578 | |
capsavon | 1:6c23a7cf204c | 579 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 580 | } |
capsavon | 1:6c23a7cf204c | 581 | |
capsavon | 1:6c23a7cf204c | 582 | /** |
capsavon | 1:6c23a7cf204c | 583 | * @brief This function resumes a paused erase command. |
capsavon | 1:6c23a7cf204c | 584 | * @retval QSPI memory status |
capsavon | 1:6c23a7cf204c | 585 | */ |
capsavon | 1:6c23a7cf204c | 586 | uint8_t BSP_QSPI_ResumeErase(void) |
capsavon | 1:6c23a7cf204c | 587 | { |
capsavon | 1:6c23a7cf204c | 588 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 589 | |
capsavon | 1:6c23a7cf204c | 590 | /* Check whether the device is in suspended state */ |
capsavon | 1:6c23a7cf204c | 591 | if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) |
capsavon | 1:6c23a7cf204c | 592 | { |
capsavon | 1:6c23a7cf204c | 593 | /* Initialize the erase command */ |
capsavon | 1:6c23a7cf204c | 594 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 595 | sCommand.Instruction = PROG_ERASE_RESUME_CMD; |
capsavon | 1:6c23a7cf204c | 596 | sCommand.AddressMode = QSPI_ADDRESS_NONE; |
capsavon | 1:6c23a7cf204c | 597 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 598 | sCommand.DataMode = QSPI_DATA_NONE; |
capsavon | 1:6c23a7cf204c | 599 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 600 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 601 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 602 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 603 | |
capsavon | 1:6c23a7cf204c | 604 | /* Enable write operations */ |
capsavon | 1:6c23a7cf204c | 605 | if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 606 | { |
capsavon | 1:6c23a7cf204c | 607 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 608 | } |
capsavon | 1:6c23a7cf204c | 609 | |
capsavon | 1:6c23a7cf204c | 610 | /* Send the command */ |
capsavon | 1:6c23a7cf204c | 611 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 612 | { |
capsavon | 1:6c23a7cf204c | 613 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 614 | } |
capsavon | 1:6c23a7cf204c | 615 | |
capsavon | 1:6c23a7cf204c | 616 | /* |
capsavon | 1:6c23a7cf204c | 617 | When this command is executed, the status register write in progress bit is set to 1, and |
capsavon | 1:6c23a7cf204c | 618 | the flag status register program erase controller bit is set to 0. This command is ignored |
capsavon | 1:6c23a7cf204c | 619 | if the device is not in a suspended state. |
capsavon | 1:6c23a7cf204c | 620 | */ |
capsavon | 1:6c23a7cf204c | 621 | |
capsavon | 1:6c23a7cf204c | 622 | if (BSP_QSPI_GetStatus() == QSPI_BUSY) |
capsavon | 1:6c23a7cf204c | 623 | { |
capsavon | 1:6c23a7cf204c | 624 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 625 | } |
capsavon | 1:6c23a7cf204c | 626 | |
capsavon | 1:6c23a7cf204c | 627 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 628 | } |
capsavon | 1:6c23a7cf204c | 629 | |
capsavon | 1:6c23a7cf204c | 630 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 631 | } |
capsavon | 1:6c23a7cf204c | 632 | |
capsavon | 1:6c23a7cf204c | 633 | /** |
capsavon | 1:6c23a7cf204c | 634 | * @} |
capsavon | 1:6c23a7cf204c | 635 | */ |
capsavon | 1:6c23a7cf204c | 636 | |
capsavon | 1:6c23a7cf204c | 637 | /** @addtogroup STM32F746G_DISCOVERY_QSPI_Private_Functions |
capsavon | 1:6c23a7cf204c | 638 | * @{ |
capsavon | 1:6c23a7cf204c | 639 | */ |
capsavon | 1:6c23a7cf204c | 640 | |
capsavon | 1:6c23a7cf204c | 641 | /** |
capsavon | 1:6c23a7cf204c | 642 | * @brief Initializes the QSPI MSP. |
capsavon | 1:6c23a7cf204c | 643 | * @retval None |
capsavon | 1:6c23a7cf204c | 644 | */ |
capsavon | 1:6c23a7cf204c | 645 | static void QSPI_MspInit(void) |
capsavon | 1:6c23a7cf204c | 646 | { |
capsavon | 1:6c23a7cf204c | 647 | GPIO_InitTypeDef GPIO_InitStruct; |
capsavon | 1:6c23a7cf204c | 648 | |
capsavon | 1:6c23a7cf204c | 649 | /* Enable the QuadSPI memory interface clock */ |
capsavon | 1:6c23a7cf204c | 650 | __HAL_RCC_QSPI_CLK_ENABLE(); |
capsavon | 1:6c23a7cf204c | 651 | |
capsavon | 1:6c23a7cf204c | 652 | /* Reset the QuadSPI memory interface */ |
capsavon | 1:6c23a7cf204c | 653 | __HAL_RCC_QSPI_FORCE_RESET(); |
capsavon | 1:6c23a7cf204c | 654 | __HAL_RCC_QSPI_RELEASE_RESET(); |
capsavon | 1:6c23a7cf204c | 655 | |
capsavon | 1:6c23a7cf204c | 656 | /* Enable GPIO clocks */ |
capsavon | 1:6c23a7cf204c | 657 | __HAL_RCC_GPIOE_CLK_ENABLE(); |
capsavon | 1:6c23a7cf204c | 658 | |
capsavon | 1:6c23a7cf204c | 659 | /* QSPI CS GPIO pin configuration */ |
capsavon | 1:6c23a7cf204c | 660 | /* DISCO-STM32L476VG : CS = PE11 */ |
capsavon | 1:6c23a7cf204c | 661 | /* DISCO-STM32F746NG : CS = PB6 */ |
capsavon | 1:6c23a7cf204c | 662 | // GPIO_InitStruct.Pin = GPIO_PIN_11; // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 663 | GPIO_InitStruct.Pin = GPIO_PIN_6; //DISCO-STM32F746NG |
capsavon | 1:6c23a7cf204c | 664 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; |
capsavon | 1:6c23a7cf204c | 665 | GPIO_InitStruct.Pull = GPIO_PULLUP; |
capsavon | 1:6c23a7cf204c | 666 | GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; |
capsavon | 1:6c23a7cf204c | 667 | GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; // TBC |
capsavon | 1:6c23a7cf204c | 668 | // HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 669 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // DISCO-STM32F746NG |
capsavon | 1:6c23a7cf204c | 670 | |
capsavon | 1:6c23a7cf204c | 671 | /* QSPI CLK, D0, D1, D2 and D3 GPIO pins configuration */ |
capsavon | 1:6c23a7cf204c | 672 | /* DISCO-STM32L476VG : CLK = PE10 | D0 = PE12 | D1 = PE13 | D2 = PE14 | D3 = PE15 */ |
capsavon | 1:6c23a7cf204c | 673 | /* DISCO-STM32F746NG : CLK = PB2 | D0 = PD11 | D1 = PD12 | D2 = PE2 | D3 = PD13 */ |
capsavon | 1:6c23a7cf204c | 674 | // GPIO_InitStruct.Pin = (GPIO_PIN_10 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 675 | |
capsavon | 1:6c23a7cf204c | 676 | GPIO_InitStruct.Pin = (GPIO_PIN_2); // CLK |
capsavon | 1:6c23a7cf204c | 677 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
capsavon | 1:6c23a7cf204c | 678 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); |
capsavon | 1:6c23a7cf204c | 679 | |
capsavon | 1:6c23a7cf204c | 680 | GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13); // D0, D1, D3 |
capsavon | 1:6c23a7cf204c | 681 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
capsavon | 1:6c23a7cf204c | 682 | HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); |
capsavon | 1:6c23a7cf204c | 683 | |
capsavon | 1:6c23a7cf204c | 684 | GPIO_InitStruct.Pin = (GPIO_PIN_2); // D2 |
capsavon | 1:6c23a7cf204c | 685 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
capsavon | 1:6c23a7cf204c | 686 | HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); |
capsavon | 1:6c23a7cf204c | 687 | } |
capsavon | 1:6c23a7cf204c | 688 | |
capsavon | 1:6c23a7cf204c | 689 | /** |
capsavon | 1:6c23a7cf204c | 690 | * @brief De-Initializes the QSPI MSP. |
capsavon | 1:6c23a7cf204c | 691 | * @retval None |
capsavon | 1:6c23a7cf204c | 692 | */ |
capsavon | 1:6c23a7cf204c | 693 | static void QSPI_MspDeInit(void) |
capsavon | 1:6c23a7cf204c | 694 | { |
capsavon | 1:6c23a7cf204c | 695 | GPIO_InitTypeDef GPIO_InitStruct; |
capsavon | 1:6c23a7cf204c | 696 | |
capsavon | 1:6c23a7cf204c | 697 | /* QSPI CLK, CS, PE10 - PE15 GPIO pins de-configuration */ |
capsavon | 1:6c23a7cf204c | 698 | |
capsavon | 1:6c23a7cf204c | 699 | __HAL_RCC_GPIOE_CLK_ENABLE(); |
capsavon | 1:6c23a7cf204c | 700 | // HAL_GPIO_DeInit(GPIOE, (GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)); // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 701 | HAL_GPIO_DeInit(GPIOD, (GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13)); // D0, D1, D3 |
capsavon | 1:6c23a7cf204c | 702 | HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2); // D2 |
capsavon | 1:6c23a7cf204c | 703 | |
capsavon | 1:6c23a7cf204c | 704 | /* Chip select pin de-configuration */ |
capsavon | 1:6c23a7cf204c | 705 | /* Set GPIOE pin 11 in pull up mode (optimum default setting) */ |
capsavon | 1:6c23a7cf204c | 706 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; |
capsavon | 1:6c23a7cf204c | 707 | // GPIO_InitStruct.Pin = GPIO_PIN_11; // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 708 | GPIO_InitStruct.Pin = GPIO_PIN_6; |
capsavon | 1:6c23a7cf204c | 709 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
capsavon | 1:6c23a7cf204c | 710 | GPIO_InitStruct.Speed = GPIO_SPEED_LOW; |
capsavon | 1:6c23a7cf204c | 711 | // HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 712 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); |
capsavon | 1:6c23a7cf204c | 713 | |
capsavon | 1:6c23a7cf204c | 714 | /* CLK pin de-configuration */ |
capsavon | 1:6c23a7cf204c | 715 | /* Set GPIOE pin 10 in no pull, low state (optimum default setting) */ |
capsavon | 1:6c23a7cf204c | 716 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP ; |
capsavon | 1:6c23a7cf204c | 717 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
capsavon | 1:6c23a7cf204c | 718 | // GPIO_InitStruct.Pin = (GPIO_PIN_10); // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 719 | GPIO_InitStruct.Pin = (GPIO_PIN_2); |
capsavon | 1:6c23a7cf204c | 720 | // HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 721 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); |
capsavon | 1:6c23a7cf204c | 722 | // HAL_GPIO_WritePin(GPIOE, GPIO_PIN_10, GPIO_PIN_RESET); // DISCO-STM32L476VG |
capsavon | 1:6c23a7cf204c | 723 | HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET); |
capsavon | 1:6c23a7cf204c | 724 | |
capsavon | 1:6c23a7cf204c | 725 | /* Reset the QuadSPI memory interface */ |
capsavon | 1:6c23a7cf204c | 726 | __HAL_RCC_QSPI_FORCE_RESET(); |
capsavon | 1:6c23a7cf204c | 727 | __HAL_RCC_QSPI_RELEASE_RESET(); |
capsavon | 1:6c23a7cf204c | 728 | |
capsavon | 1:6c23a7cf204c | 729 | /* Disable the QuadSPI memory interface clock */ |
capsavon | 1:6c23a7cf204c | 730 | __HAL_RCC_QSPI_CLK_DISABLE(); |
capsavon | 1:6c23a7cf204c | 731 | } |
capsavon | 1:6c23a7cf204c | 732 | |
capsavon | 1:6c23a7cf204c | 733 | /** |
capsavon | 1:6c23a7cf204c | 734 | * @brief This function reset the QSPI memory. |
capsavon | 1:6c23a7cf204c | 735 | * @param hqspi: QSPI handle |
capsavon | 1:6c23a7cf204c | 736 | * @retval None |
capsavon | 1:6c23a7cf204c | 737 | */ |
capsavon | 1:6c23a7cf204c | 738 | static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi) |
capsavon | 1:6c23a7cf204c | 739 | { |
capsavon | 1:6c23a7cf204c | 740 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 741 | |
capsavon | 1:6c23a7cf204c | 742 | /* Initialize the reset enable command */ |
capsavon | 1:6c23a7cf204c | 743 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 744 | sCommand.Instruction = RESET_ENABLE_CMD; |
capsavon | 1:6c23a7cf204c | 745 | sCommand.AddressMode = QSPI_ADDRESS_NONE; |
capsavon | 1:6c23a7cf204c | 746 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 747 | sCommand.DataMode = QSPI_DATA_NONE; |
capsavon | 1:6c23a7cf204c | 748 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 749 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 750 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 751 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 752 | |
capsavon | 1:6c23a7cf204c | 753 | /* Send the command */ |
capsavon | 1:6c23a7cf204c | 754 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 755 | { |
capsavon | 1:6c23a7cf204c | 756 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 757 | } |
capsavon | 1:6c23a7cf204c | 758 | |
capsavon | 1:6c23a7cf204c | 759 | /* Send the reset memory command */ |
capsavon | 1:6c23a7cf204c | 760 | sCommand.Instruction = RESET_MEMORY_CMD; |
capsavon | 1:6c23a7cf204c | 761 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 762 | { |
capsavon | 1:6c23a7cf204c | 763 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 764 | } |
capsavon | 1:6c23a7cf204c | 765 | |
capsavon | 1:6c23a7cf204c | 766 | /* Configure automatic polling mode to wait the memory is ready */ |
capsavon | 1:6c23a7cf204c | 767 | if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 768 | { |
capsavon | 1:6c23a7cf204c | 769 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 770 | } |
capsavon | 1:6c23a7cf204c | 771 | |
capsavon | 1:6c23a7cf204c | 772 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 773 | } |
capsavon | 1:6c23a7cf204c | 774 | |
capsavon | 1:6c23a7cf204c | 775 | /** |
capsavon | 1:6c23a7cf204c | 776 | * @brief This function configure the dummy cycles on memory side. |
capsavon | 1:6c23a7cf204c | 777 | * @param hqspi: QSPI handle |
capsavon | 1:6c23a7cf204c | 778 | * @retval None |
capsavon | 1:6c23a7cf204c | 779 | */ |
capsavon | 1:6c23a7cf204c | 780 | static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi) |
capsavon | 1:6c23a7cf204c | 781 | { |
capsavon | 1:6c23a7cf204c | 782 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 783 | uint8_t reg; |
capsavon | 1:6c23a7cf204c | 784 | |
capsavon | 1:6c23a7cf204c | 785 | /* Initialize the read volatile configuration register command */ |
capsavon | 1:6c23a7cf204c | 786 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 787 | sCommand.Instruction = READ_VOL_CFG_REG_CMD; |
capsavon | 1:6c23a7cf204c | 788 | sCommand.AddressMode = QSPI_ADDRESS_NONE; |
capsavon | 1:6c23a7cf204c | 789 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 790 | sCommand.DataMode = QSPI_DATA_1_LINE; |
capsavon | 1:6c23a7cf204c | 791 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 792 | sCommand.NbData = 1; |
capsavon | 1:6c23a7cf204c | 793 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 794 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 795 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 796 | |
capsavon | 1:6c23a7cf204c | 797 | /* Configure the command */ |
capsavon | 1:6c23a7cf204c | 798 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 799 | { |
capsavon | 1:6c23a7cf204c | 800 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 801 | } |
capsavon | 1:6c23a7cf204c | 802 | |
capsavon | 1:6c23a7cf204c | 803 | /* Reception of the data */ |
capsavon | 1:6c23a7cf204c | 804 | if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 805 | { |
capsavon | 1:6c23a7cf204c | 806 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 807 | } |
capsavon | 1:6c23a7cf204c | 808 | |
capsavon | 1:6c23a7cf204c | 809 | /* Enable write operations */ |
capsavon | 1:6c23a7cf204c | 810 | if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) |
capsavon | 1:6c23a7cf204c | 811 | { |
capsavon | 1:6c23a7cf204c | 812 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 813 | } |
capsavon | 1:6c23a7cf204c | 814 | |
capsavon | 1:6c23a7cf204c | 815 | /* Update volatile configuration register (with new dummy cycles) */ |
capsavon | 1:6c23a7cf204c | 816 | sCommand.Instruction = WRITE_VOL_CFG_REG_CMD; |
capsavon | 1:6c23a7cf204c | 817 | MODIFY_REG(reg, N25Q128A_VCR_NB_DUMMY, (N25Q128A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q128A_VCR_NB_DUMMY))); |
capsavon | 1:6c23a7cf204c | 818 | |
capsavon | 1:6c23a7cf204c | 819 | /* Configure the write volatile configuration register command */ |
capsavon | 1:6c23a7cf204c | 820 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 821 | { |
capsavon | 1:6c23a7cf204c | 822 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 823 | } |
capsavon | 1:6c23a7cf204c | 824 | |
capsavon | 1:6c23a7cf204c | 825 | /* Transmission of the data */ |
capsavon | 1:6c23a7cf204c | 826 | if (HAL_QSPI_Transmit(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 827 | { |
capsavon | 1:6c23a7cf204c | 828 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 829 | } |
capsavon | 1:6c23a7cf204c | 830 | |
capsavon | 1:6c23a7cf204c | 831 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 832 | } |
capsavon | 1:6c23a7cf204c | 833 | |
capsavon | 1:6c23a7cf204c | 834 | /** |
capsavon | 1:6c23a7cf204c | 835 | * @brief This function send a Write Enable and wait it is effective. |
capsavon | 1:6c23a7cf204c | 836 | * @param hqspi: QSPI handle |
capsavon | 1:6c23a7cf204c | 837 | * @retval None |
capsavon | 1:6c23a7cf204c | 838 | */ |
capsavon | 1:6c23a7cf204c | 839 | static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi) |
capsavon | 1:6c23a7cf204c | 840 | { |
capsavon | 1:6c23a7cf204c | 841 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 842 | QSPI_AutoPollingTypeDef sConfig; |
capsavon | 1:6c23a7cf204c | 843 | |
capsavon | 1:6c23a7cf204c | 844 | /* Enable write operations */ |
capsavon | 1:6c23a7cf204c | 845 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 846 | sCommand.Instruction = WRITE_ENABLE_CMD; |
capsavon | 1:6c23a7cf204c | 847 | sCommand.AddressMode = QSPI_ADDRESS_NONE; |
capsavon | 1:6c23a7cf204c | 848 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 849 | sCommand.DataMode = QSPI_DATA_NONE; |
capsavon | 1:6c23a7cf204c | 850 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 851 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 852 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 853 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 854 | |
capsavon | 1:6c23a7cf204c | 855 | if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 856 | { |
capsavon | 1:6c23a7cf204c | 857 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 858 | } |
capsavon | 1:6c23a7cf204c | 859 | |
capsavon | 1:6c23a7cf204c | 860 | /* Configure automatic polling mode to wait for write enabling */ |
capsavon | 1:6c23a7cf204c | 861 | sConfig.Match = N25Q128A_SR_WREN; |
capsavon | 1:6c23a7cf204c | 862 | sConfig.Mask = N25Q128A_SR_WREN; |
capsavon | 1:6c23a7cf204c | 863 | sConfig.MatchMode = QSPI_MATCH_MODE_AND; |
capsavon | 1:6c23a7cf204c | 864 | sConfig.StatusBytesSize = 1; |
capsavon | 1:6c23a7cf204c | 865 | sConfig.Interval = 0x10; |
capsavon | 1:6c23a7cf204c | 866 | sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; |
capsavon | 1:6c23a7cf204c | 867 | |
capsavon | 1:6c23a7cf204c | 868 | sCommand.Instruction = READ_STATUS_REG_CMD; |
capsavon | 1:6c23a7cf204c | 869 | sCommand.DataMode = QSPI_DATA_1_LINE; |
capsavon | 1:6c23a7cf204c | 870 | |
capsavon | 1:6c23a7cf204c | 871 | if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 872 | { |
capsavon | 1:6c23a7cf204c | 873 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 874 | } |
capsavon | 1:6c23a7cf204c | 875 | |
capsavon | 1:6c23a7cf204c | 876 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 877 | } |
capsavon | 1:6c23a7cf204c | 878 | |
capsavon | 1:6c23a7cf204c | 879 | /** |
capsavon | 1:6c23a7cf204c | 880 | * @brief This function read the SR of the memory and wait the EOP. |
capsavon | 1:6c23a7cf204c | 881 | * @param hqspi: QSPI handle |
capsavon | 1:6c23a7cf204c | 882 | * @param Timeout: Timeout for auto-polling |
capsavon | 1:6c23a7cf204c | 883 | * @retval None |
capsavon | 1:6c23a7cf204c | 884 | */ |
capsavon | 1:6c23a7cf204c | 885 | static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout) |
capsavon | 1:6c23a7cf204c | 886 | { |
capsavon | 1:6c23a7cf204c | 887 | QSPI_CommandTypeDef sCommand; |
capsavon | 1:6c23a7cf204c | 888 | QSPI_AutoPollingTypeDef sConfig; |
capsavon | 1:6c23a7cf204c | 889 | |
capsavon | 1:6c23a7cf204c | 890 | /* Configure automatic polling mode to wait for memory ready */ |
capsavon | 1:6c23a7cf204c | 891 | sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; |
capsavon | 1:6c23a7cf204c | 892 | sCommand.Instruction = READ_STATUS_REG_CMD; |
capsavon | 1:6c23a7cf204c | 893 | sCommand.AddressMode = QSPI_ADDRESS_NONE; |
capsavon | 1:6c23a7cf204c | 894 | sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; |
capsavon | 1:6c23a7cf204c | 895 | sCommand.DataMode = QSPI_DATA_1_LINE; |
capsavon | 1:6c23a7cf204c | 896 | sCommand.DummyCycles = 0; |
capsavon | 1:6c23a7cf204c | 897 | sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; |
capsavon | 1:6c23a7cf204c | 898 | sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; |
capsavon | 1:6c23a7cf204c | 899 | sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; |
capsavon | 1:6c23a7cf204c | 900 | |
capsavon | 1:6c23a7cf204c | 901 | sConfig.Match = 0; |
capsavon | 1:6c23a7cf204c | 902 | sConfig.Mask = N25Q128A_SR_WIP; |
capsavon | 1:6c23a7cf204c | 903 | sConfig.MatchMode = QSPI_MATCH_MODE_AND; |
capsavon | 1:6c23a7cf204c | 904 | sConfig.StatusBytesSize = 1; |
capsavon | 1:6c23a7cf204c | 905 | sConfig.Interval = 0x10; |
capsavon | 1:6c23a7cf204c | 906 | sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; |
capsavon | 1:6c23a7cf204c | 907 | |
capsavon | 1:6c23a7cf204c | 908 | if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, Timeout) != HAL_OK) |
capsavon | 1:6c23a7cf204c | 909 | { |
capsavon | 1:6c23a7cf204c | 910 | return QSPI_ERROR; |
capsavon | 1:6c23a7cf204c | 911 | } |
capsavon | 1:6c23a7cf204c | 912 | |
capsavon | 1:6c23a7cf204c | 913 | return QSPI_OK; |
capsavon | 1:6c23a7cf204c | 914 | } |
capsavon | 1:6c23a7cf204c | 915 | |
capsavon | 1:6c23a7cf204c | 916 | /** |
capsavon | 1:6c23a7cf204c | 917 | * @} |
capsavon | 1:6c23a7cf204c | 918 | */ |
capsavon | 1:6c23a7cf204c | 919 | |
capsavon | 1:6c23a7cf204c | 920 | /** |
capsavon | 1:6c23a7cf204c | 921 | * @} |
capsavon | 1:6c23a7cf204c | 922 | */ |
capsavon | 1:6c23a7cf204c | 923 | |
capsavon | 1:6c23a7cf204c | 924 | /** |
capsavon | 1:6c23a7cf204c | 925 | * @} |
capsavon | 1:6c23a7cf204c | 926 | */ |
capsavon | 1:6c23a7cf204c | 927 | |
capsavon | 1:6c23a7cf204c | 928 | /** |
capsavon | 1:6c23a7cf204c | 929 | * @} |
capsavon | 1:6c23a7cf204c | 930 | */ |
capsavon | 1:6c23a7cf204c | 931 | |
capsavon | 1:6c23a7cf204c | 932 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
capsavon | 1:6c23a7cf204c | 933 |