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