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