TUKS MCU Introductory course / TUKS-COURSE-2-LED
Committer:
elmot
Date:
Fri Feb 24 21:13:56 2017 +0000
Revision:
1:d0dfbce63a89
Ready-to-copy

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elmot 1:d0dfbce63a89 1 /**
elmot 1:d0dfbce63a89 2 ******************************************************************************
elmot 1:d0dfbce63a89 3 * @file stm32l4xx_hal_nand.c
elmot 1:d0dfbce63a89 4 * @author MCD Application Team
elmot 1:d0dfbce63a89 5 * @version V1.5.1
elmot 1:d0dfbce63a89 6 * @date 31-May-2016
elmot 1:d0dfbce63a89 7 * @brief NAND HAL module driver.
elmot 1:d0dfbce63a89 8 * This file provides a generic firmware to drive NAND memories mounted
elmot 1:d0dfbce63a89 9 * as external device.
elmot 1:d0dfbce63a89 10 *
elmot 1:d0dfbce63a89 11 @verbatim
elmot 1:d0dfbce63a89 12 ==============================================================================
elmot 1:d0dfbce63a89 13 ##### How to use this driver #####
elmot 1:d0dfbce63a89 14 ==============================================================================
elmot 1:d0dfbce63a89 15 [..]
elmot 1:d0dfbce63a89 16 This driver is a generic layered driver which contains a set of APIs used to
elmot 1:d0dfbce63a89 17 control NAND flash memories. It uses the FMC layer functions to interface
elmot 1:d0dfbce63a89 18 with NAND devices. This driver is used as follows:
elmot 1:d0dfbce63a89 19
elmot 1:d0dfbce63a89 20 (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
elmot 1:d0dfbce63a89 21 with control and timing parameters for both common and attribute spaces.
elmot 1:d0dfbce63a89 22
elmot 1:d0dfbce63a89 23 (+) Read NAND flash memory maker and device IDs using the function
elmot 1:d0dfbce63a89 24 HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
elmot 1:d0dfbce63a89 25 structure declared by the function caller.
elmot 1:d0dfbce63a89 26
elmot 1:d0dfbce63a89 27 (+) Access NAND flash memory by read/write operations using the functions
elmot 1:d0dfbce63a89 28 HAL_NAND_Read_Page()/HAL_NAND_Read_SpareArea(), HAL_NAND_Write_Page()/HAL_NAND_Write_SpareArea()
elmot 1:d0dfbce63a89 29 to read/write page(s)/spare area(s). These functions use specific device
elmot 1:d0dfbce63a89 30 information (Block, page size..) predefined by the user in the HAL_NAND_Info_TypeDef
elmot 1:d0dfbce63a89 31 structure. The read/write address information is contained by the Nand_Address_Typedef
elmot 1:d0dfbce63a89 32 structure passed as parameter.
elmot 1:d0dfbce63a89 33
elmot 1:d0dfbce63a89 34 (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
elmot 1:d0dfbce63a89 35
elmot 1:d0dfbce63a89 36 (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
elmot 1:d0dfbce63a89 37 The erase block address information is contained in the Nand_Address_Typedef
elmot 1:d0dfbce63a89 38 structure passed as parameter.
elmot 1:d0dfbce63a89 39
elmot 1:d0dfbce63a89 40 (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
elmot 1:d0dfbce63a89 41
elmot 1:d0dfbce63a89 42 (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
elmot 1:d0dfbce63a89 43 HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
elmot 1:d0dfbce63a89 44 feature or the function HAL_NAND_GetECC() to get the ECC correction code.
elmot 1:d0dfbce63a89 45
elmot 1:d0dfbce63a89 46 (+) You can monitor the NAND device HAL state by calling the function
elmot 1:d0dfbce63a89 47 HAL_NAND_GetState()
elmot 1:d0dfbce63a89 48
elmot 1:d0dfbce63a89 49 [..]
elmot 1:d0dfbce63a89 50 (@) This driver is a set of generic APIs which handle standard NAND flash operations.
elmot 1:d0dfbce63a89 51 If a NAND flash device contains different operations and/or implementations,
elmot 1:d0dfbce63a89 52 it should be implemented separately.
elmot 1:d0dfbce63a89 53
elmot 1:d0dfbce63a89 54 @endverbatim
elmot 1:d0dfbce63a89 55 ******************************************************************************
elmot 1:d0dfbce63a89 56 * @attention
elmot 1:d0dfbce63a89 57 *
elmot 1:d0dfbce63a89 58 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
elmot 1:d0dfbce63a89 59 *
elmot 1:d0dfbce63a89 60 * Redistribution and use in source and binary forms, with or without modification,
elmot 1:d0dfbce63a89 61 * are permitted provided that the following conditions are met:
elmot 1:d0dfbce63a89 62 * 1. Redistributions of source code must retain the above copyright notice,
elmot 1:d0dfbce63a89 63 * this list of conditions and the following disclaimer.
elmot 1:d0dfbce63a89 64 * 2. Redistributions in binary form must reproduce the above copyright notice,
elmot 1:d0dfbce63a89 65 * this list of conditions and the following disclaimer in the documentation
elmot 1:d0dfbce63a89 66 * and/or other materials provided with the distribution.
elmot 1:d0dfbce63a89 67 * 3. Neither the name of STMicroelectronics nor the names of its contributors
elmot 1:d0dfbce63a89 68 * may be used to endorse or promote products derived from this software
elmot 1:d0dfbce63a89 69 * without specific prior written permission.
elmot 1:d0dfbce63a89 70 *
elmot 1:d0dfbce63a89 71 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
elmot 1:d0dfbce63a89 72 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
elmot 1:d0dfbce63a89 73 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
elmot 1:d0dfbce63a89 74 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
elmot 1:d0dfbce63a89 75 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
elmot 1:d0dfbce63a89 76 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
elmot 1:d0dfbce63a89 77 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
elmot 1:d0dfbce63a89 78 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
elmot 1:d0dfbce63a89 79 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
elmot 1:d0dfbce63a89 80 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
elmot 1:d0dfbce63a89 81 *
elmot 1:d0dfbce63a89 82 ******************************************************************************
elmot 1:d0dfbce63a89 83 */
elmot 1:d0dfbce63a89 84
elmot 1:d0dfbce63a89 85 /* Includes ------------------------------------------------------------------*/
elmot 1:d0dfbce63a89 86 #include "stm32l4xx_hal.h"
elmot 1:d0dfbce63a89 87
elmot 1:d0dfbce63a89 88 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
elmot 1:d0dfbce63a89 89
elmot 1:d0dfbce63a89 90 /** @addtogroup STM32L4xx_HAL_Driver
elmot 1:d0dfbce63a89 91 * @{
elmot 1:d0dfbce63a89 92 */
elmot 1:d0dfbce63a89 93
elmot 1:d0dfbce63a89 94 #ifdef HAL_NAND_MODULE_ENABLED
elmot 1:d0dfbce63a89 95
elmot 1:d0dfbce63a89 96 /** @defgroup NAND NAND
elmot 1:d0dfbce63a89 97 * @brief NAND HAL module driver
elmot 1:d0dfbce63a89 98 * @{
elmot 1:d0dfbce63a89 99 */
elmot 1:d0dfbce63a89 100
elmot 1:d0dfbce63a89 101 /* Private typedef -----------------------------------------------------------*/
elmot 1:d0dfbce63a89 102 /* Private define ------------------------------------------------------------*/
elmot 1:d0dfbce63a89 103 /** @defgroup NAND_Private_Constants NAND Private Constants
elmot 1:d0dfbce63a89 104 * @{
elmot 1:d0dfbce63a89 105 */
elmot 1:d0dfbce63a89 106
elmot 1:d0dfbce63a89 107 /**
elmot 1:d0dfbce63a89 108 * @}
elmot 1:d0dfbce63a89 109 */
elmot 1:d0dfbce63a89 110
elmot 1:d0dfbce63a89 111 /* Private macro -------------------------------------------------------------*/
elmot 1:d0dfbce63a89 112 /** @defgroup NAND_Private_Macros NAND Private Macros
elmot 1:d0dfbce63a89 113 * @{
elmot 1:d0dfbce63a89 114 */
elmot 1:d0dfbce63a89 115
elmot 1:d0dfbce63a89 116 /**
elmot 1:d0dfbce63a89 117 * @}
elmot 1:d0dfbce63a89 118 */
elmot 1:d0dfbce63a89 119
elmot 1:d0dfbce63a89 120 /* Private variables ---------------------------------------------------------*/
elmot 1:d0dfbce63a89 121 /* Private function prototypes -----------------------------------------------*/
elmot 1:d0dfbce63a89 122 /** @defgroup NAND_Private_Functions NAND Private Functions
elmot 1:d0dfbce63a89 123 * @{
elmot 1:d0dfbce63a89 124 */
elmot 1:d0dfbce63a89 125 static uint32_t NAND_AddressIncrement(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef* Address);
elmot 1:d0dfbce63a89 126 /**
elmot 1:d0dfbce63a89 127 * @}
elmot 1:d0dfbce63a89 128 */
elmot 1:d0dfbce63a89 129
elmot 1:d0dfbce63a89 130 /* Exported functions ---------------------------------------------------------*/
elmot 1:d0dfbce63a89 131
elmot 1:d0dfbce63a89 132 /** @defgroup NAND_Exported_Functions NAND Exported Functions
elmot 1:d0dfbce63a89 133 * @{
elmot 1:d0dfbce63a89 134 */
elmot 1:d0dfbce63a89 135
elmot 1:d0dfbce63a89 136 /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
elmot 1:d0dfbce63a89 137 * @brief Initialization and Configuration functions
elmot 1:d0dfbce63a89 138 *
elmot 1:d0dfbce63a89 139 @verbatim
elmot 1:d0dfbce63a89 140 ==============================================================================
elmot 1:d0dfbce63a89 141 ##### NAND Initialization and de-initialization functions #####
elmot 1:d0dfbce63a89 142 ==============================================================================
elmot 1:d0dfbce63a89 143 [..]
elmot 1:d0dfbce63a89 144 This section provides functions allowing to initialize/de-initialize
elmot 1:d0dfbce63a89 145 the NAND memory
elmot 1:d0dfbce63a89 146
elmot 1:d0dfbce63a89 147 @endverbatim
elmot 1:d0dfbce63a89 148 * @{
elmot 1:d0dfbce63a89 149 */
elmot 1:d0dfbce63a89 150
elmot 1:d0dfbce63a89 151 /**
elmot 1:d0dfbce63a89 152 * @brief Perform NAND memory Initialization sequence.
elmot 1:d0dfbce63a89 153 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 154 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 155 * @param ComSpace_Timing: pointer to Common space timing structure
elmot 1:d0dfbce63a89 156 * @param AttSpace_Timing: pointer to Attribute space timing structure
elmot 1:d0dfbce63a89 157 * @retval HAL status
elmot 1:d0dfbce63a89 158 */
elmot 1:d0dfbce63a89 159 HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
elmot 1:d0dfbce63a89 160 {
elmot 1:d0dfbce63a89 161 /* Check the NAND handle state */
elmot 1:d0dfbce63a89 162 if(hnand == NULL)
elmot 1:d0dfbce63a89 163 {
elmot 1:d0dfbce63a89 164 return HAL_ERROR;
elmot 1:d0dfbce63a89 165 }
elmot 1:d0dfbce63a89 166
elmot 1:d0dfbce63a89 167 if(hnand->State == HAL_NAND_STATE_RESET)
elmot 1:d0dfbce63a89 168 {
elmot 1:d0dfbce63a89 169 /* Allocate lock resource and initialize it */
elmot 1:d0dfbce63a89 170 hnand->Lock = HAL_UNLOCKED;
elmot 1:d0dfbce63a89 171
elmot 1:d0dfbce63a89 172 /* Initialize the low level hardware (MSP) */
elmot 1:d0dfbce63a89 173 HAL_NAND_MspInit(hnand);
elmot 1:d0dfbce63a89 174 }
elmot 1:d0dfbce63a89 175
elmot 1:d0dfbce63a89 176 /* Initialize NAND control Interface */
elmot 1:d0dfbce63a89 177 FMC_NAND_Init(hnand->Instance, &(hnand->Init));
elmot 1:d0dfbce63a89 178
elmot 1:d0dfbce63a89 179 /* Initialize NAND common space timing Interface */
elmot 1:d0dfbce63a89 180 FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
elmot 1:d0dfbce63a89 181
elmot 1:d0dfbce63a89 182 /* Initialize NAND attribute space timing Interface */
elmot 1:d0dfbce63a89 183 FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
elmot 1:d0dfbce63a89 184
elmot 1:d0dfbce63a89 185 /* Enable the NAND device */
elmot 1:d0dfbce63a89 186 __FMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
elmot 1:d0dfbce63a89 187
elmot 1:d0dfbce63a89 188 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 189 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 190
elmot 1:d0dfbce63a89 191 return HAL_OK;
elmot 1:d0dfbce63a89 192 }
elmot 1:d0dfbce63a89 193
elmot 1:d0dfbce63a89 194 /**
elmot 1:d0dfbce63a89 195 * @brief Perform NAND memory De-Initialization sequence.
elmot 1:d0dfbce63a89 196 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 197 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 198 * @retval HAL status
elmot 1:d0dfbce63a89 199 */
elmot 1:d0dfbce63a89 200 HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 201 {
elmot 1:d0dfbce63a89 202 /* Initialize the low level hardware (MSP) */
elmot 1:d0dfbce63a89 203 HAL_NAND_MspDeInit(hnand);
elmot 1:d0dfbce63a89 204
elmot 1:d0dfbce63a89 205 /* Configure the NAND registers with their reset values */
elmot 1:d0dfbce63a89 206 FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
elmot 1:d0dfbce63a89 207
elmot 1:d0dfbce63a89 208 /* Reset the NAND controller state */
elmot 1:d0dfbce63a89 209 hnand->State = HAL_NAND_STATE_RESET;
elmot 1:d0dfbce63a89 210
elmot 1:d0dfbce63a89 211 /* Release Lock */
elmot 1:d0dfbce63a89 212 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 213
elmot 1:d0dfbce63a89 214 return HAL_OK;
elmot 1:d0dfbce63a89 215 }
elmot 1:d0dfbce63a89 216
elmot 1:d0dfbce63a89 217 /**
elmot 1:d0dfbce63a89 218 * @brief Initialize the NAND MSP.
elmot 1:d0dfbce63a89 219 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 220 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 221 * @retval None
elmot 1:d0dfbce63a89 222 */
elmot 1:d0dfbce63a89 223 __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 224 {
elmot 1:d0dfbce63a89 225 /* Prevent unused argument(s) compilation warning */
elmot 1:d0dfbce63a89 226 UNUSED(hnand);
elmot 1:d0dfbce63a89 227
elmot 1:d0dfbce63a89 228 /* NOTE : This function should not be modified, when the callback is needed,
elmot 1:d0dfbce63a89 229 the HAL_NAND_MspInit could be implemented in the user file
elmot 1:d0dfbce63a89 230 */
elmot 1:d0dfbce63a89 231 }
elmot 1:d0dfbce63a89 232
elmot 1:d0dfbce63a89 233 /**
elmot 1:d0dfbce63a89 234 * @brief DeInitialize the NAND MSP.
elmot 1:d0dfbce63a89 235 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 236 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 237 * @retval None
elmot 1:d0dfbce63a89 238 */
elmot 1:d0dfbce63a89 239 __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 240 {
elmot 1:d0dfbce63a89 241 /* Prevent unused argument(s) compilation warning */
elmot 1:d0dfbce63a89 242 UNUSED(hnand);
elmot 1:d0dfbce63a89 243
elmot 1:d0dfbce63a89 244 /* NOTE : This function should not be modified, when the callback is needed,
elmot 1:d0dfbce63a89 245 the HAL_NAND_MspDeInit could be implemented in the user file
elmot 1:d0dfbce63a89 246 */
elmot 1:d0dfbce63a89 247 }
elmot 1:d0dfbce63a89 248
elmot 1:d0dfbce63a89 249
elmot 1:d0dfbce63a89 250 /**
elmot 1:d0dfbce63a89 251 * @brief This function handles NAND device interrupt request.
elmot 1:d0dfbce63a89 252 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 253 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 254 * @retval HAL status
elmot 1:d0dfbce63a89 255 */
elmot 1:d0dfbce63a89 256 void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 257 {
elmot 1:d0dfbce63a89 258 /* Check NAND interrupt Rising edge flag */
elmot 1:d0dfbce63a89 259 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
elmot 1:d0dfbce63a89 260 {
elmot 1:d0dfbce63a89 261 /* NAND interrupt callback*/
elmot 1:d0dfbce63a89 262 HAL_NAND_ITCallback(hnand);
elmot 1:d0dfbce63a89 263
elmot 1:d0dfbce63a89 264 /* Clear NAND interrupt Rising edge pending bit */
elmot 1:d0dfbce63a89 265 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE);
elmot 1:d0dfbce63a89 266 }
elmot 1:d0dfbce63a89 267
elmot 1:d0dfbce63a89 268 /* Check NAND interrupt Level flag */
elmot 1:d0dfbce63a89 269 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
elmot 1:d0dfbce63a89 270 {
elmot 1:d0dfbce63a89 271 /* NAND interrupt callback*/
elmot 1:d0dfbce63a89 272 HAL_NAND_ITCallback(hnand);
elmot 1:d0dfbce63a89 273
elmot 1:d0dfbce63a89 274 /* Clear NAND interrupt Level pending bit */
elmot 1:d0dfbce63a89 275 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL);
elmot 1:d0dfbce63a89 276 }
elmot 1:d0dfbce63a89 277
elmot 1:d0dfbce63a89 278 /* Check NAND interrupt Falling edge flag */
elmot 1:d0dfbce63a89 279 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
elmot 1:d0dfbce63a89 280 {
elmot 1:d0dfbce63a89 281 /* NAND interrupt callback*/
elmot 1:d0dfbce63a89 282 HAL_NAND_ITCallback(hnand);
elmot 1:d0dfbce63a89 283
elmot 1:d0dfbce63a89 284 /* Clear NAND interrupt Falling edge pending bit */
elmot 1:d0dfbce63a89 285 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE);
elmot 1:d0dfbce63a89 286 }
elmot 1:d0dfbce63a89 287
elmot 1:d0dfbce63a89 288 /* Check NAND interrupt FIFO empty flag */
elmot 1:d0dfbce63a89 289 if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
elmot 1:d0dfbce63a89 290 {
elmot 1:d0dfbce63a89 291 /* NAND interrupt callback*/
elmot 1:d0dfbce63a89 292 HAL_NAND_ITCallback(hnand);
elmot 1:d0dfbce63a89 293
elmot 1:d0dfbce63a89 294 /* Clear NAND interrupt FIFO empty pending bit */
elmot 1:d0dfbce63a89 295 __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT);
elmot 1:d0dfbce63a89 296 }
elmot 1:d0dfbce63a89 297 }
elmot 1:d0dfbce63a89 298
elmot 1:d0dfbce63a89 299 /**
elmot 1:d0dfbce63a89 300 * @brief NAND interrupt feature callback.
elmot 1:d0dfbce63a89 301 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 302 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 303 * @retval None
elmot 1:d0dfbce63a89 304 */
elmot 1:d0dfbce63a89 305 __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 306 {
elmot 1:d0dfbce63a89 307 /* Prevent unused argument(s) compilation warning */
elmot 1:d0dfbce63a89 308 UNUSED(hnand);
elmot 1:d0dfbce63a89 309
elmot 1:d0dfbce63a89 310 /* NOTE : This function should not be modified, when the callback is needed,
elmot 1:d0dfbce63a89 311 the HAL_NAND_ITCallback could be implemented in the user file
elmot 1:d0dfbce63a89 312 */
elmot 1:d0dfbce63a89 313 }
elmot 1:d0dfbce63a89 314
elmot 1:d0dfbce63a89 315 /**
elmot 1:d0dfbce63a89 316 * @}
elmot 1:d0dfbce63a89 317 */
elmot 1:d0dfbce63a89 318
elmot 1:d0dfbce63a89 319 /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
elmot 1:d0dfbce63a89 320 * @brief Input Output and memory control functions
elmot 1:d0dfbce63a89 321 *
elmot 1:d0dfbce63a89 322 @verbatim
elmot 1:d0dfbce63a89 323 ==============================================================================
elmot 1:d0dfbce63a89 324 ##### NAND Input and Output functions #####
elmot 1:d0dfbce63a89 325 ==============================================================================
elmot 1:d0dfbce63a89 326 [..]
elmot 1:d0dfbce63a89 327 This section provides functions allowing to use and control the NAND
elmot 1:d0dfbce63a89 328 memory
elmot 1:d0dfbce63a89 329
elmot 1:d0dfbce63a89 330 @endverbatim
elmot 1:d0dfbce63a89 331 * @{
elmot 1:d0dfbce63a89 332 */
elmot 1:d0dfbce63a89 333
elmot 1:d0dfbce63a89 334 /**
elmot 1:d0dfbce63a89 335 * @brief Read the NAND memory electronic signature.
elmot 1:d0dfbce63a89 336 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 337 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 338 * @param pNAND_ID: NAND ID structure
elmot 1:d0dfbce63a89 339 * @retval HAL status
elmot 1:d0dfbce63a89 340 */
elmot 1:d0dfbce63a89 341 HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
elmot 1:d0dfbce63a89 342 {
elmot 1:d0dfbce63a89 343 __IO uint32_t data = 0;
elmot 1:d0dfbce63a89 344 uint32_t deviceaddress = 0;
elmot 1:d0dfbce63a89 345
elmot 1:d0dfbce63a89 346 /* Process Locked */
elmot 1:d0dfbce63a89 347 __HAL_LOCK(hnand);
elmot 1:d0dfbce63a89 348
elmot 1:d0dfbce63a89 349 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 350 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 351 {
elmot 1:d0dfbce63a89 352 return HAL_BUSY;
elmot 1:d0dfbce63a89 353 }
elmot 1:d0dfbce63a89 354
elmot 1:d0dfbce63a89 355 /* Identify the device address */
elmot 1:d0dfbce63a89 356 deviceaddress = NAND_DEVICE;
elmot 1:d0dfbce63a89 357
elmot 1:d0dfbce63a89 358 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 359 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 360
elmot 1:d0dfbce63a89 361 /* Send Read ID command sequence */
elmot 1:d0dfbce63a89 362 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID;
elmot 1:d0dfbce63a89 363 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
elmot 1:d0dfbce63a89 364
elmot 1:d0dfbce63a89 365 /* Read the electronic signature from NAND flash */
elmot 1:d0dfbce63a89 366 data = *(__IO uint32_t *)deviceaddress;
elmot 1:d0dfbce63a89 367
elmot 1:d0dfbce63a89 368 /* Return the data read */
elmot 1:d0dfbce63a89 369 pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
elmot 1:d0dfbce63a89 370 pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
elmot 1:d0dfbce63a89 371 pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
elmot 1:d0dfbce63a89 372 pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
elmot 1:d0dfbce63a89 373
elmot 1:d0dfbce63a89 374 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 375 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 376
elmot 1:d0dfbce63a89 377 /* Process unlocked */
elmot 1:d0dfbce63a89 378 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 379
elmot 1:d0dfbce63a89 380 return HAL_OK;
elmot 1:d0dfbce63a89 381 }
elmot 1:d0dfbce63a89 382
elmot 1:d0dfbce63a89 383 /**
elmot 1:d0dfbce63a89 384 * @brief NAND memory reset.
elmot 1:d0dfbce63a89 385 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 386 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 387 * @retval HAL status
elmot 1:d0dfbce63a89 388 */
elmot 1:d0dfbce63a89 389 HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 390 {
elmot 1:d0dfbce63a89 391 uint32_t deviceaddress = 0;
elmot 1:d0dfbce63a89 392
elmot 1:d0dfbce63a89 393 /* Process Locked */
elmot 1:d0dfbce63a89 394 __HAL_LOCK(hnand);
elmot 1:d0dfbce63a89 395
elmot 1:d0dfbce63a89 396 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 397 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 398 {
elmot 1:d0dfbce63a89 399 return HAL_BUSY;
elmot 1:d0dfbce63a89 400 }
elmot 1:d0dfbce63a89 401
elmot 1:d0dfbce63a89 402 /* Identify the device address */
elmot 1:d0dfbce63a89 403 deviceaddress = NAND_DEVICE;
elmot 1:d0dfbce63a89 404
elmot 1:d0dfbce63a89 405 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 406 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 407
elmot 1:d0dfbce63a89 408 /* Send NAND reset command */
elmot 1:d0dfbce63a89 409 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
elmot 1:d0dfbce63a89 410
elmot 1:d0dfbce63a89 411
elmot 1:d0dfbce63a89 412 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 413 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 414
elmot 1:d0dfbce63a89 415 /* Process unlocked */
elmot 1:d0dfbce63a89 416 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 417
elmot 1:d0dfbce63a89 418 return HAL_OK;
elmot 1:d0dfbce63a89 419
elmot 1:d0dfbce63a89 420 }
elmot 1:d0dfbce63a89 421
elmot 1:d0dfbce63a89 422 /**
elmot 1:d0dfbce63a89 423 * @brief Read Page(s) from NAND memory block.
elmot 1:d0dfbce63a89 424 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 425 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 426 * @param pAddress: pointer to NAND address structure
elmot 1:d0dfbce63a89 427 * @param pBuffer: pointer to destination read buffer
elmot 1:d0dfbce63a89 428 * @param NumPageToRead: number of pages to read from block
elmot 1:d0dfbce63a89 429 * @retval HAL status
elmot 1:d0dfbce63a89 430 */
elmot 1:d0dfbce63a89 431 HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
elmot 1:d0dfbce63a89 432 {
elmot 1:d0dfbce63a89 433 __IO uint32_t index = 0;
elmot 1:d0dfbce63a89 434 uint32_t deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS;
elmot 1:d0dfbce63a89 435 NAND_AddressTypeDef nandaddress;
elmot 1:d0dfbce63a89 436 uint32_t addressoffset = 0;
elmot 1:d0dfbce63a89 437
elmot 1:d0dfbce63a89 438 /* Process Locked */
elmot 1:d0dfbce63a89 439 __HAL_LOCK(hnand);
elmot 1:d0dfbce63a89 440
elmot 1:d0dfbce63a89 441 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 442 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 443 {
elmot 1:d0dfbce63a89 444 return HAL_BUSY;
elmot 1:d0dfbce63a89 445 }
elmot 1:d0dfbce63a89 446
elmot 1:d0dfbce63a89 447 /* Identify the device address */
elmot 1:d0dfbce63a89 448 deviceaddress = NAND_DEVICE;
elmot 1:d0dfbce63a89 449
elmot 1:d0dfbce63a89 450 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 451 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 452
elmot 1:d0dfbce63a89 453 /* Save the content of pAddress as it will be modified */
elmot 1:d0dfbce63a89 454 nandaddress.Block = pAddress->Block;
elmot 1:d0dfbce63a89 455 nandaddress.Page = pAddress->Page;
elmot 1:d0dfbce63a89 456 nandaddress.Zone = pAddress->Zone;
elmot 1:d0dfbce63a89 457
elmot 1:d0dfbce63a89 458 /* Page(s) read loop */
elmot 1:d0dfbce63a89 459 while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
elmot 1:d0dfbce63a89 460 {
elmot 1:d0dfbce63a89 461 /* update the buffer size */
elmot 1:d0dfbce63a89 462 size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread);
elmot 1:d0dfbce63a89 463
elmot 1:d0dfbce63a89 464 /* Get the address offset */
elmot 1:d0dfbce63a89 465 addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
elmot 1:d0dfbce63a89 466
elmot 1:d0dfbce63a89 467 /* Send read page command sequence */
elmot 1:d0dfbce63a89 468 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
elmot 1:d0dfbce63a89 469
elmot 1:d0dfbce63a89 470 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
elmot 1:d0dfbce63a89 471 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 472 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 473 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 474
elmot 1:d0dfbce63a89 475 /* for 512 and 1 GB devices, 4th cycle is required */
elmot 1:d0dfbce63a89 476 if(hnand->Info.BlockNbr >= 1024)
elmot 1:d0dfbce63a89 477 {
elmot 1:d0dfbce63a89 478 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 479 }
elmot 1:d0dfbce63a89 480
elmot 1:d0dfbce63a89 481 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
elmot 1:d0dfbce63a89 482
elmot 1:d0dfbce63a89 483 /* Get Data into Buffer */
elmot 1:d0dfbce63a89 484 for(; index < size; index++)
elmot 1:d0dfbce63a89 485 {
elmot 1:d0dfbce63a89 486 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
elmot 1:d0dfbce63a89 487 }
elmot 1:d0dfbce63a89 488
elmot 1:d0dfbce63a89 489 /* Increment read pages number */
elmot 1:d0dfbce63a89 490 numpagesread++;
elmot 1:d0dfbce63a89 491
elmot 1:d0dfbce63a89 492 /* Decrement pages to read */
elmot 1:d0dfbce63a89 493 NumPageToRead--;
elmot 1:d0dfbce63a89 494
elmot 1:d0dfbce63a89 495 /* Increment the NAND address */
elmot 1:d0dfbce63a89 496 addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
elmot 1:d0dfbce63a89 497 }
elmot 1:d0dfbce63a89 498
elmot 1:d0dfbce63a89 499 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 500 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 501
elmot 1:d0dfbce63a89 502 /* Process unlocked */
elmot 1:d0dfbce63a89 503 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 504
elmot 1:d0dfbce63a89 505 return HAL_OK;
elmot 1:d0dfbce63a89 506
elmot 1:d0dfbce63a89 507 }
elmot 1:d0dfbce63a89 508
elmot 1:d0dfbce63a89 509 /**
elmot 1:d0dfbce63a89 510 * @brief Write Page(s) to NAND memory block.
elmot 1:d0dfbce63a89 511 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 512 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 513 * @param pAddress: pointer to NAND address structure
elmot 1:d0dfbce63a89 514 * @param pBuffer: pointer to source buffer to write
elmot 1:d0dfbce63a89 515 * @param NumPageToWrite: number of pages to write to block
elmot 1:d0dfbce63a89 516 * @retval HAL status
elmot 1:d0dfbce63a89 517 */
elmot 1:d0dfbce63a89 518 HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
elmot 1:d0dfbce63a89 519 {
elmot 1:d0dfbce63a89 520 __IO uint32_t index = 0;
elmot 1:d0dfbce63a89 521 uint32_t tickstart = 0;
elmot 1:d0dfbce63a89 522 uint32_t deviceaddress = 0 , size = 0, numpageswritten = 0, addressstatus = NAND_VALID_ADDRESS;
elmot 1:d0dfbce63a89 523 NAND_AddressTypeDef nandaddress;
elmot 1:d0dfbce63a89 524 uint32_t addressoffset = 0;
elmot 1:d0dfbce63a89 525
elmot 1:d0dfbce63a89 526 /* Process Locked */
elmot 1:d0dfbce63a89 527 __HAL_LOCK(hnand);
elmot 1:d0dfbce63a89 528
elmot 1:d0dfbce63a89 529 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 530 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 531 {
elmot 1:d0dfbce63a89 532 return HAL_BUSY;
elmot 1:d0dfbce63a89 533 }
elmot 1:d0dfbce63a89 534
elmot 1:d0dfbce63a89 535 /* Identify the device address */
elmot 1:d0dfbce63a89 536 deviceaddress = NAND_DEVICE;
elmot 1:d0dfbce63a89 537
elmot 1:d0dfbce63a89 538 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 539 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 540
elmot 1:d0dfbce63a89 541 /* Save the content of pAddress as it will be modified */
elmot 1:d0dfbce63a89 542 nandaddress.Block = pAddress->Block;
elmot 1:d0dfbce63a89 543 nandaddress.Page = pAddress->Page;
elmot 1:d0dfbce63a89 544 nandaddress.Zone = pAddress->Zone;
elmot 1:d0dfbce63a89 545
elmot 1:d0dfbce63a89 546 /* Page(s) write loop */
elmot 1:d0dfbce63a89 547 while((NumPageToWrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
elmot 1:d0dfbce63a89 548 {
elmot 1:d0dfbce63a89 549 /* update the buffer size */
elmot 1:d0dfbce63a89 550 size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpageswritten);
elmot 1:d0dfbce63a89 551
elmot 1:d0dfbce63a89 552 /* Get the address offset */
elmot 1:d0dfbce63a89 553 addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
elmot 1:d0dfbce63a89 554
elmot 1:d0dfbce63a89 555 /* Send write page command sequence */
elmot 1:d0dfbce63a89 556 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
elmot 1:d0dfbce63a89 557 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
elmot 1:d0dfbce63a89 558
elmot 1:d0dfbce63a89 559 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
elmot 1:d0dfbce63a89 560 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 561 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 562 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 563
elmot 1:d0dfbce63a89 564 /* for 512 and 1 GB devices, 4th cycle is required */
elmot 1:d0dfbce63a89 565 if(hnand->Info.BlockNbr >= 1024)
elmot 1:d0dfbce63a89 566 {
elmot 1:d0dfbce63a89 567 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 568 }
elmot 1:d0dfbce63a89 569
elmot 1:d0dfbce63a89 570 /* Write data to memory */
elmot 1:d0dfbce63a89 571 for(; index < size; index++)
elmot 1:d0dfbce63a89 572 {
elmot 1:d0dfbce63a89 573 *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
elmot 1:d0dfbce63a89 574 }
elmot 1:d0dfbce63a89 575
elmot 1:d0dfbce63a89 576 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
elmot 1:d0dfbce63a89 577
elmot 1:d0dfbce63a89 578 /* Get tick */
elmot 1:d0dfbce63a89 579 tickstart = HAL_GetTick();
elmot 1:d0dfbce63a89 580
elmot 1:d0dfbce63a89 581 /* Read status until NAND is ready */
elmot 1:d0dfbce63a89 582 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
elmot 1:d0dfbce63a89 583 {
elmot 1:d0dfbce63a89 584 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
elmot 1:d0dfbce63a89 585 {
elmot 1:d0dfbce63a89 586 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 587 }
elmot 1:d0dfbce63a89 588 }
elmot 1:d0dfbce63a89 589
elmot 1:d0dfbce63a89 590 /* Increment written pages number */
elmot 1:d0dfbce63a89 591 numpageswritten++;
elmot 1:d0dfbce63a89 592
elmot 1:d0dfbce63a89 593 /* Decrement pages to write */
elmot 1:d0dfbce63a89 594 NumPageToWrite--;
elmot 1:d0dfbce63a89 595
elmot 1:d0dfbce63a89 596 /* Increment the NAND address */
elmot 1:d0dfbce63a89 597 addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
elmot 1:d0dfbce63a89 598 }
elmot 1:d0dfbce63a89 599
elmot 1:d0dfbce63a89 600 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 601 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 602
elmot 1:d0dfbce63a89 603 /* Process unlocked */
elmot 1:d0dfbce63a89 604 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 605
elmot 1:d0dfbce63a89 606 return HAL_OK;
elmot 1:d0dfbce63a89 607 }
elmot 1:d0dfbce63a89 608
elmot 1:d0dfbce63a89 609 /**
elmot 1:d0dfbce63a89 610 * @brief Read Spare area(s) from NAND memory.
elmot 1:d0dfbce63a89 611 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 612 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 613 * @param pAddress: pointer to NAND address structure
elmot 1:d0dfbce63a89 614 * @param pBuffer: pointer to source buffer to write
elmot 1:d0dfbce63a89 615 * @param NumSpareAreaToRead: Number of spare area to read
elmot 1:d0dfbce63a89 616 * @retval HAL status
elmot 1:d0dfbce63a89 617 */
elmot 1:d0dfbce63a89 618 HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
elmot 1:d0dfbce63a89 619 {
elmot 1:d0dfbce63a89 620 __IO uint32_t index = 0;
elmot 1:d0dfbce63a89 621 uint32_t deviceaddress = 0, size = 0, num_spare_area_read = 0, addressstatus = NAND_VALID_ADDRESS;
elmot 1:d0dfbce63a89 622 NAND_AddressTypeDef nandaddress;
elmot 1:d0dfbce63a89 623 uint32_t addressoffset = 0;
elmot 1:d0dfbce63a89 624
elmot 1:d0dfbce63a89 625 /* Process Locked */
elmot 1:d0dfbce63a89 626 __HAL_LOCK(hnand);
elmot 1:d0dfbce63a89 627
elmot 1:d0dfbce63a89 628 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 629 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 630 {
elmot 1:d0dfbce63a89 631 return HAL_BUSY;
elmot 1:d0dfbce63a89 632 }
elmot 1:d0dfbce63a89 633
elmot 1:d0dfbce63a89 634 /* Identify the device address */
elmot 1:d0dfbce63a89 635 deviceaddress = NAND_DEVICE;
elmot 1:d0dfbce63a89 636
elmot 1:d0dfbce63a89 637 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 638 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 639
elmot 1:d0dfbce63a89 640 /* Save the content of pAddress as it will be modified */
elmot 1:d0dfbce63a89 641 nandaddress.Block = pAddress->Block;
elmot 1:d0dfbce63a89 642 nandaddress.Page = pAddress->Page;
elmot 1:d0dfbce63a89 643 nandaddress.Zone = pAddress->Zone;
elmot 1:d0dfbce63a89 644
elmot 1:d0dfbce63a89 645 /* Spare area(s) read loop */
elmot 1:d0dfbce63a89 646 while((NumSpareAreaToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
elmot 1:d0dfbce63a89 647 {
elmot 1:d0dfbce63a89 648 /* update the buffer size */
elmot 1:d0dfbce63a89 649 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_read);
elmot 1:d0dfbce63a89 650
elmot 1:d0dfbce63a89 651 /* Get the address offset */
elmot 1:d0dfbce63a89 652 addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
elmot 1:d0dfbce63a89 653
elmot 1:d0dfbce63a89 654 /* Send read spare area command sequence */
elmot 1:d0dfbce63a89 655 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
elmot 1:d0dfbce63a89 656
elmot 1:d0dfbce63a89 657 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
elmot 1:d0dfbce63a89 658 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 659 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 660 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 661
elmot 1:d0dfbce63a89 662 /* for 512 and 1 GB devices, 4th cycle is required */
elmot 1:d0dfbce63a89 663 if(hnand->Info.BlockNbr >= 1024)
elmot 1:d0dfbce63a89 664 {
elmot 1:d0dfbce63a89 665 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 666 }
elmot 1:d0dfbce63a89 667
elmot 1:d0dfbce63a89 668 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
elmot 1:d0dfbce63a89 669
elmot 1:d0dfbce63a89 670 /* Get Data into Buffer */
elmot 1:d0dfbce63a89 671 for ( ;index < size; index++)
elmot 1:d0dfbce63a89 672 {
elmot 1:d0dfbce63a89 673 *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
elmot 1:d0dfbce63a89 674 }
elmot 1:d0dfbce63a89 675
elmot 1:d0dfbce63a89 676 /* Increment read spare areas number */
elmot 1:d0dfbce63a89 677 num_spare_area_read++;
elmot 1:d0dfbce63a89 678
elmot 1:d0dfbce63a89 679 /* Decrement spare areas to read */
elmot 1:d0dfbce63a89 680 NumSpareAreaToRead--;
elmot 1:d0dfbce63a89 681
elmot 1:d0dfbce63a89 682 /* Increment the NAND address */
elmot 1:d0dfbce63a89 683 addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
elmot 1:d0dfbce63a89 684 }
elmot 1:d0dfbce63a89 685
elmot 1:d0dfbce63a89 686 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 687 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 688
elmot 1:d0dfbce63a89 689 /* Process unlocked */
elmot 1:d0dfbce63a89 690 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 691
elmot 1:d0dfbce63a89 692 return HAL_OK;
elmot 1:d0dfbce63a89 693 }
elmot 1:d0dfbce63a89 694
elmot 1:d0dfbce63a89 695 /**
elmot 1:d0dfbce63a89 696 * @brief Write Spare area(s) to NAND memory.
elmot 1:d0dfbce63a89 697 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 698 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 699 * @param pAddress: pointer to NAND address structure
elmot 1:d0dfbce63a89 700 * @param pBuffer: pointer to source buffer to write
elmot 1:d0dfbce63a89 701 * @param NumSpareAreaTowrite: number of spare areas to write to block
elmot 1:d0dfbce63a89 702 * @retval HAL status
elmot 1:d0dfbce63a89 703 */
elmot 1:d0dfbce63a89 704 HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
elmot 1:d0dfbce63a89 705 {
elmot 1:d0dfbce63a89 706 __IO uint32_t index = 0;
elmot 1:d0dfbce63a89 707 uint32_t tickstart = 0;
elmot 1:d0dfbce63a89 708 uint32_t deviceaddress = 0, size = 0, num_spare_area_written = 0, addressstatus = NAND_VALID_ADDRESS;
elmot 1:d0dfbce63a89 709 NAND_AddressTypeDef nandaddress;
elmot 1:d0dfbce63a89 710 uint32_t addressoffset = 0;
elmot 1:d0dfbce63a89 711
elmot 1:d0dfbce63a89 712 /* Process Locked */
elmot 1:d0dfbce63a89 713 __HAL_LOCK(hnand);
elmot 1:d0dfbce63a89 714
elmot 1:d0dfbce63a89 715 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 716 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 717 {
elmot 1:d0dfbce63a89 718 return HAL_BUSY;
elmot 1:d0dfbce63a89 719 }
elmot 1:d0dfbce63a89 720
elmot 1:d0dfbce63a89 721 /* Identify the device address */
elmot 1:d0dfbce63a89 722 deviceaddress = NAND_DEVICE;
elmot 1:d0dfbce63a89 723
elmot 1:d0dfbce63a89 724 /* Update the FMC_NAND controller state */
elmot 1:d0dfbce63a89 725 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 726
elmot 1:d0dfbce63a89 727 /* Save the content of pAddress as it will be modified */
elmot 1:d0dfbce63a89 728 nandaddress.Block = pAddress->Block;
elmot 1:d0dfbce63a89 729 nandaddress.Page = pAddress->Page;
elmot 1:d0dfbce63a89 730 nandaddress.Zone = pAddress->Zone;
elmot 1:d0dfbce63a89 731
elmot 1:d0dfbce63a89 732 /* Spare area(s) write loop */
elmot 1:d0dfbce63a89 733 while((NumSpareAreaTowrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
elmot 1:d0dfbce63a89 734 {
elmot 1:d0dfbce63a89 735 /* update the buffer size */
elmot 1:d0dfbce63a89 736 size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_written);
elmot 1:d0dfbce63a89 737
elmot 1:d0dfbce63a89 738 /* Get the address offset */
elmot 1:d0dfbce63a89 739 addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
elmot 1:d0dfbce63a89 740
elmot 1:d0dfbce63a89 741 /* Send write Spare area command sequence */
elmot 1:d0dfbce63a89 742 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
elmot 1:d0dfbce63a89 743 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
elmot 1:d0dfbce63a89 744
elmot 1:d0dfbce63a89 745 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
elmot 1:d0dfbce63a89 746 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 747 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 748 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 749
elmot 1:d0dfbce63a89 750 /* for 512 and 1 GB devices, 4th cycle is required */
elmot 1:d0dfbce63a89 751 if(hnand->Info.BlockNbr >= 1024)
elmot 1:d0dfbce63a89 752 {
elmot 1:d0dfbce63a89 753 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
elmot 1:d0dfbce63a89 754 }
elmot 1:d0dfbce63a89 755
elmot 1:d0dfbce63a89 756 /* Write data to memory */
elmot 1:d0dfbce63a89 757 for(; index < size; index++)
elmot 1:d0dfbce63a89 758 {
elmot 1:d0dfbce63a89 759 *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
elmot 1:d0dfbce63a89 760 }
elmot 1:d0dfbce63a89 761
elmot 1:d0dfbce63a89 762 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
elmot 1:d0dfbce63a89 763
elmot 1:d0dfbce63a89 764 /* Get tick */
elmot 1:d0dfbce63a89 765 tickstart = HAL_GetTick();
elmot 1:d0dfbce63a89 766
elmot 1:d0dfbce63a89 767 /* Read status until NAND is ready */
elmot 1:d0dfbce63a89 768 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
elmot 1:d0dfbce63a89 769 {
elmot 1:d0dfbce63a89 770 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
elmot 1:d0dfbce63a89 771 {
elmot 1:d0dfbce63a89 772 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 773 }
elmot 1:d0dfbce63a89 774 }
elmot 1:d0dfbce63a89 775
elmot 1:d0dfbce63a89 776 /* Increment written spare areas number */
elmot 1:d0dfbce63a89 777 num_spare_area_written++;
elmot 1:d0dfbce63a89 778
elmot 1:d0dfbce63a89 779 /* Decrement spare areas to write */
elmot 1:d0dfbce63a89 780 NumSpareAreaTowrite--;
elmot 1:d0dfbce63a89 781
elmot 1:d0dfbce63a89 782 /* Increment the NAND address */
elmot 1:d0dfbce63a89 783 addressstatus = NAND_AddressIncrement(hnand, &nandaddress);
elmot 1:d0dfbce63a89 784 }
elmot 1:d0dfbce63a89 785
elmot 1:d0dfbce63a89 786 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 787 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 788
elmot 1:d0dfbce63a89 789 /* Process unlocked */
elmot 1:d0dfbce63a89 790 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 791
elmot 1:d0dfbce63a89 792 return HAL_OK;
elmot 1:d0dfbce63a89 793 }
elmot 1:d0dfbce63a89 794
elmot 1:d0dfbce63a89 795 /**
elmot 1:d0dfbce63a89 796 * @brief NAND memory Block erase.
elmot 1:d0dfbce63a89 797 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 798 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 799 * @param pAddress: pointer to NAND address structure
elmot 1:d0dfbce63a89 800 * @retval HAL status
elmot 1:d0dfbce63a89 801 */
elmot 1:d0dfbce63a89 802 HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
elmot 1:d0dfbce63a89 803 {
elmot 1:d0dfbce63a89 804 uint32_t deviceaddress = 0;
elmot 1:d0dfbce63a89 805 uint32_t tickstart = 0;
elmot 1:d0dfbce63a89 806
elmot 1:d0dfbce63a89 807 /* Process Locked */
elmot 1:d0dfbce63a89 808 __HAL_LOCK(hnand);
elmot 1:d0dfbce63a89 809
elmot 1:d0dfbce63a89 810 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 811 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 812 {
elmot 1:d0dfbce63a89 813 return HAL_BUSY;
elmot 1:d0dfbce63a89 814 }
elmot 1:d0dfbce63a89 815
elmot 1:d0dfbce63a89 816 /* Identify the device address */
elmot 1:d0dfbce63a89 817 deviceaddress = NAND_DEVICE;
elmot 1:d0dfbce63a89 818
elmot 1:d0dfbce63a89 819 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 820 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 821
elmot 1:d0dfbce63a89 822 /* Send Erase block command sequence */
elmot 1:d0dfbce63a89 823 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
elmot 1:d0dfbce63a89 824
elmot 1:d0dfbce63a89 825 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
elmot 1:d0dfbce63a89 826 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
elmot 1:d0dfbce63a89 827 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
elmot 1:d0dfbce63a89 828
elmot 1:d0dfbce63a89 829 /* for 512 and 1 GB devices, 4th cycle is required */
elmot 1:d0dfbce63a89 830 if(hnand->Info.BlockNbr >= 1024)
elmot 1:d0dfbce63a89 831 {
elmot 1:d0dfbce63a89 832 *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
elmot 1:d0dfbce63a89 833 }
elmot 1:d0dfbce63a89 834
elmot 1:d0dfbce63a89 835 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
elmot 1:d0dfbce63a89 836
elmot 1:d0dfbce63a89 837 /* Update the NAND controller state */
elmot 1:d0dfbce63a89 838 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 839
elmot 1:d0dfbce63a89 840 /* Get tick */
elmot 1:d0dfbce63a89 841 tickstart = HAL_GetTick();
elmot 1:d0dfbce63a89 842
elmot 1:d0dfbce63a89 843 /* Read status until NAND is ready */
elmot 1:d0dfbce63a89 844 while(HAL_NAND_Read_Status(hnand) != NAND_READY)
elmot 1:d0dfbce63a89 845 {
elmot 1:d0dfbce63a89 846 if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
elmot 1:d0dfbce63a89 847 {
elmot 1:d0dfbce63a89 848 /* Process unlocked */
elmot 1:d0dfbce63a89 849 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 850
elmot 1:d0dfbce63a89 851 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 852 }
elmot 1:d0dfbce63a89 853 }
elmot 1:d0dfbce63a89 854
elmot 1:d0dfbce63a89 855 /* Process unlocked */
elmot 1:d0dfbce63a89 856 __HAL_UNLOCK(hnand);
elmot 1:d0dfbce63a89 857
elmot 1:d0dfbce63a89 858 return HAL_OK;
elmot 1:d0dfbce63a89 859 }
elmot 1:d0dfbce63a89 860
elmot 1:d0dfbce63a89 861 /**
elmot 1:d0dfbce63a89 862 * @brief NAND memory read status.
elmot 1:d0dfbce63a89 863 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 864 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 865 * @retval NAND status
elmot 1:d0dfbce63a89 866 */
elmot 1:d0dfbce63a89 867 uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 868 {
elmot 1:d0dfbce63a89 869 uint32_t data = 0;
elmot 1:d0dfbce63a89 870 uint32_t deviceaddress = 0;
elmot 1:d0dfbce63a89 871
elmot 1:d0dfbce63a89 872 /* Prevent unused argument(s) compilation warning */
elmot 1:d0dfbce63a89 873 UNUSED(hnand);
elmot 1:d0dfbce63a89 874
elmot 1:d0dfbce63a89 875 /* Identify the device address */
elmot 1:d0dfbce63a89 876 deviceaddress = NAND_DEVICE;
elmot 1:d0dfbce63a89 877
elmot 1:d0dfbce63a89 878 /* Send Read status operation command */
elmot 1:d0dfbce63a89 879 *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
elmot 1:d0dfbce63a89 880
elmot 1:d0dfbce63a89 881 /* Read status register data */
elmot 1:d0dfbce63a89 882 data = *(__IO uint8_t *)deviceaddress;
elmot 1:d0dfbce63a89 883
elmot 1:d0dfbce63a89 884 /* Return the status */
elmot 1:d0dfbce63a89 885 if((data & NAND_ERROR) == NAND_ERROR)
elmot 1:d0dfbce63a89 886 {
elmot 1:d0dfbce63a89 887 return NAND_ERROR;
elmot 1:d0dfbce63a89 888 }
elmot 1:d0dfbce63a89 889 else if((data & NAND_READY) == NAND_READY)
elmot 1:d0dfbce63a89 890 {
elmot 1:d0dfbce63a89 891 return NAND_READY;
elmot 1:d0dfbce63a89 892 }
elmot 1:d0dfbce63a89 893
elmot 1:d0dfbce63a89 894 return NAND_BUSY;
elmot 1:d0dfbce63a89 895 }
elmot 1:d0dfbce63a89 896
elmot 1:d0dfbce63a89 897 /**
elmot 1:d0dfbce63a89 898 * @brief Increment the NAND memory address.
elmot 1:d0dfbce63a89 899 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 900 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 901 * @param pAddress: pointer to NAND address structure
elmot 1:d0dfbce63a89 902 * @retval The new status of the increment address operation. It can be:
elmot 1:d0dfbce63a89 903 * - NAND_VALID_ADDRESS: When the new address is valid address
elmot 1:d0dfbce63a89 904 * - NAND_INVALID_ADDRESS: When the new address is invalid address
elmot 1:d0dfbce63a89 905 */
elmot 1:d0dfbce63a89 906 uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
elmot 1:d0dfbce63a89 907 {
elmot 1:d0dfbce63a89 908 uint32_t status = NAND_VALID_ADDRESS;
elmot 1:d0dfbce63a89 909
elmot 1:d0dfbce63a89 910 /* Increment page address */
elmot 1:d0dfbce63a89 911 pAddress->Page++;
elmot 1:d0dfbce63a89 912
elmot 1:d0dfbce63a89 913 /* Check NAND address is valid */
elmot 1:d0dfbce63a89 914 if(pAddress->Page == hnand->Info.BlockSize)
elmot 1:d0dfbce63a89 915 {
elmot 1:d0dfbce63a89 916 pAddress->Page = 0;
elmot 1:d0dfbce63a89 917 pAddress->Block++;
elmot 1:d0dfbce63a89 918
elmot 1:d0dfbce63a89 919 if(pAddress->Block == hnand->Info.ZoneSize)
elmot 1:d0dfbce63a89 920 {
elmot 1:d0dfbce63a89 921 pAddress->Block = 0;
elmot 1:d0dfbce63a89 922 pAddress->Zone++;
elmot 1:d0dfbce63a89 923
elmot 1:d0dfbce63a89 924 if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
elmot 1:d0dfbce63a89 925 {
elmot 1:d0dfbce63a89 926 status = NAND_INVALID_ADDRESS;
elmot 1:d0dfbce63a89 927 }
elmot 1:d0dfbce63a89 928 }
elmot 1:d0dfbce63a89 929 }
elmot 1:d0dfbce63a89 930
elmot 1:d0dfbce63a89 931 return (status);
elmot 1:d0dfbce63a89 932 }
elmot 1:d0dfbce63a89 933 /**
elmot 1:d0dfbce63a89 934 * @}
elmot 1:d0dfbce63a89 935 */
elmot 1:d0dfbce63a89 936
elmot 1:d0dfbce63a89 937 /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
elmot 1:d0dfbce63a89 938 * @brief management functions
elmot 1:d0dfbce63a89 939 *
elmot 1:d0dfbce63a89 940 @verbatim
elmot 1:d0dfbce63a89 941 ==============================================================================
elmot 1:d0dfbce63a89 942 ##### NAND Control functions #####
elmot 1:d0dfbce63a89 943 ==============================================================================
elmot 1:d0dfbce63a89 944 [..]
elmot 1:d0dfbce63a89 945 This subsection provides a set of functions allowing to control dynamically
elmot 1:d0dfbce63a89 946 the NAND interface.
elmot 1:d0dfbce63a89 947
elmot 1:d0dfbce63a89 948 @endverbatim
elmot 1:d0dfbce63a89 949 * @{
elmot 1:d0dfbce63a89 950 */
elmot 1:d0dfbce63a89 951
elmot 1:d0dfbce63a89 952
elmot 1:d0dfbce63a89 953 /**
elmot 1:d0dfbce63a89 954 * @brief Enable dynamically NAND ECC feature.
elmot 1:d0dfbce63a89 955 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 956 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 957 * @retval HAL status
elmot 1:d0dfbce63a89 958 */
elmot 1:d0dfbce63a89 959 HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 960 {
elmot 1:d0dfbce63a89 961 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 962 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 963 {
elmot 1:d0dfbce63a89 964 return HAL_BUSY;
elmot 1:d0dfbce63a89 965 }
elmot 1:d0dfbce63a89 966
elmot 1:d0dfbce63a89 967 /* Update the NAND state */
elmot 1:d0dfbce63a89 968 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 969
elmot 1:d0dfbce63a89 970 /* Enable ECC feature */
elmot 1:d0dfbce63a89 971 FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
elmot 1:d0dfbce63a89 972
elmot 1:d0dfbce63a89 973 /* Update the NAND state */
elmot 1:d0dfbce63a89 974 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 975
elmot 1:d0dfbce63a89 976 return HAL_OK;
elmot 1:d0dfbce63a89 977 }
elmot 1:d0dfbce63a89 978
elmot 1:d0dfbce63a89 979 /**
elmot 1:d0dfbce63a89 980 * @brief Disable dynamically NAND ECC feature.
elmot 1:d0dfbce63a89 981 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 982 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 983 * @retval HAL status
elmot 1:d0dfbce63a89 984 */
elmot 1:d0dfbce63a89 985 HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 986 {
elmot 1:d0dfbce63a89 987 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 988 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 989 {
elmot 1:d0dfbce63a89 990 return HAL_BUSY;
elmot 1:d0dfbce63a89 991 }
elmot 1:d0dfbce63a89 992
elmot 1:d0dfbce63a89 993 /* Update the NAND state */
elmot 1:d0dfbce63a89 994 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 995
elmot 1:d0dfbce63a89 996 /* Disable ECC feature */
elmot 1:d0dfbce63a89 997 FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
elmot 1:d0dfbce63a89 998
elmot 1:d0dfbce63a89 999 /* Update the NAND state */
elmot 1:d0dfbce63a89 1000 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 1001
elmot 1:d0dfbce63a89 1002 return HAL_OK;
elmot 1:d0dfbce63a89 1003 }
elmot 1:d0dfbce63a89 1004
elmot 1:d0dfbce63a89 1005 /**
elmot 1:d0dfbce63a89 1006 * @brief Disable dynamically NAND ECC feature.
elmot 1:d0dfbce63a89 1007 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1008 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 1009 * @param ECCval: pointer to ECC value
elmot 1:d0dfbce63a89 1010 * @param Timeout: maximum timeout to wait
elmot 1:d0dfbce63a89 1011 * @retval HAL status
elmot 1:d0dfbce63a89 1012 */
elmot 1:d0dfbce63a89 1013 HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
elmot 1:d0dfbce63a89 1014 {
elmot 1:d0dfbce63a89 1015 HAL_StatusTypeDef status = HAL_OK;
elmot 1:d0dfbce63a89 1016
elmot 1:d0dfbce63a89 1017 /* Check the NAND controller state */
elmot 1:d0dfbce63a89 1018 if(hnand->State == HAL_NAND_STATE_BUSY)
elmot 1:d0dfbce63a89 1019 {
elmot 1:d0dfbce63a89 1020 return HAL_BUSY;
elmot 1:d0dfbce63a89 1021 }
elmot 1:d0dfbce63a89 1022
elmot 1:d0dfbce63a89 1023 /* Update the NAND state */
elmot 1:d0dfbce63a89 1024 hnand->State = HAL_NAND_STATE_BUSY;
elmot 1:d0dfbce63a89 1025
elmot 1:d0dfbce63a89 1026 /* Get NAND ECC value */
elmot 1:d0dfbce63a89 1027 status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
elmot 1:d0dfbce63a89 1028
elmot 1:d0dfbce63a89 1029 /* Update the NAND state */
elmot 1:d0dfbce63a89 1030 hnand->State = HAL_NAND_STATE_READY;
elmot 1:d0dfbce63a89 1031
elmot 1:d0dfbce63a89 1032 return status;
elmot 1:d0dfbce63a89 1033 }
elmot 1:d0dfbce63a89 1034
elmot 1:d0dfbce63a89 1035 /**
elmot 1:d0dfbce63a89 1036 * @}
elmot 1:d0dfbce63a89 1037 */
elmot 1:d0dfbce63a89 1038
elmot 1:d0dfbce63a89 1039
elmot 1:d0dfbce63a89 1040 /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
elmot 1:d0dfbce63a89 1041 * @brief Peripheral State functions
elmot 1:d0dfbce63a89 1042 *
elmot 1:d0dfbce63a89 1043 @verbatim
elmot 1:d0dfbce63a89 1044 ==============================================================================
elmot 1:d0dfbce63a89 1045 ##### NAND State functions #####
elmot 1:d0dfbce63a89 1046 ==============================================================================
elmot 1:d0dfbce63a89 1047 [..]
elmot 1:d0dfbce63a89 1048 This subsection permits to get in run-time the status of the NAND controller
elmot 1:d0dfbce63a89 1049 and the data flow.
elmot 1:d0dfbce63a89 1050
elmot 1:d0dfbce63a89 1051 @endverbatim
elmot 1:d0dfbce63a89 1052 * @{
elmot 1:d0dfbce63a89 1053 */
elmot 1:d0dfbce63a89 1054
elmot 1:d0dfbce63a89 1055 /**
elmot 1:d0dfbce63a89 1056 * @brief Return the NAND handle state.
elmot 1:d0dfbce63a89 1057 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1058 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 1059 * @retval HAL state
elmot 1:d0dfbce63a89 1060 */
elmot 1:d0dfbce63a89 1061 HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
elmot 1:d0dfbce63a89 1062 {
elmot 1:d0dfbce63a89 1063 /* Return NAND handle state */
elmot 1:d0dfbce63a89 1064 return hnand->State;
elmot 1:d0dfbce63a89 1065 }
elmot 1:d0dfbce63a89 1066
elmot 1:d0dfbce63a89 1067 /**
elmot 1:d0dfbce63a89 1068 * @}
elmot 1:d0dfbce63a89 1069 */
elmot 1:d0dfbce63a89 1070
elmot 1:d0dfbce63a89 1071 /**
elmot 1:d0dfbce63a89 1072 * @}
elmot 1:d0dfbce63a89 1073 */
elmot 1:d0dfbce63a89 1074
elmot 1:d0dfbce63a89 1075 /** @addtogroup NAND_Private_Functions
elmot 1:d0dfbce63a89 1076 * @{
elmot 1:d0dfbce63a89 1077 */
elmot 1:d0dfbce63a89 1078
elmot 1:d0dfbce63a89 1079 /**
elmot 1:d0dfbce63a89 1080 * @brief Increment the NAND memory address.
elmot 1:d0dfbce63a89 1081 * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1082 * the configuration information for NAND module.
elmot 1:d0dfbce63a89 1083 * @param Address: address to be incremented.
elmot 1:d0dfbce63a89 1084 * @retval The new status of the increment address operation. It can be:
elmot 1:d0dfbce63a89 1085 * - NAND_VALID_ADDRESS: When the new address is valid address
elmot 1:d0dfbce63a89 1086 * - NAND_INVALID_ADDRESS: When the new address is invalid address
elmot 1:d0dfbce63a89 1087 */
elmot 1:d0dfbce63a89 1088 static uint32_t NAND_AddressIncrement(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef* Address)
elmot 1:d0dfbce63a89 1089 {
elmot 1:d0dfbce63a89 1090 uint32_t status = NAND_VALID_ADDRESS;
elmot 1:d0dfbce63a89 1091
elmot 1:d0dfbce63a89 1092 Address->Page++;
elmot 1:d0dfbce63a89 1093
elmot 1:d0dfbce63a89 1094 if(Address->Page == hnand->Info.BlockSize)
elmot 1:d0dfbce63a89 1095 {
elmot 1:d0dfbce63a89 1096 Address->Page = 0;
elmot 1:d0dfbce63a89 1097 Address->Block++;
elmot 1:d0dfbce63a89 1098
elmot 1:d0dfbce63a89 1099 if(Address->Block == hnand->Info.ZoneSize)
elmot 1:d0dfbce63a89 1100 {
elmot 1:d0dfbce63a89 1101 Address->Block = 0;
elmot 1:d0dfbce63a89 1102 Address->Zone++;
elmot 1:d0dfbce63a89 1103
elmot 1:d0dfbce63a89 1104 if(Address->Zone == hnand->Info.BlockNbr)
elmot 1:d0dfbce63a89 1105 {
elmot 1:d0dfbce63a89 1106 status = NAND_INVALID_ADDRESS;
elmot 1:d0dfbce63a89 1107 }
elmot 1:d0dfbce63a89 1108 }
elmot 1:d0dfbce63a89 1109 }
elmot 1:d0dfbce63a89 1110
elmot 1:d0dfbce63a89 1111 return (status);
elmot 1:d0dfbce63a89 1112 }
elmot 1:d0dfbce63a89 1113
elmot 1:d0dfbce63a89 1114 /**
elmot 1:d0dfbce63a89 1115 * @}
elmot 1:d0dfbce63a89 1116 */
elmot 1:d0dfbce63a89 1117
elmot 1:d0dfbce63a89 1118 /**
elmot 1:d0dfbce63a89 1119 * @}
elmot 1:d0dfbce63a89 1120 */
elmot 1:d0dfbce63a89 1121
elmot 1:d0dfbce63a89 1122 #endif /* HAL_NAND_MODULE_ENABLED */
elmot 1:d0dfbce63a89 1123
elmot 1:d0dfbce63a89 1124 /**
elmot 1:d0dfbce63a89 1125 * @}
elmot 1:d0dfbce63a89 1126 */
elmot 1:d0dfbce63a89 1127
elmot 1:d0dfbce63a89 1128 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */
elmot 1:d0dfbce63a89 1129
elmot 1:d0dfbce63a89 1130 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/