2 ******************************************************************************
3 * @file stm32f3xx_hal_pccard.c
4 * @author MCD Application Team
7 * @brief PCCARD HAL module driver.
8 * This file provides a generic firmware to drive PCCARD memories mounted
12 ===============================================================================
13 ##### How to use this driver #####
14 ===============================================================================
16 This driver is a generic layered driver which contains a set of APIs used to
17 control PCCARD/compact flash memories. It uses the FMC/FSMC layer functions
18 to interface with PCCARD devices. This driver is used for:
20 (+) PCCARD/compact flash memory configuration sequence using the function
21 HAL_PCCARD_Init() with control and timing parameters for both common and
24 (+) Read PCCARD/compact flash memory maker and device IDs using the function
25 HAL_CF_Read_ID(). The read information is stored in the CompactFlash_ID
26 structure declared by the function caller.
28 (+) Access PCCARD/compact flash memory by read/write operations using the functions
29 HAL_CF_Read_Sector()/HAL_CF_Write_Sector(), to read/write sector.
31 (+) Perform PCCARD/compact flash Reset chip operation using the function HAL_CF_Reset().
33 (+) Perform PCCARD/compact flash erase sector operation using the function
34 HAL_CF_Erase_Sector().
36 (+) Read the PCCARD/compact flash status operation using the function HAL_CF_ReadStatus().
38 (+) You can monitor the PCCARD/compact flash device HAL state by calling the function
42 (@) This driver is a set of generic APIs which handle standard PCCARD/compact flash
43 operations. If a PCCARD/compact flash device contains different operations
44 and/or implementations, it should be implemented separately.
47 ******************************************************************************
50 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
52 * Redistribution and use in source and binary forms, with or without modification,
53 * are permitted provided that the following conditions are met:
54 * 1. Redistributions of source code must retain the above copyright notice,
55 * this list of conditions and the following disclaimer.
56 * 2. Redistributions in binary form must reproduce the above copyright notice,
57 * this list of conditions and the following disclaimer in the documentation
58 * and/or other materials provided with the distribution.
59 * 3. Neither the name of STMicroelectronics nor the names of its contributors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
64 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
69 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
70 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
71 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
72 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74 ******************************************************************************
77 /* Includes ------------------------------------------------------------------*/
78 #include "stm32f3xx_hal.h"
80 /** @addtogroup STM32F3xx_HAL_Driver
84 /** @defgroup PCCARD PCCARD HAL module driver
85 * @brief PCCARD HAL module driver
88 #ifdef HAL_PCCARD_MODULE_ENABLED
89 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx)
91 /* Private typedef -----------------------------------------------------------*/
92 /* Private define ------------------------------------------------------------*/
93 /* Private macro -------------------------------------------------------------*/
94 /* Private variables ---------------------------------------------------------*/
95 /* Private function prototypes -----------------------------------------------*/
96 /* Exported functions ---------------------------------------------------------*/
98 /** @defgroup PCCARD_Exported_Functions PCCARD Exported Functions
102 /** @defgroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
103 * @brief Initialization and Configuration functions
106 ==============================================================================
107 ##### PCCARD Initialization and de-initialization functions #####
108 ==============================================================================
110 This section provides functions allowing to initialize/de-initialize
118 * @brief Perform the PCCARD memory Initialization sequence
119 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
120 * the configuration information for PCCARD module.
121 * @param ComSpaceTiming: Common space timing structure
122 * @param AttSpaceTiming: Attribute space timing structure
123 * @param IOSpaceTiming: IO space timing structure
126 HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FMC_NAND_PCC_TimingTypeDef *ComSpaceTiming, FMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FMC_NAND_PCC_TimingTypeDef *IOSpaceTiming)
128 /* Check the PCCARD controller state */
129 if(hpccard == HAL_NULL)
134 if(hpccard->State == HAL_PCCARD_STATE_RESET)
136 /* Initialize the low level hardware (MSP) */
137 HAL_PCCARD_MspInit(hpccard);
140 /* Initialize the PCCARD state */
141 hpccard->State = HAL_PCCARD_STATE_BUSY;
143 /* Initialize PCCARD control Interface */
144 FMC_PCCARD_Init(hpccard->Instance, &(hpccard->Init));
146 /* Init PCCARD common space timing Interface */
147 FMC_PCCARD_CommonSpace_Timing_Init(hpccard->Instance, ComSpaceTiming);
149 /* Init PCCARD attribute space timing Interface */
150 FMC_PCCARD_AttributeSpace_Timing_Init(hpccard->Instance, AttSpaceTiming);
152 /* Init PCCARD IO space timing Interface */
153 FMC_PCCARD_IOSpace_Timing_Init(hpccard->Instance, IOSpaceTiming);
155 /* Enable the PCCARD device */
156 __FMC_PCCARD_ENABLE(hpccard->Instance);
158 /* Update the PCCARD state */
159 hpccard->State = HAL_PCCARD_STATE_READY;
166 * @brief Perform the PCCARD memory De-initialization sequence
167 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
168 * the configuration information for PCCARD module.
171 HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard)
173 /* De-Initialize the low level hardware (MSP) */
174 HAL_PCCARD_MspDeInit(hpccard);
176 /* Configure the PCCARD registers with their reset values */
177 FMC_PCCARD_DeInit(hpccard->Instance);
179 /* Update the PCCARD controller state */
180 hpccard->State = HAL_PCCARD_STATE_RESET;
183 __HAL_UNLOCK(hpccard);
189 * @brief PCCARD MSP Init
190 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
191 * the configuration information for PCCARD module.
194 __weak void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard)
196 /* NOTE : This function Should not be modified, when the callback is needed,
197 the HAL_PCCARD_MspInit could be implemented in the user file
202 * @brief PCCARD MSP DeInit
203 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
204 * the configuration information for PCCARD module.
207 __weak void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard)
209 /* NOTE : This function Should not be modified, when the callback is needed,
210 the HAL_PCCARD_MspDeInit could be implemented in the user file
218 /** @defgroup PCCARD_Exported_Functions_Group2 Input Output and memory functions
219 * @brief Input Output and memory control functions
222 ==============================================================================
223 ##### PCCARD Input Output and memory functions #####
224 ==============================================================================
226 This section provides functions allowing to use and control the PCCARD memory
233 * @brief Read Compact Flash's ID.
234 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
235 * the configuration information for PCCARD module.
236 * @param CompactFlash_ID: Compact flash ID structure.
237 * @param pStatus: pointer to compact flash status
241 HAL_StatusTypeDef HAL_CF_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus)
243 uint32_t timeout = 0xFFFF, index;
249 /* Check the PCCARD controller state */
250 if(hpccard->State == HAL_PCCARD_STATE_BUSY)
255 /* Update the PCCARD controller state */
256 hpccard->State = HAL_PCCARD_STATE_BUSY;
258 /* Initialize the CF status */
261 /* Send the Identify Command */
262 *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD) = 0xECEC;
264 /* Read CF IDs and timeout treatment */
267 /* Read the CF status */
268 status = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
271 }while((status != 0x58) && timeout);
275 *pStatus = CF_TIMEOUT_ERROR;
279 /* Read CF ID bytes */
280 for(index = 0; index < 16; index++)
282 CompactFlash_ID[index] = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_DATA);
286 /* Update the PCCARD controller state */
287 hpccard->State = HAL_PCCARD_STATE_READY;
289 /* Process unlocked */
290 __HAL_UNLOCK(hpccard);
296 * @brief Read sector from PCCARD memory
297 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
298 * the configuration information for PCCARD module.
299 * @param pBuffer: pointer to destination read buffer
300 * @param SectorAddress: Sector address to read
301 * @param pStatus: pointer to CF status
304 HAL_StatusTypeDef HAL_CF_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus)
306 uint32_t timeout = 0xFFFF, index = 0;
312 /* Check the PCCARD controller state */
313 if(hpccard->State == HAL_PCCARD_STATE_BUSY)
318 /* Update the PCCARD controller state */
319 hpccard->State = HAL_PCCARD_STATE_BUSY;
321 /* Initialize CF status */
324 /* Set the parameters to write a sector */
325 *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_CYLINDER_HIGH) = (uint16_t)0x00;
326 *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_SECTOR_COUNT) = ((uint16_t)0x0100 ) | ((uint16_t)SectorAddress);
327 *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD) = (uint16_t)0xE4A0;
331 /* wait till the Status = 0x80 */
332 status = *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
334 }while((status == 0x80) && timeout);
338 *pStatus = CF_TIMEOUT_ERROR;
345 /* wait till the Status = 0x58 */
346 status = *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
348 }while((status != 0x58) && timeout);
352 *pStatus = CF_TIMEOUT_ERROR;
356 for(; index < CF_SECTOR_SIZE; index++)
358 *(uint16_t *)pBuffer++ = *(uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR);
361 /* Update the PCCARD controller state */
362 hpccard->State = HAL_PCCARD_STATE_READY;
364 /* Process unlocked */
365 __HAL_UNLOCK(hpccard);
372 * @brief Write sector to PCCARD memory
373 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
374 * the configuration information for PCCARD module.
375 * @param pBuffer: pointer to source write buffer
376 * @param SectorAddress: Sector address to write
377 * @param pStatus: pointer to CF status
380 HAL_StatusTypeDef HAL_CF_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus)
382 uint32_t timeout = 0xFFFF, index = 0;
388 /* Check the PCCARD controller state */
389 if(hpccard->State == HAL_PCCARD_STATE_BUSY)
394 /* Update the PCCARD controller state */
395 hpccard->State = HAL_PCCARD_STATE_BUSY;
397 /* Initialize CF status */
400 /* Set the parameters to write a sector */
401 *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_CYLINDER_HIGH) = (uint16_t)0x00;
402 *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_SECTOR_COUNT) = ((uint16_t)0x0100 ) | ((uint16_t)SectorAddress);
403 *(__IO uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD) = (uint16_t)0x30A0;
407 /* Wait till the Status = 0x58 */
408 status = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
410 }while((status != 0x58) && timeout);
414 *pStatus = CF_TIMEOUT_ERROR;
418 for(; index < CF_SECTOR_SIZE; index++)
420 *(uint16_t *)(CF_IO_SPACE_PRIMARY_ADDR) = *(uint16_t *)pBuffer++;
425 /* Wait till the Status = 0x50 */
426 status = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
428 }while((status != 0x50) && timeout);
432 *pStatus = CF_TIMEOUT_ERROR;
435 /* Update the PCCARD controller state */
436 hpccard->State = HAL_PCCARD_STATE_READY;
438 /* Process unlocked */
439 __HAL_UNLOCK(hpccard);
446 * @brief Erase sector from PCCARD memory
447 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
448 * the configuration information for PCCARD module.
449 * @param SectorAddress: Sector address to erase
450 * @param pStatus: pointer to CF status
453 HAL_StatusTypeDef HAL_CF_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus)
455 uint32_t timeout = 0x400;
461 /* Check the PCCARD controller state */
462 if(hpccard->State == HAL_PCCARD_STATE_BUSY)
467 /* Update the PCCARD controller state */
468 hpccard->State = HAL_PCCARD_STATE_BUSY;
470 /* Initialize CF status */
473 /* Set the parameters to write a sector */
474 *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_CYLINDER_LOW) = 0x00;
475 *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_CYLINDER_HIGH) = 0x00;
476 *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_SECTOR_NUMBER) = SectorAddress;
477 *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_SECTOR_COUNT) = 0x01;
478 *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_CARD_HEAD) = 0xA0;
479 *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD) = CF_ERASE_SECTOR_CMD;
481 /* wait till the CF is ready */
482 status = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
484 while((status != 0x50) && timeout)
486 status = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
492 *pStatus = CF_TIMEOUT_ERROR;
495 /* Check the PCCARD controller state */
496 hpccard->State = HAL_PCCARD_STATE_READY;
498 /* Process unlocked */
499 __HAL_UNLOCK(hpccard);
505 * @brief Reset the PCCARD memory
506 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
507 * the configuration information for PCCARD module.
510 HAL_StatusTypeDef HAL_CF_Reset(PCCARD_HandleTypeDef *hpccard)
516 /* Check the PCCARD controller state */
517 if(hpccard->State == HAL_PCCARD_STATE_BUSY)
522 /* Provide an SW reset and Read and verify the:
523 - CF Configuration Option Register at address 0x98000200 --> 0x80
524 - Card Configuration and Status Register at address 0x98000202 --> 0x00
525 - Pin Replacement Register at address 0x98000204 --> 0x0C
526 - Socket and Copy Register at address 0x98000206 --> 0x00
529 /* Check the PCCARD controller state */
530 hpccard->State = HAL_PCCARD_STATE_BUSY;
532 *(__IO uint8_t *)(0x98000202) = 0x01;
534 /* Check the PCCARD controller state */
535 hpccard->State = HAL_PCCARD_STATE_READY;
537 /* Process unlocked */
538 __HAL_UNLOCK(hpccard);
544 * @brief This function handles PCCARD device interrupt request.
545 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
546 * the configuration information for PCCARD module.
549 void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard)
551 /* Check PCCARD interrupt Rising edge flag */
552 if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE))
554 /* PCCARD interrupt callback*/
555 HAL_PCCARD_ITCallback(hpccard);
557 /* Clear PCCARD interrupt Rising edge pending bit */
558 __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE);
561 /* Check PCCARD interrupt Level flag */
562 if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_LEVEL))
564 /* PCCARD interrupt callback*/
565 HAL_PCCARD_ITCallback(hpccard);
567 /* Clear PCCARD interrupt Level pending bit */
568 __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_LEVEL);
571 /* Check PCCARD interrupt Falling edge flag */
572 if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE))
574 /* PCCARD interrupt callback*/
575 HAL_PCCARD_ITCallback(hpccard);
577 /* Clear PCCARD interrupt Falling edge pending bit */
578 __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE);
581 /* Check PCCARD interrupt FIFO empty flag */
582 if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FEMPT))
584 /* PCCARD interrupt callback*/
585 HAL_PCCARD_ITCallback(hpccard);
587 /* Clear PCCARD interrupt FIFO empty pending bit */
588 __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FEMPT);
594 * @brief PCCARD interrupt feature callback
595 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
596 * the configuration information for PCCARD module.
599 __weak void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard)
601 /* NOTE : This function Should not be modified, when the callback is needed,
602 the HAL_PCCARD_ITCallback could be implemented in the user file
610 /** @defgroup PCCARD_Exported_Functions_Group3 Peripheral State functions
611 * @brief Peripheral State functions
614 ==============================================================================
615 ##### PCCARD Peripheral State functions #####
616 ==============================================================================
618 This subsection permits to get in run-time the status of the PCCARD controller
626 * @brief return the PCCARD controller state
627 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
628 * the configuration information for PCCARD module.
631 HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard)
633 return hpccard->State;
637 * @brief Get the compact flash memory status
638 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
639 * the configuration information for PCCARD module.
640 * @retval New status of the CF operation. This parameter can be:
641 * - CompactFlash_TIMEOUT_ERROR: when the previous operation generate
643 * - CompactFlash_READY: when memory is ready for the next operation
646 CF_StatusTypedef HAL_CF_GetStatus(PCCARD_HandleTypeDef *hpccard)
648 uint32_t timeout = 0x1000000, status_CF;
650 /* Check the PCCARD controller state */
651 if(hpccard->State == HAL_PCCARD_STATE_BUSY)
656 status_CF = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
658 while((status_CF == CF_BUSY) && timeout)
660 status_CF = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
666 status_CF = CF_TIMEOUT_ERROR;
669 /* Return the operation status */
670 return (CF_StatusTypedef) status_CF;
674 * @brief Reads the Compact Flash memory status using the Read status command
675 * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
676 * the configuration information for PCCARD module.
677 * @retval The status of the Compact Flash memory. This parameter can be:
678 * - CompactFlash_BUSY: when memory is busy
679 * - CompactFlash_READY: when memory is ready for the next operation
680 * - CompactFlash_ERROR: when the previous operation gererates error
682 CF_StatusTypedef HAL_CF_ReadStatus(PCCARD_HandleTypeDef *hpccard)
684 uint8_t data = 0, status_CF = CF_BUSY;
686 /* Check the PCCARD controller state */
687 if(hpccard->State == HAL_PCCARD_STATE_BUSY)
692 /* Read status operation */
693 data = *(__IO uint8_t *)(CF_IO_SPACE_PRIMARY_ADDR | CF_STATUS_CMD_ALTERNATE);
695 if((data & CF_TIMEOUT_ERROR) == CF_TIMEOUT_ERROR)
697 status_CF = CF_TIMEOUT_ERROR;
699 else if((data & CF_READY) == CF_READY)
701 status_CF = CF_READY;
704 return (CF_StatusTypedef) status_CF;
714 #endif /* STM32F302xE || STM32F303xE || STM32F398xx */
715 #endif /* HAL_PCCARD_MODULE_ENABLED */
725 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/