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