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