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