STM32F479xx HAL User Manual
stm32f4xx_hal_pccard.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_pccard.c
00004   * @author  MCD Application Team
00005   * @brief   PCCARD HAL module driver.
00006   *          This file provides a generic firmware to drive PCCARD memories mounted
00007   *          as external device.
00008   *
00009   @verbatim
00010  ===============================================================================
00011                         ##### How to use this driver #####
00012  ===============================================================================
00013    [..]
00014      This driver is a generic layered driver which contains a set of APIs used to
00015       control PCCARD/compact flash memories. It uses the FMC/FSMC layer functions
00016      to interface with PCCARD devices. This driver is used for:
00017 
00018     (+) PCCARD/Compact Flash memory configuration sequence using the function
00019         HAL_PCCARD_Init()/HAL_CF_Init() with control and timing parameters for
00020         both common and attribute spaces.
00021 
00022     (+) Read PCCARD/Compact Flash memory maker and device IDs using the function
00023         HAL_PCCARD_Read_ID()/HAL_CF_Read_ID(). The read information is stored in
00024         the CompactFlash_ID structure declared by the function caller.
00025 
00026     (+) Access PCCARD/Compact Flash memory by read/write operations using the functions
00027         HAL_PCCARD_Read_Sector()/ HAL_PCCARD_Write_Sector() -
00028         HAL_CF_Read_Sector()/HAL_CF_Write_Sector(), to read/write sector.
00029 
00030     (+) Perform PCCARD/Compact Flash Reset chip operation using the function
00031         HAL_PCCARD_Reset()/HAL_CF_Reset.
00032 
00033     (+) Perform PCCARD/Compact Flash erase sector operation using the function
00034         HAL_PCCARD_Erase_Sector()/HAL_CF_Erase_Sector.
00035 
00036     (+) Read the PCCARD/Compact Flash status operation using the function
00037         HAL_PCCARD_ReadStatus()/HAL_CF_ReadStatus().
00038 
00039     (+) You can monitor the PCCARD/Compact Flash  device HAL state by calling
00040         the function HAL_PCCARD_GetState()/HAL_CF_GetState()
00041 
00042    [..]
00043      (@) This driver is a set of generic APIs which handle standard PCCARD/compact flash
00044          operations. If a PCCARD/Compact Flash device contains different operations
00045          and/or implementations, it should be implemented separately.
00046 
00047       *** Callback registration ***
00048     =============================================
00049     [..]
00050       The compilation define  USE_HAL_PCCARD_REGISTER_CALLBACKS when set to 1
00051       allows the user to configure dynamically the driver callbacks.
00052 
00053       Use Functions HAL_PCCARD_RegisterCallback() to register a user callback,
00054       it allows to register following callbacks:
00055         (+) MspInitCallback    : PCCARD MspInit.
00056         (+) MspDeInitCallback  : PCCARD MspDeInit.
00057       This function takes as parameters the HAL peripheral handle, the Callback ID
00058       and a pointer to the user callback function.
00059 
00060       Use function HAL_PCCARD_UnRegisterCallback() to reset a callback to the default
00061       weak (surcharged) function. It allows to reset following callbacks:
00062         (+) MspInitCallback    : PCCARD MspInit.
00063         (+) MspDeInitCallback  : PCCARD MspDeInit.
00064       This function) takes as parameters the HAL peripheral handle and the Callback ID.
00065 
00066       By default, after the HAL_PCCARD_Init and if the state is HAL_PCCARD_STATE_RESET
00067       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
00068       Exception done for MspInit and MspDeInit callbacks that are respectively
00069       reset to the legacy weak (surcharged) functions in the HAL_PCCARD_Init
00070       and  HAL_PCCARD_DeInit only when these callbacks are null (not registered beforehand).
00071       If not, MspInit or MspDeInit are not null, the HAL_PCCARD_Init and HAL_PCCARD_DeInit
00072       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
00073 
00074       Callbacks can be registered/unregistered in READY state only.
00075       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
00076       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
00077       during the Init/DeInit.
00078       In that case first register the MspInit/MspDeInit user callbacks
00079       using HAL_PCCARD_RegisterCallback before calling HAL_PCCARD_DeInit
00080       or HAL_PCCARD_Init function.
00081 
00082       When The compilation define USE_HAL_PCCARD_REGISTER_CALLBACKS is set to 0 or
00083       not defined, the callback registering feature is not available
00084       and weak (surcharged) callbacks are used.
00085 
00086   @endverbatim
00087   ******************************************************************************
00088   * @attention
00089   *
00090   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
00091   * All rights reserved.</center></h2>
00092   *
00093   * This software component is licensed by ST under BSD 3-Clause license,
00094   * the "License"; You may not use this file except in compliance with the
00095   * License. You may obtain a copy of the License at:
00096   *                       opensource.org/licenses/BSD-3-Clause
00097   *
00098   ******************************************************************************
00099   */
00100 
00101 /* Includes ------------------------------------------------------------------*/
00102 #include "stm32f4xx_hal.h"
00103 
00104 #if defined(FMC_Bank4) || defined(FSMC_Bank4)
00105 
00106 /** @addtogroup STM32F4xx_HAL_Driver
00107   * @{
00108   */
00109 
00110 #ifdef HAL_PCCARD_MODULE_ENABLED
00111 
00112 /** @defgroup PCCARD PCCARD
00113   * @brief PCCARD HAL module driver
00114   * @{
00115   */
00116 /* Private typedef -----------------------------------------------------------*/
00117 /* Private define ------------------------------------------------------------*/
00118 
00119 /** @defgroup PCCARD_Private_Defines PCCARD Private Defines
00120   * @{
00121   */
00122 #define PCCARD_TIMEOUT_READ_ID                 0x0000FFFFU
00123 #define PCCARD_TIMEOUT_READ_WRITE_SECTOR       0x0000FFFFU
00124 #define PCCARD_TIMEOUT_ERASE_SECTOR            0x00000400U
00125 #define PCCARD_TIMEOUT_STATUS                  0x01000000U
00126 
00127 #define PCCARD_STATUS_OK                       (uint8_t)0x58
00128 #define PCCARD_STATUS_WRITE_OK                 (uint8_t)0x50
00129 /**
00130   * @}
00131   */
00132 
00133 /* Private macro -------------------------------------------------------------*/
00134 /* Private variables ---------------------------------------------------------*/
00135 /* Private function ----------------------------------------------------------*/
00136 /* Exported functions --------------------------------------------------------*/
00137 /** @defgroup PCCARD_Exported_Functions PCCARD Exported Functions
00138   * @{
00139   */
00140 
00141 /** @defgroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
00142   * @brief    Initialization and Configuration functions
00143   *
00144   @verbatim
00145   ==============================================================================
00146           ##### PCCARD Initialization and de-initialization functions #####
00147   ==============================================================================
00148   [..]
00149     This section provides functions allowing to initialize/de-initialize
00150     the PCCARD memory
00151 
00152 @endverbatim
00153   * @{
00154   */
00155 
00156 /**
00157   * @brief  Perform the PCCARD memory Initialization sequence
00158   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00159   *                the configuration information for PCCARD module.
00160   * @param  ComSpaceTiming Common space timing structure
00161   * @param  AttSpaceTiming Attribute space timing structure
00162   * @param  IOSpaceTiming IO space timing structure
00163   * @retval HAL status
00164   */
00165 HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FMC_NAND_PCC_TimingTypeDef *ComSpaceTiming,
00166                                   FMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FMC_NAND_PCC_TimingTypeDef *IOSpaceTiming)
00167 {
00168   /* Check the PCCARD controller state */
00169   if (hpccard == NULL)
00170   {
00171     return HAL_ERROR;
00172   }
00173 
00174   if (hpccard->State == HAL_PCCARD_STATE_RESET)
00175   {
00176     /* Allocate lock resource and initialize it */
00177     hpccard->Lock = HAL_UNLOCKED;
00178 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
00179     if (hpccard->MspInitCallback == NULL)
00180     {
00181       hpccard->MspInitCallback = HAL_PCCARD_MspInit;
00182     }
00183     hpccard->ItCallback = HAL_PCCARD_ITCallback;
00184 
00185     /* Init the low level hardware */
00186     hpccard->MspInitCallback(hpccard);
00187 #else
00188     /* Initialize the low level hardware (MSP) */
00189     HAL_PCCARD_MspInit(hpccard);
00190 #endif
00191   }
00192 
00193   /* Initialize the PCCARD state */
00194   hpccard->State = HAL_PCCARD_STATE_BUSY;
00195 
00196   /* Initialize PCCARD control Interface */
00197   FMC_PCCARD_Init(hpccard->Instance, &(hpccard->Init));
00198 
00199   /* Init PCCARD common space timing Interface */
00200   FMC_PCCARD_CommonSpace_Timing_Init(hpccard->Instance, ComSpaceTiming);
00201 
00202   /* Init PCCARD attribute space timing Interface */
00203   FMC_PCCARD_AttributeSpace_Timing_Init(hpccard->Instance, AttSpaceTiming);
00204 
00205   /* Init PCCARD IO space timing Interface */
00206   FMC_PCCARD_IOSpace_Timing_Init(hpccard->Instance, IOSpaceTiming);
00207 
00208   /* Enable the PCCARD device */
00209   __FMC_PCCARD_ENABLE(hpccard->Instance);
00210 
00211   /* Update the PCCARD state */
00212   hpccard->State = HAL_PCCARD_STATE_READY;
00213 
00214   return HAL_OK;
00215 
00216 }
00217 
00218 /**
00219   * @brief  Perform the PCCARD memory De-initialization sequence
00220   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00221   *                the configuration information for PCCARD module.
00222   * @retval HAL status
00223   */
00224 HAL_StatusTypeDef  HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard)
00225 {
00226 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
00227   if (hpccard->MspDeInitCallback == NULL)
00228   {
00229     hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
00230   }
00231 
00232   /* DeInit the low level hardware */
00233   hpccard->MspDeInitCallback(hpccard);
00234 #else
00235   /* De-Initialize the low level hardware (MSP) */
00236   HAL_PCCARD_MspDeInit(hpccard);
00237 #endif
00238 
00239   /* Configure the PCCARD registers with their reset values */
00240   FMC_PCCARD_DeInit(hpccard->Instance);
00241 
00242   /* Update the PCCARD controller state */
00243   hpccard->State = HAL_PCCARD_STATE_RESET;
00244 
00245   /* Release Lock */
00246   __HAL_UNLOCK(hpccard);
00247 
00248   return HAL_OK;
00249 }
00250 
00251 /**
00252   * @brief  PCCARD MSP Init
00253   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00254   *                the configuration information for PCCARD module.
00255   * @retval None
00256   */
00257 __weak void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard)
00258 {
00259   /* Prevent unused argument(s) compilation warning */
00260   UNUSED(hpccard);
00261   /* NOTE : This function Should not be modified, when the callback is needed,
00262             the HAL_PCCARD_MspInit could be implemented in the user file
00263    */
00264 }
00265 
00266 /**
00267   * @brief  PCCARD MSP DeInit
00268   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00269   *                the configuration information for PCCARD module.
00270   * @retval None
00271   */
00272 __weak void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard)
00273 {
00274   /* Prevent unused argument(s) compilation warning */
00275   UNUSED(hpccard);
00276   /* NOTE : This function Should not be modified, when the callback is needed,
00277             the HAL_PCCARD_MspDeInit could be implemented in the user file
00278    */
00279 }
00280 
00281 /**
00282   * @}
00283   */
00284 
00285 /** @defgroup PCCARD_Exported_Functions_Group2 Input and Output functions
00286   * @brief    Input Output and memory control functions
00287   *
00288   @verbatim
00289   ==============================================================================
00290                     ##### PCCARD Input and Output functions #####
00291   ==============================================================================
00292   [..]
00293     This section provides functions allowing to use and control the PCCARD memory
00294 
00295 @endverbatim
00296   * @{
00297   */
00298 
00299 /**
00300   * @brief  Read Compact Flash's ID.
00301   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00302   *                the configuration information for PCCARD module.
00303   * @param  CompactFlash_ID Compact flash ID structure.
00304   * @param  pStatus pointer to compact flash status
00305   * @retval HAL status
00306   *
00307   */
00308 HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus)
00309 {
00310   uint32_t timeout = PCCARD_TIMEOUT_READ_ID, index = 0U;
00311   uint8_t status = 0;
00312 
00313   /* Process Locked */
00314   __HAL_LOCK(hpccard);
00315 
00316   /* Check the PCCARD controller state */
00317   if (hpccard->State == HAL_PCCARD_STATE_BUSY)
00318   {
00319     return HAL_BUSY;
00320   }
00321 
00322   /* Update the PCCARD controller state */
00323   hpccard->State = HAL_PCCARD_STATE_BUSY;
00324 
00325   /* Initialize the PCCARD status */
00326   *pStatus = PCCARD_READY;
00327 
00328   /* Send the Identify Command */
00329   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD)  = (uint16_t)0xECEC;
00330 
00331   /* Read PCCARD IDs and timeout treatment */
00332   do
00333   {
00334     /* Read the PCCARD status */
00335     status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00336 
00337     timeout--;
00338   } while ((status != PCCARD_STATUS_OK) && timeout);
00339 
00340   if (timeout == 0U)
00341   {
00342     *pStatus = PCCARD_TIMEOUT_ERROR;
00343   }
00344   else
00345   {
00346     /* Read PCCARD ID bytes */
00347     for (index = 0U; index < 16U; index++)
00348     {
00349       CompactFlash_ID[index] = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_DATA);
00350     }
00351   }
00352 
00353   /* Update the PCCARD controller state */
00354   hpccard->State = HAL_PCCARD_STATE_READY;
00355 
00356   /* Process unlocked */
00357   __HAL_UNLOCK(hpccard);
00358 
00359   return HAL_OK;
00360 }
00361 
00362 /**
00363   * @brief  Read sector from PCCARD memory
00364   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00365   *                the configuration information for PCCARD module.
00366   * @param  pBuffer pointer to destination read buffer
00367   * @param  SectorAddress Sector address to read
00368   * @param  pStatus pointer to PCCARD status
00369   * @retval HAL status
00370   */
00371 HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress,
00372                                          uint8_t *pStatus)
00373 {
00374   uint32_t timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR, index = 0U;
00375   uint8_t status = 0;
00376 
00377   /* Process Locked */
00378   __HAL_LOCK(hpccard);
00379 
00380   /* Check the PCCARD controller state */
00381   if (hpccard->State == HAL_PCCARD_STATE_BUSY)
00382   {
00383     return HAL_BUSY;
00384   }
00385 
00386   /* Update the PCCARD controller state */
00387   hpccard->State = HAL_PCCARD_STATE_BUSY;
00388 
00389   /* Initialize PCCARD status */
00390   *pStatus = PCCARD_READY;
00391 
00392   /* Set the parameters to write a sector */
00393   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x0000;
00394   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT)  = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
00395   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD)    = (uint16_t)0xE4A0;
00396 
00397   do
00398   {
00399     /* wait till the Status = 0x80 */
00400     status =  *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00401     timeout--;
00402   } while ((status == 0x80U) && timeout);
00403 
00404   if (timeout == 0U)
00405   {
00406     *pStatus = PCCARD_TIMEOUT_ERROR;
00407   }
00408 
00409   timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR;
00410 
00411   do
00412   {
00413     /* wait till the Status = PCCARD_STATUS_OK */
00414     status =  *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00415     timeout--;
00416   } while ((status != PCCARD_STATUS_OK) && timeout);
00417 
00418   if (timeout == 0U)
00419   {
00420     *pStatus = PCCARD_TIMEOUT_ERROR;
00421   }
00422 
00423   /* Read bytes */
00424   for (; index < PCCARD_SECTOR_SIZE; index++)
00425   {
00426     *(uint16_t *)pBuffer++ = *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR);
00427   }
00428 
00429   /* Update the PCCARD controller state */
00430   hpccard->State = HAL_PCCARD_STATE_READY;
00431 
00432   /* Process unlocked */
00433   __HAL_UNLOCK(hpccard);
00434 
00435   return HAL_OK;
00436 }
00437 
00438 
00439 /**
00440   * @brief  Write sector to PCCARD memory
00441   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00442   *                the configuration information for PCCARD module.
00443   * @param  pBuffer pointer to source write buffer
00444   * @param  SectorAddress Sector address to write
00445   * @param  pStatus pointer to PCCARD status
00446   * @retval HAL status
00447   */
00448 HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress,
00449                                           uint8_t *pStatus)
00450 {
00451   uint32_t timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR, index = 0U;
00452   uint8_t status = 0;
00453 
00454   /* Process Locked */
00455   __HAL_LOCK(hpccard);
00456 
00457   /* Check the PCCARD controller state */
00458   if (hpccard->State == HAL_PCCARD_STATE_BUSY)
00459   {
00460     return HAL_BUSY;
00461   }
00462 
00463   /* Update the PCCARD controller state */
00464   hpccard->State = HAL_PCCARD_STATE_BUSY;
00465 
00466   /* Initialize PCCARD status */
00467   *pStatus = PCCARD_READY;
00468 
00469   /* Set the parameters to write a sector */
00470   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x0000;
00471   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT)  = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
00472   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD)    = (uint16_t)0x30A0;
00473 
00474   do
00475   {
00476     /* Wait till the Status = PCCARD_STATUS_OK */
00477     status =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00478     timeout--;
00479   } while ((status != PCCARD_STATUS_OK) && timeout);
00480 
00481   if (timeout == 0U)
00482   {
00483     *pStatus = PCCARD_TIMEOUT_ERROR;
00484   }
00485 
00486   /* Write bytes */
00487   for (; index < PCCARD_SECTOR_SIZE; index++)
00488   {
00489     *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR) = *(uint16_t *)pBuffer++;
00490   }
00491 
00492   do
00493   {
00494     /* Wait till the Status = PCCARD_STATUS_WRITE_OK */
00495     status =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00496     timeout--;
00497   } while ((status != PCCARD_STATUS_WRITE_OK) && timeout);
00498 
00499   if (timeout == 0U)
00500   {
00501     *pStatus = PCCARD_TIMEOUT_ERROR;
00502   }
00503 
00504   /* Update the PCCARD controller state */
00505   hpccard->State = HAL_PCCARD_STATE_READY;
00506 
00507   /* Process unlocked */
00508   __HAL_UNLOCK(hpccard);
00509 
00510   return HAL_OK;
00511 }
00512 
00513 
00514 /**
00515   * @brief  Erase sector from PCCARD memory
00516   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00517   *                the configuration information for PCCARD module.
00518   * @param  SectorAddress Sector address to erase
00519   * @param  pStatus pointer to PCCARD status
00520   * @retval HAL status
00521   */
00522 HAL_StatusTypeDef  HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus)
00523 {
00524   uint32_t timeout = PCCARD_TIMEOUT_ERASE_SECTOR;
00525   uint8_t status = 0;
00526 
00527   /* Process Locked */
00528   __HAL_LOCK(hpccard);
00529 
00530   /* Check the PCCARD controller state */
00531   if (hpccard->State == HAL_PCCARD_STATE_BUSY)
00532   {
00533     return HAL_BUSY;
00534   }
00535 
00536   /* Update the PCCARD controller state */
00537   hpccard->State = HAL_PCCARD_STATE_BUSY;
00538 
00539   /* Initialize PCCARD status */
00540   *pStatus = PCCARD_READY;
00541 
00542   /* Set the parameters to write a sector */
00543   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_LOW)  = 0x00;
00544   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = 0x00;
00545   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_NUMBER) = SectorAddress;
00546   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT)  = 0x01;
00547   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CARD_HEAD)     = 0xA0;
00548   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD)    = ATA_ERASE_SECTOR_CMD;
00549 
00550   /* wait till the PCCARD is ready */
00551   status =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00552 
00553   while ((status != PCCARD_STATUS_WRITE_OK) && timeout)
00554   {
00555     status =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00556     timeout--;
00557   }
00558 
00559   if (timeout == 0U)
00560   {
00561     *pStatus = PCCARD_TIMEOUT_ERROR;
00562   }
00563 
00564   /* Check the PCCARD controller state */
00565   hpccard->State = HAL_PCCARD_STATE_READY;
00566 
00567   /* Process unlocked */
00568   __HAL_UNLOCK(hpccard);
00569 
00570   return HAL_OK;
00571 }
00572 
00573 /**
00574   * @brief  Reset the PCCARD memory
00575   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00576   *                the configuration information for PCCARD module.
00577   * @retval HAL status
00578   */
00579 HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard)
00580 {
00581   /* Process Locked */
00582   __HAL_LOCK(hpccard);
00583 
00584   /* Check the PCCARD controller state */
00585   if (hpccard->State == HAL_PCCARD_STATE_BUSY)
00586   {
00587     return HAL_BUSY;
00588   }
00589 
00590   /* Provide a SW reset and Read and verify the:
00591    - PCCard Configuration Option Register at address 0x98000200 --> 0x80
00592    - Card Configuration and Status Register at address 0x98000202 --> 0x00
00593    - Pin Replacement Register at address 0x98000204 --> 0x0C
00594    - Socket and Copy Register at address 0x98000206 --> 0x00
00595   */
00596 
00597   /* Check the PCCARD controller state */
00598   hpccard->State = HAL_PCCARD_STATE_BUSY;
00599 
00600   *(__IO uint8_t *)(PCCARD_ATTRIBUTE_SPACE_ADDRESS | ATA_CARD_CONFIGURATION) = 0x01;
00601 
00602   /* Check the PCCARD controller state */
00603   hpccard->State = HAL_PCCARD_STATE_READY;
00604 
00605   /* Process unlocked */
00606   __HAL_UNLOCK(hpccard);
00607 
00608   return HAL_OK;
00609 }
00610 
00611 /**
00612   * @brief  This function handles PCCARD device interrupt request.
00613   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00614   *                the configuration information for PCCARD module.
00615   * @retval HAL status
00616   */
00617 void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard)
00618 {
00619   /* Check PCCARD interrupt Rising edge flag */
00620   if (__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE))
00621   {
00622     /* PCCARD interrupt callback*/
00623 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
00624     hpccard->ItCallback(hpccard);
00625 #else
00626     HAL_PCCARD_ITCallback(hpccard);
00627 #endif
00628 
00629     /* Clear PCCARD interrupt Rising edge pending bit */
00630     __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE);
00631   }
00632 
00633   /* Check PCCARD interrupt Level flag */
00634   if (__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_LEVEL))
00635   {
00636     /* PCCARD interrupt callback*/
00637 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
00638     hpccard->ItCallback(hpccard);
00639 #else
00640     HAL_PCCARD_ITCallback(hpccard);
00641 #endif
00642 
00643     /* Clear PCCARD interrupt Level pending bit */
00644     __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_LEVEL);
00645   }
00646 
00647   /* Check PCCARD interrupt Falling edge flag */
00648   if (__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE))
00649   {
00650     /* PCCARD interrupt callback*/
00651 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
00652     hpccard->ItCallback(hpccard);
00653 #else
00654     HAL_PCCARD_ITCallback(hpccard);
00655 #endif
00656 
00657     /* Clear PCCARD interrupt Falling edge pending bit */
00658     __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE);
00659   }
00660 
00661   /* Check PCCARD interrupt FIFO empty flag */
00662   if (__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FEMPT))
00663   {
00664     /* PCCARD interrupt callback*/
00665 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
00666     hpccard->ItCallback(hpccard);
00667 #else
00668     HAL_PCCARD_ITCallback(hpccard);
00669 #endif
00670 
00671     /* Clear PCCARD interrupt FIFO empty pending bit */
00672     __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FEMPT);
00673   }
00674 }
00675 
00676 /**
00677   * @brief  PCCARD interrupt feature callback
00678   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00679   *                the configuration information for PCCARD module.
00680   * @retval None
00681   */
00682 __weak void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard)
00683 {
00684   /* Prevent unused argument(s) compilation warning */
00685   UNUSED(hpccard);
00686   /* NOTE : This function Should not be modified, when the callback is needed,
00687             the HAL_PCCARD_ITCallback could be implemented in the user file
00688    */
00689 }
00690 
00691 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
00692 /**
00693   * @brief  Register a User PCCARD Callback
00694   *         To be used instead of the weak (surcharged) predefined callback
00695   * @param hpccard : PCCARD handle
00696   * @param CallbackId : ID of the callback to be registered
00697   *        This parameter can be one of the following values:
00698   *          @arg @ref HAL_PCCARD_MSP_INIT_CB_ID       PCCARD MspInit callback ID
00699   *          @arg @ref HAL_PCCARD_MSP_DEINIT_CB_ID     PCCARD MspDeInit callback ID
00700   *          @arg @ref HAL_PCCARD_IT_CB_ID             PCCARD IT callback ID
00701   * @param pCallback : pointer to the Callback function
00702   * @retval status
00703   */
00704 HAL_StatusTypeDef HAL_PCCARD_RegisterCallback(PCCARD_HandleTypeDef *hpccard, HAL_PCCARD_CallbackIDTypeDef CallbackId,
00705                                               pPCCARD_CallbackTypeDef pCallback)
00706 {
00707   HAL_StatusTypeDef status = HAL_OK;
00708 
00709   if (pCallback == NULL)
00710   {
00711     return HAL_ERROR;
00712   }
00713 
00714   /* Process locked */
00715   __HAL_LOCK(hpccard);
00716 
00717   if (hpccard->State == HAL_PCCARD_STATE_READY)
00718   {
00719     switch (CallbackId)
00720     {
00721       case HAL_PCCARD_MSP_INIT_CB_ID :
00722         hpccard->MspInitCallback = pCallback;
00723         break;
00724       case HAL_PCCARD_MSP_DEINIT_CB_ID :
00725         hpccard->MspDeInitCallback = pCallback;
00726         break;
00727       case HAL_PCCARD_IT_CB_ID :
00728         hpccard->ItCallback = pCallback;
00729         break;
00730       default :
00731         /* update return status */
00732         status =  HAL_ERROR;
00733         break;
00734     }
00735   }
00736   else if (hpccard->State == HAL_PCCARD_STATE_RESET)
00737   {
00738     switch (CallbackId)
00739     {
00740       case HAL_PCCARD_MSP_INIT_CB_ID :
00741         hpccard->MspInitCallback = pCallback;
00742         break;
00743       case HAL_PCCARD_MSP_DEINIT_CB_ID :
00744         hpccard->MspDeInitCallback = pCallback;
00745         break;
00746       default :
00747         /* update return status */
00748         status =  HAL_ERROR;
00749         break;
00750     }
00751   }
00752   else
00753   {
00754     /* update return status */
00755     status =  HAL_ERROR;
00756   }
00757 
00758   /* Release Lock */
00759   __HAL_UNLOCK(hpccard);
00760   return status;
00761 }
00762 
00763 /**
00764   * @brief  Unregister a User PCCARD Callback
00765   *         PCCARD Callback is redirected to the weak (surcharged) predefined callback
00766   * @param hpccard : PCCARD handle
00767   * @param CallbackId : ID of the callback to be unregistered
00768   *        This parameter can be one of the following values:
00769   *          @arg @ref HAL_PCCARD_MSP_INIT_CB_ID       PCCARD MspInit callback ID
00770   *          @arg @ref HAL_PCCARD_MSP_DEINIT_CB_ID     PCCARD MspDeInit callback ID
00771   *          @arg @ref HAL_PCCARD_IT_CB_ID             PCCARD IT callback ID
00772   * @retval status
00773   */
00774 HAL_StatusTypeDef HAL_PCCARD_UnRegisterCallback(PCCARD_HandleTypeDef *hpccard, HAL_PCCARD_CallbackIDTypeDef CallbackId)
00775 {
00776   HAL_StatusTypeDef status = HAL_OK;
00777 
00778   /* Process locked */
00779   __HAL_LOCK(hpccard);
00780 
00781   if (hpccard->State == HAL_PCCARD_STATE_READY)
00782   {
00783     switch (CallbackId)
00784     {
00785       case HAL_PCCARD_MSP_INIT_CB_ID :
00786         hpccard->MspInitCallback = HAL_PCCARD_MspInit;
00787         break;
00788       case HAL_PCCARD_MSP_DEINIT_CB_ID :
00789         hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
00790         break;
00791       case HAL_PCCARD_IT_CB_ID :
00792         hpccard->ItCallback = HAL_PCCARD_ITCallback;
00793         break;
00794       default :
00795         /* update return status */
00796         status =  HAL_ERROR;
00797         break;
00798     }
00799   }
00800   else if (hpccard->State == HAL_PCCARD_STATE_RESET)
00801   {
00802     switch (CallbackId)
00803     {
00804       case HAL_PCCARD_MSP_INIT_CB_ID :
00805         hpccard->MspInitCallback = HAL_PCCARD_MspInit;
00806         break;
00807       case HAL_PCCARD_MSP_DEINIT_CB_ID :
00808         hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
00809         break;
00810       default :
00811         /* update return status */
00812         status =  HAL_ERROR;
00813         break;
00814     }
00815   }
00816   else
00817   {
00818     /* update return status */
00819     status =  HAL_ERROR;
00820   }
00821 
00822   /* Release Lock */
00823   __HAL_UNLOCK(hpccard);
00824   return status;
00825 }
00826 #endif
00827 
00828 /**
00829   * @}
00830   */
00831 
00832 /** @defgroup PCCARD_Exported_Functions_Group3 State functions
00833   *  @brief   Peripheral State functions
00834   *
00835 @verbatim
00836   ==============================================================================
00837                       ##### PCCARD State functions #####
00838   ==============================================================================
00839   [..]
00840     This subsection permits to get in run-time the status of the PCCARD controller
00841     and the data flow.
00842 
00843 @endverbatim
00844   * @{
00845   */
00846 
00847 /**
00848   * @brief  return the PCCARD controller state
00849   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00850   *                the configuration information for PCCARD module.
00851   * @retval HAL state
00852   */
00853 HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard)
00854 {
00855   return hpccard->State;
00856 }
00857 
00858 /**
00859   * @brief  Get the compact flash memory status
00860   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00861   *                the configuration information for PCCARD module.
00862   * @retval New status of the PCCARD operation. This parameter can be:
00863   *          - CompactFlash_TIMEOUT_ERROR: when the previous operation generate
00864   *            a Timeout error
00865   *          - CompactFlash_READY: when memory is ready for the next operation
00866   */
00867 HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard)
00868 {
00869   uint32_t timeout = PCCARD_TIMEOUT_STATUS, status_pccard = 0U;
00870 
00871   /* Check the PCCARD controller state */
00872   if (hpccard->State == HAL_PCCARD_STATE_BUSY)
00873   {
00874     return HAL_PCCARD_STATUS_ONGOING;
00875   }
00876 
00877   status_pccard =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00878 
00879   while ((status_pccard == PCCARD_BUSY) && timeout)
00880   {
00881     status_pccard =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00882     timeout--;
00883   }
00884 
00885   if (timeout == 0U)
00886   {
00887     status_pccard =  PCCARD_TIMEOUT_ERROR;
00888   }
00889 
00890   /* Return the operation status */
00891   return (HAL_PCCARD_StatusTypeDef) status_pccard;
00892 }
00893 
00894 /**
00895   * @brief  Reads the Compact Flash memory status using the Read status command
00896   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
00897   *                the configuration information for PCCARD module.
00898   * @retval The status of the Compact Flash memory. This parameter can be:
00899   *          - CompactFlash_BUSY: when memory is busy
00900   *          - CompactFlash_READY: when memory is ready for the next operation
00901   *          - CompactFlash_ERROR: when the previous operation generates error
00902   */
00903 HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard)
00904 {
00905   uint8_t data = 0U, status_pccard = PCCARD_BUSY;
00906 
00907   /* Check the PCCARD controller state */
00908   if (hpccard->State == HAL_PCCARD_STATE_BUSY)
00909   {
00910     return HAL_PCCARD_STATUS_ONGOING;
00911   }
00912 
00913   /* Read status operation */
00914   data =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
00915 
00916   if ((data & PCCARD_TIMEOUT_ERROR) == PCCARD_TIMEOUT_ERROR)
00917   {
00918     status_pccard = PCCARD_TIMEOUT_ERROR;
00919   }
00920   else if ((data & PCCARD_READY) == PCCARD_READY)
00921   {
00922     status_pccard = PCCARD_READY;
00923   }
00924 
00925   return (HAL_PCCARD_StatusTypeDef) status_pccard;
00926 }
00927 
00928 /**
00929   * @}
00930   */
00931 
00932 /**
00933   * @}
00934   */
00935 
00936 /**
00937   * @}
00938   */
00939 
00940 #endif /* HAL_PCCARD_MODULE_ENABLED */
00941 
00942 /**
00943   * @}
00944   */
00945 
00946 #endif /* FMC_Bank4) || defined(FSMC_Bank4 */
00947 
00948 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/