1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_pccard.c
4   * @author  MCD Application Team
5   * @brief   PCCARD HAL module driver.
6   *          This file provides a generic firmware to drive PCCARD memories mounted
7   *          as external device.
8   *
9   @verbatim
10  ===============================================================================
11                         ##### How to use this driver #####
12  ===============================================================================
13    [..]
14      This driver is a generic layered driver which contains a set of APIs used to
15      control PCCARD/compact flash memories. It uses the FMC/FSMC layer functions
16      to interface with PCCARD devices. This driver is used for:
17 
18     (+) PCCARD/Compact Flash memory configuration sequence using the function
19         HAL_PCCARD_Init()/HAL_CF_Init() with control and timing parameters for
20         both common and attribute spaces.
21 
22     (+) Read PCCARD/Compact Flash memory maker and device IDs using the function
23         HAL_PCCARD_Read_ID()/HAL_CF_Read_ID(). The read information is stored in
24         the CompactFlash_ID structure declared by the function caller.
25 
26     (+) Access PCCARD/Compact Flash memory by read/write operations using the functions
27         HAL_PCCARD_Read_Sector()/ HAL_PCCARD_Write_Sector() -
28         HAL_CF_Read_Sector()/HAL_CF_Write_Sector(), to read/write sector.
29 
30     (+) Perform PCCARD/Compact Flash Reset chip operation using the function
31         HAL_PCCARD_Reset()/HAL_CF_Reset.
32 
33     (+) Perform PCCARD/Compact Flash erase sector operation using the function
34         HAL_PCCARD_Erase_Sector()/HAL_CF_Erase_Sector.
35 
36     (+) Read the PCCARD/Compact Flash status operation using the function
37         HAL_PCCARD_ReadStatus()/HAL_CF_ReadStatus().
38 
39     (+) You can monitor the PCCARD/Compact Flash  device HAL state by calling
40         the function HAL_PCCARD_GetState()/HAL_CF_GetState()
41 
42    [..]
43      (@) This driver is a set of generic APIs which handle standard PCCARD/compact flash
44          operations. If a PCCARD/Compact Flash device contains different operations
45          and/or implementations, it should be implemented separately.
46 
47       *** Callback registration ***
48     =============================================
49     [..]
50       The compilation define  USE_HAL_PCCARD_REGISTER_CALLBACKS when set to 1
51       allows the user to configure dynamically the driver callbacks.
52 
53       Use Functions @ref HAL_PCCARD_RegisterCallback() to register a user callback,
54       it allows to register following callbacks:
55         (+) MspInitCallback    : PCCARD MspInit.
56         (+) MspDeInitCallback  : PCCARD MspDeInit.
57       This function takes as parameters the HAL peripheral handle, the Callback ID
58       and a pointer to the user callback function.
59 
60       Use function @ref HAL_PCCARD_UnRegisterCallback() to reset a callback to the default
61       weak (surcharged) function. It allows to reset following callbacks:
62         (+) MspInitCallback    : PCCARD MspInit.
63         (+) MspDeInitCallback  : PCCARD MspDeInit.
64       This function) takes as parameters the HAL peripheral handle and the Callback ID.
65 
66       By default, after the @ref HAL_PCCARD_Init and if the state is HAL_PCCARD_STATE_RESET
67       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
68       Exception done for MspInit and MspDeInit callbacks that are respectively
69       reset to the legacy weak (surcharged) functions in the @ref HAL_PCCARD_Init
70       and @ref  HAL_PCCARD_DeInit only when these callbacks are null (not registered beforehand).
71       If not, MspInit or MspDeInit are not null, the @ref HAL_PCCARD_Init and @ref HAL_PCCARD_DeInit
72       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
73 
74       Callbacks can be registered/unregistered in READY state only.
75       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
76       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
77       during the Init/DeInit.
78       In that case first register the MspInit/MspDeInit user callbacks
79       using @ref HAL_PCCARD_RegisterCallback before calling @ref HAL_PCCARD_DeInit
80       or @ref HAL_PCCARD_Init function.
81 
82       When The compilation define USE_HAL_PCCARD_REGISTER_CALLBACKS is set to 0 or
83       not defined, the callback registering feature is not available
84       and weak (surcharged) callbacks are used.
85 
86   @endverbatim
87   ******************************************************************************
88   * @attention
89   *
90   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
91   * All rights reserved.</center></h2>
92   *
93   * This software component is licensed by ST under BSD 3-Clause license,
94   * the "License"; You may not use this file except in compliance with the
95   * License. You may obtain a copy of the License at:
96   *                        opensource.org/licenses/BSD-3-Clause
97   *
98   ******************************************************************************
99   */
100 
101 /* Includes ------------------------------------------------------------------*/
102 #include "stm32f4xx_hal.h"
103 
104 /** @addtogroup STM32F4xx_HAL_Driver
105   * @{
106   */
107 
108 #ifdef HAL_PCCARD_MODULE_ENABLED
109 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
110     defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
111 /** @defgroup PCCARD PCCARD
112   * @brief PCCARD HAL module driver
113   * @{
114   */
115 /* Private typedef -----------------------------------------------------------*/
116 /* Private define ------------------------------------------------------------*/
117 
118 /** @defgroup PCCARD_Private_Defines PCCARD Private Defines
119   * @{
120   */
121 #define PCCARD_TIMEOUT_READ_ID                 0x0000FFFFU
122 #define PCCARD_TIMEOUT_READ_WRITE_SECTOR       0x0000FFFFU
123 #define PCCARD_TIMEOUT_ERASE_SECTOR            0x00000400U
124 #define PCCARD_TIMEOUT_STATUS                  0x01000000U
125 
126 #define PCCARD_STATUS_OK                       (uint8_t)0x58
127 #define PCCARD_STATUS_WRITE_OK                 (uint8_t)0x50
128 /**
129   * @}
130   */
131 
132 /* Private macro -------------------------------------------------------------*/
133 /* Private variables ---------------------------------------------------------*/
134 /* Private function ----------------------------------------------------------*/
135 /* Exported functions --------------------------------------------------------*/
136 /** @defgroup PCCARD_Exported_Functions PCCARD Exported Functions
137   * @{
138   */
139 
140 /** @defgroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
141   * @brief    Initialization and Configuration functions
142   *
143   @verbatim
144   ==============================================================================
145           ##### PCCARD Initialization and de-initialization functions #####
146   ==============================================================================
147   [..]
148     This section provides functions allowing to initialize/de-initialize
149     the PCCARD memory
150 
151 @endverbatim
152   * @{
153   */
154 
155 /**
156   * @brief  Perform the PCCARD memory Initialization sequence
157   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
158   *                the configuration information for PCCARD module.
159   * @param  ComSpaceTiming Common space timing structure
160   * @param  AttSpaceTiming Attribute space timing structure
161   * @param  IOSpaceTiming IO space timing structure
162   * @retval HAL status
163   */
HAL_PCCARD_Init(PCCARD_HandleTypeDef * hpccard,FMC_NAND_PCC_TimingTypeDef * ComSpaceTiming,FMC_NAND_PCC_TimingTypeDef * AttSpaceTiming,FMC_NAND_PCC_TimingTypeDef * IOSpaceTiming)164 HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FMC_NAND_PCC_TimingTypeDef *ComSpaceTiming, FMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FMC_NAND_PCC_TimingTypeDef *IOSpaceTiming)
165 {
166   /* Check the PCCARD controller state */
167   if(hpccard == NULL)
168   {
169      return HAL_ERROR;
170   }
171 
172   if(hpccard->State == HAL_PCCARD_STATE_RESET)
173   {
174     /* Allocate lock resource and initialize it */
175     hpccard->Lock = HAL_UNLOCKED;
176 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
177     if(hpccard->MspInitCallback == NULL)
178     {
179       hpccard->MspInitCallback = HAL_PCCARD_MspInit;
180     }
181     hpccard->ItCallback = HAL_PCCARD_ITCallback;
182 
183     /* Init the low level hardware */
184     hpccard->MspInitCallback(hpccard);
185 #else
186     /* Initialize the low level hardware (MSP) */
187     HAL_PCCARD_MspInit(hpccard);
188 #endif
189   }
190 
191   /* Initialize the PCCARD state */
192   hpccard->State = HAL_PCCARD_STATE_BUSY;
193 
194   /* Initialize PCCARD control Interface */
195   FMC_PCCARD_Init(hpccard->Instance, &(hpccard->Init));
196 
197   /* Init PCCARD common space timing Interface */
198   FMC_PCCARD_CommonSpace_Timing_Init(hpccard->Instance, ComSpaceTiming);
199 
200   /* Init PCCARD attribute space timing Interface */
201   FMC_PCCARD_AttributeSpace_Timing_Init(hpccard->Instance, AttSpaceTiming);
202 
203   /* Init PCCARD IO space timing Interface */
204   FMC_PCCARD_IOSpace_Timing_Init(hpccard->Instance, IOSpaceTiming);
205 
206   /* Enable the PCCARD device */
207   __FMC_PCCARD_ENABLE(hpccard->Instance);
208 
209   /* Update the PCCARD state */
210   hpccard->State = HAL_PCCARD_STATE_READY;
211 
212   return HAL_OK;
213 
214 }
215 
216 /**
217   * @brief  Perform the PCCARD memory De-initialization sequence
218   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
219   *                the configuration information for PCCARD module.
220   * @retval HAL status
221   */
HAL_PCCARD_DeInit(PCCARD_HandleTypeDef * hpccard)222 HAL_StatusTypeDef  HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard)
223 {
224 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
225   if(hpccard->MspDeInitCallback == NULL)
226   {
227     hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
228   }
229 
230   /* DeInit the low level hardware */
231   hpccard->MspDeInitCallback(hpccard);
232 #else
233   /* De-Initialize the low level hardware (MSP) */
234   HAL_PCCARD_MspDeInit(hpccard);
235 #endif
236 
237   /* Configure the PCCARD registers with their reset values */
238   FMC_PCCARD_DeInit(hpccard->Instance);
239 
240   /* Update the PCCARD controller state */
241   hpccard->State = HAL_PCCARD_STATE_RESET;
242 
243   /* Release Lock */
244   __HAL_UNLOCK(hpccard);
245 
246   return HAL_OK;
247 }
248 
249 /**
250   * @brief  PCCARD MSP Init
251   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
252   *                the configuration information for PCCARD module.
253   * @retval None
254   */
HAL_PCCARD_MspInit(PCCARD_HandleTypeDef * hpccard)255 __weak void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard)
256 {
257   /* Prevent unused argument(s) compilation warning */
258   UNUSED(hpccard);
259   /* NOTE : This function Should not be modified, when the callback is needed,
260             the HAL_PCCARD_MspInit could be implemented in the user file
261    */
262 }
263 
264 /**
265   * @brief  PCCARD MSP DeInit
266   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
267   *                the configuration information for PCCARD module.
268   * @retval None
269   */
HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef * hpccard)270 __weak void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard)
271 {
272   /* Prevent unused argument(s) compilation warning */
273   UNUSED(hpccard);
274   /* NOTE : This function Should not be modified, when the callback is needed,
275             the HAL_PCCARD_MspDeInit could be implemented in the user file
276    */
277 }
278 
279 /**
280   * @}
281   */
282 
283 /** @defgroup PCCARD_Exported_Functions_Group2 Input and Output functions
284   * @brief    Input Output and memory control functions
285   *
286   @verbatim
287   ==============================================================================
288                     ##### PCCARD Input and Output functions #####
289   ==============================================================================
290   [..]
291     This section provides functions allowing to use and control the PCCARD memory
292 
293 @endverbatim
294   * @{
295   */
296 
297 /**
298   * @brief  Read Compact Flash's ID.
299   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
300   *                the configuration information for PCCARD module.
301   * @param  CompactFlash_ID Compact flash ID structure.
302   * @param  pStatus pointer to compact flash status
303   * @retval HAL status
304   *
305   */
HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef * hpccard,uint8_t CompactFlash_ID[],uint8_t * pStatus)306 HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus)
307 {
308   uint32_t timeout = PCCARD_TIMEOUT_READ_ID, index = 0U;
309   uint8_t status = 0;
310 
311   /* Process Locked */
312   __HAL_LOCK(hpccard);
313 
314   /* Check the PCCARD controller state */
315   if(hpccard->State == HAL_PCCARD_STATE_BUSY)
316   {
317      return HAL_BUSY;
318   }
319 
320   /* Update the PCCARD controller state */
321   hpccard->State = HAL_PCCARD_STATE_BUSY;
322 
323   /* Initialize the PCCARD status */
324   *pStatus = PCCARD_READY;
325 
326   /* Send the Identify Command */
327   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD)  = 0xECEC;
328 
329   /* Read PCCARD IDs and timeout treatment */
330   do
331   {
332      /* Read the PCCARD status */
333      status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
334 
335      timeout--;
336   }while((status != PCCARD_STATUS_OK) && timeout);
337 
338   if(timeout == 0U)
339   {
340     *pStatus = PCCARD_TIMEOUT_ERROR;
341   }
342   else
343   {
344      /* Read PCCARD ID bytes */
345     for(index = 0U; index < 16U; index++)
346     {
347       CompactFlash_ID[index] = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_DATA);
348     }
349   }
350 
351   /* Update the PCCARD controller state */
352   hpccard->State = HAL_PCCARD_STATE_READY;
353 
354   /* Process unlocked */
355   __HAL_UNLOCK(hpccard);
356 
357   return HAL_OK;
358 }
359 
360 /**
361   * @brief  Read sector from PCCARD memory
362   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
363   *                the configuration information for PCCARD module.
364   * @param  pBuffer pointer to destination read buffer
365   * @param  SectorAddress Sector address to read
366   * @param  pStatus pointer to PCCARD status
367   * @retval HAL status
368   */
HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef * hpccard,uint16_t * pBuffer,uint16_t SectorAddress,uint8_t * pStatus)369 HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus)
370 {
371   uint32_t timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR, index = 0U;
372   uint8_t status = 0;
373 
374   /* Process Locked */
375   __HAL_LOCK(hpccard);
376 
377   /* Check the PCCARD controller state */
378   if(hpccard->State == HAL_PCCARD_STATE_BUSY)
379   {
380      return HAL_BUSY;
381   }
382 
383   /* Update the PCCARD controller state */
384   hpccard->State = HAL_PCCARD_STATE_BUSY;
385 
386   /* Initialize PCCARD status */
387   *pStatus = PCCARD_READY;
388 
389   /* Set the parameters to write a sector */
390   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x00;
391   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT)  = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
392   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD)    = (uint16_t)0xE4A0;
393 
394   do
395   {
396     /* wait till the Status = 0x80 */
397     status =  *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
398     timeout--;
399   }while((status == 0x80) && timeout);
400 
401   if(timeout == 0U)
402   {
403     *pStatus = PCCARD_TIMEOUT_ERROR;
404   }
405 
406   timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR;
407 
408   do
409   {
410     /* wait till the Status = PCCARD_STATUS_OK */
411     status =  *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
412     timeout--;
413   }while((status != PCCARD_STATUS_OK) && timeout);
414 
415   if(timeout == 0U)
416   {
417     *pStatus = PCCARD_TIMEOUT_ERROR;
418   }
419 
420   /* Read bytes */
421   for(; index < PCCARD_SECTOR_SIZE; index++)
422   {
423     *(uint16_t *)pBuffer++ = *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR);
424   }
425 
426   /* Update the PCCARD controller state */
427   hpccard->State = HAL_PCCARD_STATE_READY;
428 
429   /* Process unlocked */
430   __HAL_UNLOCK(hpccard);
431 
432   return HAL_OK;
433 }
434 
435 
436 /**
437   * @brief  Write sector to PCCARD memory
438   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
439   *                the configuration information for PCCARD module.
440   * @param  pBuffer pointer to source write buffer
441   * @param  SectorAddress Sector address to write
442   * @param  pStatus pointer to PCCARD status
443   * @retval HAL status
444   */
HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef * hpccard,uint16_t * pBuffer,uint16_t SectorAddress,uint8_t * pStatus)445 HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress,  uint8_t *pStatus)
446 {
447   uint32_t timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR, index = 0U;
448   uint8_t status = 0;
449 
450   /* Process Locked */
451   __HAL_LOCK(hpccard);
452 
453   /* Check the PCCARD controller state */
454   if(hpccard->State == HAL_PCCARD_STATE_BUSY)
455   {
456      return HAL_BUSY;
457   }
458 
459   /* Update the PCCARD controller state */
460   hpccard->State = HAL_PCCARD_STATE_BUSY;
461 
462   /* Initialize PCCARD status */
463   *pStatus = PCCARD_READY;
464 
465   /* Set the parameters to write a sector */
466   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x00;
467   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT)  = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
468   *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD)    = (uint16_t)0x30A0;
469 
470   do
471   {
472     /* Wait till the Status = PCCARD_STATUS_OK */
473     status =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
474     timeout--;
475   }while((status != PCCARD_STATUS_OK) && timeout);
476 
477   if(timeout == 0U)
478   {
479     *pStatus = PCCARD_TIMEOUT_ERROR;
480   }
481 
482   /* Write bytes */
483   for(; index < PCCARD_SECTOR_SIZE; index++)
484   {
485     *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR) = *(uint16_t *)pBuffer++;
486   }
487 
488   do
489   {
490     /* Wait till the Status = PCCARD_STATUS_WRITE_OK */
491     status =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
492     timeout--;
493   }while((status != PCCARD_STATUS_WRITE_OK) && timeout);
494 
495   if(timeout == 0U)
496   {
497     *pStatus = PCCARD_TIMEOUT_ERROR;
498   }
499 
500   /* Update the PCCARD controller state */
501   hpccard->State = HAL_PCCARD_STATE_READY;
502 
503   /* Process unlocked */
504   __HAL_UNLOCK(hpccard);
505 
506   return HAL_OK;
507 }
508 
509 
510 /**
511   * @brief  Erase sector from PCCARD memory
512   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
513   *                the configuration information for PCCARD module.
514   * @param  SectorAddress Sector address to erase
515   * @param  pStatus pointer to PCCARD status
516   * @retval HAL status
517   */
HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef * hpccard,uint16_t SectorAddress,uint8_t * pStatus)518 HAL_StatusTypeDef  HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus)
519 {
520   uint32_t timeout = PCCARD_TIMEOUT_ERASE_SECTOR;
521   uint8_t status = 0;
522 
523   /* Process Locked */
524   __HAL_LOCK(hpccard);
525 
526   /* Check the PCCARD controller state */
527   if(hpccard->State == HAL_PCCARD_STATE_BUSY)
528   {
529      return HAL_BUSY;
530   }
531 
532   /* Update the PCCARD controller state */
533   hpccard->State = HAL_PCCARD_STATE_BUSY;
534 
535   /* Initialize PCCARD status */
536   *pStatus = PCCARD_READY;
537 
538   /* Set the parameters to write a sector */
539   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_LOW)  = 0x00;
540   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = 0x00;
541   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_NUMBER) = SectorAddress;
542   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT)  = 0x01;
543   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CARD_HEAD)     = 0xA0;
544   *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD)    = ATA_ERASE_SECTOR_CMD;
545 
546   /* wait till the PCCARD is ready */
547   status =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
548 
549   while((status != PCCARD_STATUS_WRITE_OK) && timeout)
550   {
551     status =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
552     timeout--;
553   }
554 
555   if(timeout == 0U)
556   {
557     *pStatus = PCCARD_TIMEOUT_ERROR;
558   }
559 
560   /* Check the PCCARD controller state */
561   hpccard->State = HAL_PCCARD_STATE_READY;
562 
563   /* Process unlocked */
564   __HAL_UNLOCK(hpccard);
565 
566   return HAL_OK;
567 }
568 
569 /**
570   * @brief  Reset the PCCARD memory
571   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
572   *                the configuration information for PCCARD module.
573   * @retval HAL status
574   */
HAL_PCCARD_Reset(PCCARD_HandleTypeDef * hpccard)575 HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard)
576 {
577   /* Process Locked */
578   __HAL_LOCK(hpccard);
579 
580   /* Check the PCCARD controller state */
581   if(hpccard->State == HAL_PCCARD_STATE_BUSY)
582   {
583      return HAL_BUSY;
584   }
585 
586   /* Provide a SW reset and Read and verify the:
587    - PCCard Configuration Option Register at address 0x98000200 --> 0x80
588    - Card Configuration and Status Register at address 0x98000202 --> 0x00
589    - Pin Replacement Register at address 0x98000204 --> 0x0C
590    - Socket and Copy Register at address 0x98000206 --> 0x00
591   */
592 
593   /* Check the PCCARD controller state */
594   hpccard->State = HAL_PCCARD_STATE_BUSY;
595 
596   *(__IO uint8_t *)(PCCARD_ATTRIBUTE_SPACE_ADDRESS | ATA_CARD_CONFIGURATION ) = 0x01;
597 
598   /* Check the PCCARD controller state */
599   hpccard->State = HAL_PCCARD_STATE_READY;
600 
601   /* Process unlocked */
602   __HAL_UNLOCK(hpccard);
603 
604   return HAL_OK;
605 }
606 
607 /**
608   * @brief  This function handles PCCARD device interrupt request.
609   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
610   *                the configuration information for PCCARD module.
611   * @retval HAL status
612 */
HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef * hpccard)613 void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard)
614 {
615   /* Check PCCARD interrupt Rising edge flag */
616   if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE))
617   {
618     /* PCCARD interrupt callback*/
619 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
620     hpccard->ItCallback(hpccard);
621 #else
622     HAL_PCCARD_ITCallback(hpccard);
623 #endif
624 
625     /* Clear PCCARD interrupt Rising edge pending bit */
626     __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE);
627   }
628 
629   /* Check PCCARD interrupt Level flag */
630   if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_LEVEL))
631   {
632     /* PCCARD interrupt callback*/
633 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
634     hpccard->ItCallback(hpccard);
635 #else
636     HAL_PCCARD_ITCallback(hpccard);
637 #endif
638 
639     /* Clear PCCARD interrupt Level pending bit */
640     __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_LEVEL);
641   }
642 
643   /* Check PCCARD interrupt Falling edge flag */
644   if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE))
645   {
646     /* PCCARD interrupt callback*/
647 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
648     hpccard->ItCallback(hpccard);
649 #else
650     HAL_PCCARD_ITCallback(hpccard);
651 #endif
652 
653     /* Clear PCCARD interrupt Falling edge pending bit */
654     __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE);
655   }
656 
657   /* Check PCCARD interrupt FIFO empty flag */
658   if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FEMPT))
659   {
660     /* PCCARD interrupt callback*/
661 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
662     hpccard->ItCallback(hpccard);
663 #else
664     HAL_PCCARD_ITCallback(hpccard);
665 #endif
666 
667     /* Clear PCCARD interrupt FIFO empty pending bit */
668     __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FEMPT);
669   }
670 }
671 
672 /**
673   * @brief  PCCARD interrupt feature callback
674   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
675   *                the configuration information for PCCARD module.
676   * @retval None
677   */
HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef * hpccard)678 __weak void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard)
679 {
680   /* Prevent unused argument(s) compilation warning */
681   UNUSED(hpccard);
682   /* NOTE : This function Should not be modified, when the callback is needed,
683             the HAL_PCCARD_ITCallback could be implemented in the user file
684    */
685 }
686 
687 #if (USE_HAL_PCCARD_REGISTER_CALLBACKS == 1)
688 /**
689   * @brief  Register a User PCCARD Callback
690   *         To be used instead of the weak (surcharged) predefined callback
691   * @param hpccard : PCCARD handle
692   * @param CallbackId : ID of the callback to be registered
693   *        This parameter can be one of the following values:
694   *          @arg @ref HAL_PCCARD_MSP_INIT_CB_ID       PCCARD MspInit callback ID
695   *          @arg @ref HAL_PCCARD_MSP_DEINIT_CB_ID     PCCARD MspDeInit callback ID
696   *          @arg @ref HAL_PCCARD_IT_CB_ID             PCCARD IT callback ID
697   * @param pCallback : pointer to the Callback function
698   * @retval status
699   */
HAL_PCCARD_RegisterCallback(PCCARD_HandleTypeDef * hpccard,HAL_PCCARD_CallbackIDTypeDef CallbackId,pPCCARD_CallbackTypeDef pCallback)700 HAL_StatusTypeDef HAL_PCCARD_RegisterCallback (PCCARD_HandleTypeDef *hpccard, HAL_PCCARD_CallbackIDTypeDef CallbackId, pPCCARD_CallbackTypeDef pCallback)
701 {
702   HAL_StatusTypeDef status = HAL_OK;
703 
704   if(pCallback == NULL)
705   {
706     return HAL_ERROR;
707   }
708 
709   /* Process locked */
710   __HAL_LOCK(hpccard);
711 
712   if(hpccard->State == HAL_PCCARD_STATE_READY)
713   {
714     switch (CallbackId)
715     {
716     case HAL_PCCARD_MSP_INIT_CB_ID :
717       hpccard->MspInitCallback = pCallback;
718       break;
719     case HAL_PCCARD_MSP_DEINIT_CB_ID :
720       hpccard->MspDeInitCallback = pCallback;
721       break;
722     case HAL_PCCARD_IT_CB_ID :
723       hpccard->ItCallback = pCallback;
724       break;
725     default :
726       /* update return status */
727       status =  HAL_ERROR;
728       break;
729     }
730   }
731   else if(hpccard->State == HAL_PCCARD_STATE_RESET)
732   {
733     switch (CallbackId)
734     {
735     case HAL_PCCARD_MSP_INIT_CB_ID :
736       hpccard->MspInitCallback = pCallback;
737       break;
738     case HAL_PCCARD_MSP_DEINIT_CB_ID :
739       hpccard->MspDeInitCallback = pCallback;
740       break;
741     default :
742       /* update return status */
743       status =  HAL_ERROR;
744       break;
745     }
746   }
747   else
748   {
749     /* update return status */
750     status =  HAL_ERROR;
751   }
752 
753   /* Release Lock */
754   __HAL_UNLOCK(hpccard);
755   return status;
756 }
757 
758 /**
759   * @brief  Unregister a User PCCARD Callback
760   *         PCCARD Callback is redirected to the weak (surcharged) predefined callback
761   * @param hpccard : PCCARD handle
762   * @param CallbackId : ID of the callback to be unregistered
763   *        This parameter can be one of the following values:
764   *          @arg @ref HAL_PCCARD_MSP_INIT_CB_ID       PCCARD MspInit callback ID
765   *          @arg @ref HAL_PCCARD_MSP_DEINIT_CB_ID     PCCARD MspDeInit callback ID
766   *          @arg @ref HAL_PCCARD_IT_CB_ID             PCCARD IT callback ID
767   * @retval status
768   */
HAL_PCCARD_UnRegisterCallback(PCCARD_HandleTypeDef * hpccard,HAL_PCCARD_CallbackIDTypeDef CallbackId)769 HAL_StatusTypeDef HAL_PCCARD_UnRegisterCallback (PCCARD_HandleTypeDef *hpccard, HAL_PCCARD_CallbackIDTypeDef CallbackId)
770 {
771   HAL_StatusTypeDef status = HAL_OK;
772 
773   /* Process locked */
774   __HAL_LOCK(hpccard);
775 
776   if(hpccard->State == HAL_PCCARD_STATE_READY)
777   {
778     switch (CallbackId)
779     {
780     case HAL_PCCARD_MSP_INIT_CB_ID :
781       hpccard->MspInitCallback = HAL_PCCARD_MspInit;
782       break;
783     case HAL_PCCARD_MSP_DEINIT_CB_ID :
784       hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
785       break;
786     case HAL_PCCARD_IT_CB_ID :
787       hpccard->ItCallback = HAL_PCCARD_ITCallback;
788       break;
789     default :
790       /* update return status */
791       status =  HAL_ERROR;
792       break;
793     }
794   }
795   else if(hpccard->State == HAL_PCCARD_STATE_RESET)
796   {
797     switch (CallbackId)
798     {
799     case HAL_PCCARD_MSP_INIT_CB_ID :
800       hpccard->MspInitCallback = HAL_PCCARD_MspInit;
801       break;
802     case HAL_PCCARD_MSP_DEINIT_CB_ID :
803       hpccard->MspDeInitCallback = HAL_PCCARD_MspDeInit;
804       break;
805     default :
806       /* update return status */
807       status =  HAL_ERROR;
808       break;
809     }
810   }
811   else
812   {
813     /* update return status */
814     status =  HAL_ERROR;
815   }
816 
817   /* Release Lock */
818   __HAL_UNLOCK(hpccard);
819   return status;
820 }
821 #endif
822 
823 /**
824   * @}
825   */
826 
827 /** @defgroup PCCARD_Exported_Functions_Group3 State functions
828  *  @brief   Peripheral State functions
829  *
830 @verbatim
831   ==============================================================================
832                       ##### PCCARD State functions #####
833   ==============================================================================
834   [..]
835     This subsection permits to get in run-time the status of the PCCARD controller
836     and the data flow.
837 
838 @endverbatim
839   * @{
840   */
841 
842 /**
843   * @brief  return the PCCARD controller state
844   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
845   *                the configuration information for PCCARD module.
846   * @retval HAL state
847   */
HAL_PCCARD_GetState(PCCARD_HandleTypeDef * hpccard)848 HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard)
849 {
850   return hpccard->State;
851 }
852 
853 /**
854   * @brief  Get the compact flash memory status
855   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
856   *                the configuration information for PCCARD module.
857   * @retval New status of the PCCARD operation. This parameter can be:
858   *          - CompactFlash_TIMEOUT_ERROR: when the previous operation generate
859   *            a Timeout error
860   *          - CompactFlash_READY: when memory is ready for the next operation
861   */
HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef * hpccard)862 HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard)
863 {
864   uint32_t timeout = PCCARD_TIMEOUT_STATUS, status_pccard = 0U;
865 
866   /* Check the PCCARD controller state */
867   if(hpccard->State == HAL_PCCARD_STATE_BUSY)
868   {
869      return HAL_PCCARD_STATUS_ONGOING;
870   }
871 
872   status_pccard =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
873 
874   while((status_pccard == PCCARD_BUSY) && timeout)
875   {
876     status_pccard =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
877     timeout--;
878   }
879 
880   if(timeout == 0U)
881   {
882     status_pccard =  PCCARD_TIMEOUT_ERROR;
883   }
884 
885   /* Return the operation status */
886   return (HAL_PCCARD_StatusTypeDef) status_pccard;
887 }
888 
889 /**
890   * @brief  Reads the Compact Flash memory status using the Read status command
891   * @param  hpccard pointer to a PCCARD_HandleTypeDef structure that contains
892   *                the configuration information for PCCARD module.
893   * @retval The status of the Compact Flash memory. This parameter can be:
894   *          - CompactFlash_BUSY: when memory is busy
895   *          - CompactFlash_READY: when memory is ready for the next operation
896   *          - CompactFlash_ERROR: when the previous operation generates error
897   */
HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef * hpccard)898 HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard)
899 {
900   uint8_t data = 0U, status_pccard = PCCARD_BUSY;
901 
902   /* Check the PCCARD controller state */
903   if(hpccard->State == HAL_PCCARD_STATE_BUSY)
904   {
905      return HAL_PCCARD_STATUS_ONGOING;
906   }
907 
908   /* Read status operation */
909   data =  *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
910 
911   if((data & PCCARD_TIMEOUT_ERROR) == PCCARD_TIMEOUT_ERROR)
912   {
913     status_pccard = PCCARD_TIMEOUT_ERROR;
914   }
915   else if((data & PCCARD_READY) == PCCARD_READY)
916   {
917     status_pccard = PCCARD_READY;
918   }
919 
920   return (HAL_PCCARD_StatusTypeDef) status_pccard;
921 }
922 
923 /**
924   * @}
925   */
926 
927 /**
928   * @}
929   */
930 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\
931           STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
932 #endif /* HAL_PCCARD_MODULE_ENABLED */
933 
934 /**
935   * @}
936   */
937 
938 /**
939   * @}
940   */
941 
942 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
943