diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h
new file mode 100644
index 0000000..28a3eab
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h
@@ -0,0 +1,709 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_sd.h
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief Header file of SD HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ *
© COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_SD_H
+#define __STM32F1xx_HAL_SD_H
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_sdmmc.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SD
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup SD_Exported_Types SD Exported Types
+ * @{
+ */
+
+#define SD_InitTypeDef SDIO_InitTypeDef
+#define SD_TypeDef SDIO_TypeDef
+
+/**
+ * @brief SDIO Handle Structure definition
+ */
+typedef struct
+{
+ SD_TypeDef *Instance; /*!< SDIO register base address */
+
+ SD_InitTypeDef Init; /*!< SD required parameters */
+
+ HAL_LockTypeDef Lock; /*!< SD locking object */
+
+ uint32_t CardType; /*!< SD card type */
+
+ uint32_t RCA; /*!< SD relative card address */
+
+ uint32_t CSD[4]; /*!< SD card specific data table */
+
+ uint32_t CID[4]; /*!< SD card identification number table */
+
+ __IO uint32_t SdTransferCplt; /*!< SD transfer complete flag in non blocking mode */
+
+ __IO uint32_t SdTransferErr; /*!< SD transfer error flag in non blocking mode */
+
+ __IO uint32_t DmaTransferCplt; /*!< SD DMA transfer complete flag */
+
+ __IO uint32_t SdOperation; /*!< SD transfer operation (read/write) */
+
+ DMA_HandleTypeDef *hdmarx; /*!< SD Rx DMA handle parameters */
+
+ DMA_HandleTypeDef *hdmatx; /*!< SD Tx DMA handle parameters */
+
+}SD_HandleTypeDef;
+
+/**
+ * @brief Card Specific Data: CSD Register
+ */
+typedef struct
+{
+ __IO uint8_t CSDStruct; /*!< CSD structure */
+ __IO uint8_t SysSpecVersion; /*!< System specification version */
+ __IO uint8_t Reserved1; /*!< Reserved */
+ __IO uint8_t TAAC; /*!< Data read access time 1 */
+ __IO uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */
+ __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
+ __IO uint16_t CardComdClasses; /*!< Card command classes */
+ __IO uint8_t RdBlockLen; /*!< Max. read data block length */
+ __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
+ __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */
+ __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */
+ __IO uint8_t DSRImpl; /*!< DSR implemented */
+ __IO uint8_t Reserved2; /*!< Reserved */
+ __IO uint32_t DeviceSize; /*!< Device Size */
+ __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
+ __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
+ __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
+ __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
+ __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */
+ __IO uint8_t EraseGrSize; /*!< Erase group size */
+ __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */
+ __IO uint8_t WrProtectGrSize; /*!< Write protect group size */
+ __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */
+ __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */
+ __IO uint8_t WrSpeedFact; /*!< Write speed factor */
+ __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */
+ __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
+ __IO uint8_t Reserved3; /*!< Reserved */
+ __IO uint8_t ContentProtectAppli; /*!< Content protection application */
+ __IO uint8_t FileFormatGrouop; /*!< File format group */
+ __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */
+ __IO uint8_t PermWrProtect; /*!< Permanent write protection */
+ __IO uint8_t TempWrProtect; /*!< Temporary write protection */
+ __IO uint8_t FileFormat; /*!< File format */
+ __IO uint8_t ECC; /*!< ECC code */
+ __IO uint8_t CSD_CRC; /*!< CSD CRC */
+ __IO uint8_t Reserved4; /*!< Always 1 */
+
+}HAL_SD_CSDTypedef;
+
+/**
+ * @brief Card Identification Data: CID Register
+ */
+typedef struct
+{
+ __IO uint8_t ManufacturerID; /*!< Manufacturer ID */
+ __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */
+ __IO uint32_t ProdName1; /*!< Product Name part1 */
+ __IO uint8_t ProdName2; /*!< Product Name part2 */
+ __IO uint8_t ProdRev; /*!< Product Revision */
+ __IO uint32_t ProdSN; /*!< Product Serial Number */
+ __IO uint8_t Reserved1; /*!< Reserved1 */
+ __IO uint16_t ManufactDate; /*!< Manufacturing Date */
+ __IO uint8_t CID_CRC; /*!< CID CRC */
+ __IO uint8_t Reserved2; /*!< Always 1 */
+
+}HAL_SD_CIDTypedef;
+
+/**
+ * @brief SD Card Status returned by ACMD13
+ */
+typedef struct
+{
+ __IO uint8_t DAT_BUS_WIDTH; /*!< Shows the currently defined data bus width */
+ __IO uint8_t SECURED_MODE; /*!< Card is in secured mode of operation */
+ __IO uint16_t SD_CARD_TYPE; /*!< Carries information about card type */
+ __IO uint32_t SIZE_OF_PROTECTED_AREA; /*!< Carries information about the capacity of protected area */
+ __IO uint8_t SPEED_CLASS; /*!< Carries information about the speed class of the card */
+ __IO uint8_t PERFORMANCE_MOVE; /*!< Carries information about the card's performance move */
+ __IO uint8_t AU_SIZE; /*!< Carries information about the card's allocation unit size */
+ __IO uint16_t ERASE_SIZE; /*!< Determines the number of AUs to be erased in one operation */
+ __IO uint8_t ERASE_TIMEOUT; /*!< Determines the timeout for any number of AU erase */
+ __IO uint8_t ERASE_OFFSET; /*!< Carries information about the erase offset */
+
+}HAL_SD_CardStatusTypedef;
+
+/**
+ * @brief SD Card information structure
+ */
+typedef struct
+{
+ HAL_SD_CSDTypedef SD_csd; /*!< SD card specific data register */
+ HAL_SD_CIDTypedef SD_cid; /*!< SD card identification number register */
+ uint64_t CardCapacity; /*!< Card capacity */
+ uint32_t CardBlockSize; /*!< Card block size */
+ uint16_t RCA; /*!< SD relative card address */
+ uint8_t CardType; /*!< SD card type */
+
+}HAL_SD_CardInfoTypedef;
+
+/**
+ * @brief SD Error status enumeration Structure definition
+ */
+typedef enum
+{
+/**
+ * @brief SD specific error defines
+ */
+ SD_CMD_CRC_FAIL = (1), /*!< Command response received (but CRC check failed) */
+ SD_DATA_CRC_FAIL = (2), /*!< Data block sent/received (CRC check failed) */
+ SD_CMD_RSP_TIMEOUT = (3), /*!< Command response timeout */
+ SD_DATA_TIMEOUT = (4), /*!< Data timeout */
+ SD_TX_UNDERRUN = (5), /*!< Transmit FIFO underrun */
+ SD_RX_OVERRUN = (6), /*!< Receive FIFO overrun */
+ SD_START_BIT_ERR = (7), /*!< Start bit not detected on all data signals in wide bus mode */
+ SD_CMD_OUT_OF_RANGE = (8), /*!< Command's argument was out of range. */
+ SD_ADDR_MISALIGNED = (9), /*!< Misaligned address */
+ SD_BLOCK_LEN_ERR = (10), /*!< Transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */
+ SD_ERASE_SEQ_ERR = (11), /*!< An error in the sequence of erase command occurs. */
+ SD_BAD_ERASE_PARAM = (12), /*!< An invalid selection for erase groups */
+ SD_WRITE_PROT_VIOLATION = (13), /*!< Attempt to program a write protect block */
+ SD_LOCK_UNLOCK_FAILED = (14), /*!< Sequence or password error has been detected in unlock command or if there was an attempt to access a locked card */
+ SD_COM_CRC_FAILED = (15), /*!< CRC check of the previous command failed */
+ SD_ILLEGAL_CMD = (16), /*!< Command is not legal for the card state */
+ SD_CARD_ECC_FAILED = (17), /*!< Card internal ECC was applied but failed to correct the data */
+ SD_CC_ERROR = (18), /*!< Internal card controller error */
+ SD_GENERAL_UNKNOWN_ERROR = (19), /*!< General or unknown error */
+ SD_STREAM_READ_UNDERRUN = (20), /*!< The card could not sustain data transfer in stream read operation. */
+ SD_STREAM_WRITE_OVERRUN = (21), /*!< The card could not sustain data programming in stream mode */
+ SD_CID_CSD_OVERWRITE = (22), /*!< CID/CSD overwrite error */
+ SD_WP_ERASE_SKIP = (23), /*!< Only partial address space was erased */
+ SD_CARD_ECC_DISABLED = (24), /*!< Command has been executed without using internal ECC */
+ SD_ERASE_RESET = (25), /*!< Erase sequence was cleared before executing because an out of erase sequence command was received */
+ SD_AKE_SEQ_ERROR = (26), /*!< Error in sequence of authentication. */
+ SD_INVALID_VOLTRANGE = (27),
+ SD_ADDR_OUT_OF_RANGE = (28),
+ SD_SWITCH_ERROR = (29),
+ SD_SDIO_DISABLED = (30),
+ SD_SDIO_FUNCTION_BUSY = (31),
+ SD_SDIO_FUNCTION_FAILED = (32),
+ SD_SDIO_UNKNOWN_FUNCTION = (33),
+
+/**
+ * @brief Standard error defines
+ */
+ SD_INTERNAL_ERROR = (34),
+ SD_NOT_CONFIGURED = (35),
+ SD_REQUEST_PENDING = (36),
+ SD_REQUEST_NOT_APPLICABLE = (37),
+ SD_INVALID_PARAMETER = (38),
+ SD_UNSUPPORTED_FEATURE = (39),
+ SD_UNSUPPORTED_HW = (40),
+ SD_ERROR = (41),
+ SD_OK = (0)
+
+}HAL_SD_ErrorTypedef;
+
+/**
+ * @brief SD Transfer state enumeration structure
+ */
+typedef enum
+{
+ SD_TRANSFER_OK = 0, /*!< Transfer success */
+ SD_TRANSFER_BUSY = 1, /*!< Transfer is occurring */
+ SD_TRANSFER_ERROR = 2 /*!< Transfer failed */
+
+}HAL_SD_TransferStateTypedef;
+
+/**
+ * @brief SD Card State enumeration structure
+ */
+typedef enum
+{
+ SD_CARD_READY = ((uint32_t)0x00000001), /*!< Card state is ready */
+ SD_CARD_IDENTIFICATION = ((uint32_t)0x00000002), /*!< Card is in identification state */
+ SD_CARD_STANDBY = ((uint32_t)0x00000003), /*!< Card is in standby state */
+ SD_CARD_TRANSFER = ((uint32_t)0x00000004), /*!< Card is in transfer state */
+ SD_CARD_SENDING = ((uint32_t)0x00000005), /*!< Card is sending an operation */
+ SD_CARD_RECEIVING = ((uint32_t)0x00000006), /*!< Card is receiving operation information */
+ SD_CARD_PROGRAMMING = ((uint32_t)0x00000007), /*!< Card is in programming state */
+ SD_CARD_DISCONNECTED = ((uint32_t)0x00000008), /*!< Card is disconnected */
+ SD_CARD_ERROR = ((uint32_t)0x000000FF) /*!< Card is in error state */
+
+}HAL_SD_CardStateTypedef;
+
+/**
+ * @brief SD Operation enumeration structure
+ */
+typedef enum
+{
+ SD_READ_SINGLE_BLOCK = 0, /*!< Read single block operation */
+ SD_READ_MULTIPLE_BLOCK = 1, /*!< Read multiple blocks operation */
+ SD_WRITE_SINGLE_BLOCK = 2, /*!< Write single block operation */
+ SD_WRITE_MULTIPLE_BLOCK = 3 /*!< Write multiple blocks operation */
+
+}HAL_SD_OperationTypedef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SD_Exported_Constants SD Exported Constants
+ * @{
+ */
+
+/**
+ * @brief SD Commands Index
+ */
+#define SD_CMD_GO_IDLE_STATE ((uint8_t)0) /*!< Resets the SD memory card. */
+#define SD_CMD_SEND_OP_COND ((uint8_t)1) /*!< Sends host capacity support information and activates the card's initialization process. */
+#define SD_CMD_ALL_SEND_CID ((uint8_t)2) /*!< Asks any card connected to the host to send the CID numbers on the CMD line. */
+#define SD_CMD_SET_REL_ADDR ((uint8_t)3) /*!< Asks the card to publish a new relative address (RCA). */
+#define SD_CMD_SET_DSR ((uint8_t)4) /*!< Programs the DSR of all cards. */
+#define SD_CMD_SDIO_SEN_OP_COND ((uint8_t)5) /*!< Sends host capacity support information (HCS) and asks the accessed card to send its
+ operating condition register (OCR) content in the response on the CMD line. */
+#define SD_CMD_HS_SWITCH ((uint8_t)6) /*!< Checks switchable function (mode 0) and switch card function (mode 1). */
+#define SD_CMD_SEL_DESEL_CARD ((uint8_t)7) /*!< Selects the card by its own relative address and gets deselected by any other address */
+#define SD_CMD_HS_SEND_EXT_CSD ((uint8_t)8) /*!< Sends SD Memory Card interface condition, which includes host supply voltage information
+ and asks the card whether card supports voltage. */
+#define SD_CMD_SEND_CSD ((uint8_t)9) /*!< Addressed card sends its card specific data (CSD) on the CMD line. */
+#define SD_CMD_SEND_CID ((uint8_t)10) /*!< Addressed card sends its card identification (CID) on the CMD line. */
+#define SD_CMD_READ_DAT_UNTIL_STOP ((uint8_t)11) /*!< SD card doesn't support it. */
+#define SD_CMD_STOP_TRANSMISSION ((uint8_t)12) /*!< Forces the card to stop transmission. */
+#define SD_CMD_SEND_STATUS ((uint8_t)13) /*!< Addressed card sends its status register. */
+#define SD_CMD_HS_BUSTEST_READ ((uint8_t)14)
+#define SD_CMD_GO_INACTIVE_STATE ((uint8_t)15) /*!< Sends an addressed card into the inactive state. */
+#define SD_CMD_SET_BLOCKLEN ((uint8_t)16) /*!< Sets the block length (in bytes for SDSC) for all following block commands
+ (read, write, lock). Default block length is fixed to 512 Bytes. Not effective
+ for SDHS and SDXC. */
+#define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17) /*!< Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of
+ fixed 512 bytes in case of SDHC and SDXC. */
+#define SD_CMD_READ_MULT_BLOCK ((uint8_t)18) /*!< Continuously transfers data blocks from card to host until interrupted by
+ STOP_TRANSMISSION command. */
+#define SD_CMD_HS_BUSTEST_WRITE ((uint8_t)19) /*!< 64 bytes tuning pattern is sent for SDR50 and SDR104. */
+#define SD_CMD_WRITE_DAT_UNTIL_STOP ((uint8_t)20) /*!< Speed class control command. */
+#define SD_CMD_SET_BLOCK_COUNT ((uint8_t)23) /*!< Specify block count for CMD18 and CMD25. */
+#define SD_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24) /*!< Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of
+ fixed 512 bytes in case of SDHC and SDXC. */
+#define SD_CMD_WRITE_MULT_BLOCK ((uint8_t)25) /*!< Continuously writes blocks of data until a STOP_TRANSMISSION follows. */
+#define SD_CMD_PROG_CID ((uint8_t)26) /*!< Reserved for manufacturers. */
+#define SD_CMD_PROG_CSD ((uint8_t)27) /*!< Programming of the programmable bits of the CSD. */
+#define SD_CMD_SET_WRITE_PROT ((uint8_t)28) /*!< Sets the write protection bit of the addressed group. */
+#define SD_CMD_CLR_WRITE_PROT ((uint8_t)29) /*!< Clears the write protection bit of the addressed group. */
+#define SD_CMD_SEND_WRITE_PROT ((uint8_t)30) /*!< Asks the card to send the status of the write protection bits. */
+#define SD_CMD_SD_ERASE_GRP_START ((uint8_t)32) /*!< Sets the address of the first write block to be erased. (For SD card only). */
+#define SD_CMD_SD_ERASE_GRP_END ((uint8_t)33) /*!< Sets the address of the last write block of the continuous range to be erased. */
+#define SD_CMD_ERASE_GRP_START ((uint8_t)35) /*!< Sets the address of the first write block to be erased. Reserved for each command
+ system set by switch function command (CMD6). */
+#define SD_CMD_ERASE_GRP_END ((uint8_t)36) /*!< Sets the address of the last write block of the continuous range to be erased.
+ Reserved for each command system set by switch function command (CMD6). */
+#define SD_CMD_ERASE ((uint8_t)38) /*!< Reserved for SD security applications. */
+#define SD_CMD_FAST_IO ((uint8_t)39) /*!< SD card doesn't support it (Reserved). */
+#define SD_CMD_GO_IRQ_STATE ((uint8_t)40) /*!< SD card doesn't support it (Reserved). */
+#define SD_CMD_LOCK_UNLOCK ((uint8_t)42) /*!< Sets/resets the password or lock/unlock the card. The size of the data block is set by
+ the SET_BLOCK_LEN command. */
+#define SD_CMD_APP_CMD ((uint8_t)55) /*!< Indicates to the card that the next command is an application specific command rather
+ than a standard command. */
+#define SD_CMD_GEN_CMD ((uint8_t)56) /*!< Used either to transfer a data block to the card or to get a data block from the card
+ for general purpose/application specific commands. */
+#define SD_CMD_NO_CMD ((uint8_t)64)
+
+/**
+ * @brief Following commands are SD Card Specific commands.
+ * SDIO_APP_CMD should be sent before sending these commands.
+ */
+#define SD_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /*!< (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus
+ widths are given in SCR register. */
+#define SD_CMD_SD_APP_STATUS ((uint8_t)13) /*!< (ACMD13) Sends the SD status. */
+#define SD_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((uint8_t)22) /*!< (ACMD22) Sends the number of the written (without errors) write blocks. Responds with
+ 32bit+CRC data block. */
+#define SD_CMD_SD_APP_OP_COND ((uint8_t)41) /*!< (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to
+ send its operating condition register (OCR) content in the response on the CMD line. */
+#define SD_CMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42) /*!< (ACMD42) Connects/Disconnects the 50 KOhm pull-up resistor on CD/DAT3 (pin 1) of the card. */
+#define SD_CMD_SD_APP_SEND_SCR ((uint8_t)51) /*!< Reads the SD Configuration Register (SCR). */
+#define SD_CMD_SDIO_RW_DIRECT ((uint8_t)52) /*!< For SD I/O card only, reserved for security specification. */
+#define SD_CMD_SDIO_RW_EXTENDED ((uint8_t)53) /*!< For SD I/O card only, reserved for security specification. */
+
+/**
+ * @brief Following commands are SD Card Specific security commands.
+ * SD_CMD_APP_CMD should be sent before sending these commands.
+ */
+#define SD_CMD_SD_APP_GET_MKB ((uint8_t)43) /*!< For SD card only */
+#define SD_CMD_SD_APP_GET_MID ((uint8_t)44) /*!< For SD card only */
+#define SD_CMD_SD_APP_SET_CER_RN1 ((uint8_t)45) /*!< For SD card only */
+#define SD_CMD_SD_APP_GET_CER_RN2 ((uint8_t)46) /*!< For SD card only */
+#define SD_CMD_SD_APP_SET_CER_RES2 ((uint8_t)47) /*!< For SD card only */
+#define SD_CMD_SD_APP_GET_CER_RES1 ((uint8_t)48) /*!< For SD card only */
+#define SD_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((uint8_t)18) /*!< For SD card only */
+#define SD_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((uint8_t)25) /*!< For SD card only */
+#define SD_CMD_SD_APP_SECURE_ERASE ((uint8_t)38) /*!< For SD card only */
+#define SD_CMD_SD_APP_CHANGE_SECURE_AREA ((uint8_t)49) /*!< For SD card only */
+#define SD_CMD_SD_APP_SECURE_WRITE_MKB ((uint8_t)48) /*!< For SD card only */
+
+/**
+ * @brief Supported SD Memory Cards
+ */
+#define STD_CAPACITY_SD_CARD_V1_1 ((uint32_t)0x00000000)
+#define STD_CAPACITY_SD_CARD_V2_0 ((uint32_t)0x00000001)
+#define HIGH_CAPACITY_SD_CARD ((uint32_t)0x00000002)
+#define MULTIMEDIA_CARD ((uint32_t)0x00000003)
+#define SECURE_DIGITAL_IO_CARD ((uint32_t)0x00000004)
+#define HIGH_SPEED_MULTIMEDIA_CARD ((uint32_t)0x00000005)
+#define SECURE_DIGITAL_IO_COMBO_CARD ((uint32_t)0x00000006)
+#define HIGH_CAPACITY_MMC_CARD ((uint32_t)0x00000007)
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup SD_Exported_macros SD Exported Macros
+ * @brief macros to handle interrupts and specific clock configurations
+ * @{
+ */
+
+/**
+ * @brief Enable the SD device.
+ * @param __HANDLE__: SD Handle
+ * @retval None
+ */
+#define __HAL_SD_SDIO_ENABLE(__HANDLE__) __SDIO_ENABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Disable the SD device.
+ * @param __HANDLE__: SD Handle
+ * @retval None
+ */
+#define __HAL_SD_SDIO_DISABLE(__HANDLE__) __SDIO_DISABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Enable the SDIO DMA transfer.
+ * @param __HANDLE__: SD Handle
+ * @retval None
+ */
+#define __HAL_SD_SDIO_DMA_ENABLE(__HANDLE__) __SDIO_DMA_ENABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Disable the SDIO DMA transfer.
+ * @param __HANDLE__: SD Handle
+ * @retval None
+ */
+#define __HAL_SD_SDIO_DMA_DISABLE(__HANDLE__) __SDIO_DMA_DISABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Enable the SD device interrupt.
+ * @param __HANDLE__: SD Handle
+ * @param __INTERRUPT__: specifies the SDIO interrupt sources to be enabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt
+ * @retval None
+ */
+#define __HAL_SD_SDIO_ENABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_ENABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @brief Disable the SD device interrupt.
+ * @param __HANDLE__: SD Handle
+ * @param __INTERRUPT__: specifies the SDIO interrupt sources to be disabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt
+ * @retval None
+ */
+#define __HAL_SD_SDIO_DISABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_DISABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @brief Check whether the specified SD flag is set or not.
+ * @param __HANDLE__: SD Handle
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode.
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_CMDACT: Command transfer in progress
+ * @arg SDIO_FLAG_TXACT: Data transmit in progress
+ * @arg SDIO_FLAG_RXACT: Data receive in progress
+ * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
+ * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
+ * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
+ * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
+ * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
+ * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
+ * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
+ * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval The new state of SD FLAG (SET or RESET).
+ */
+#define __HAL_SD_SDIO_GET_FLAG(__HANDLE__, __FLAG__) __SDIO_GET_FLAG((__HANDLE__)->Instance, (__FLAG__))
+
+/**
+ * @brief Clear the SD's pending flags.
+ * @param __HANDLE__: SD Handle
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval None
+ */
+#define __HAL_SD_SDIO_CLEAR_FLAG(__HANDLE__, __FLAG__) __SDIO_CLEAR_FLAG((__HANDLE__)->Instance, (__FLAG__))
+
+/**
+ * @brief Check whether the specified SD interrupt has occurred or not.
+ * @param __HANDLE__: SD Handle
+ * @param __INTERRUPT__: specifies the SDIO interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt
+ * @retval The new state of SD IT (SET or RESET).
+ */
+#define __HAL_SD_SDIO_GET_IT (__HANDLE__, __INTERRUPT__) __SDIO_GET_IT ((__HANDLE__)->Instance, __INTERRUPT__)
+
+/**
+ * @brief Clear the SD's interrupt pending bits.
+ * @param __HANDLE__ : SD Handle
+ * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval None
+ */
+#define __HAL_SD_SDIO_CLEAR_IT(__HANDLE__, __INTERRUPT__) __SDIO_CLEAR_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SD_Exported_Functions
+ * @{
+ */
+
+/* Initialization and de-initialization functions **********************************/
+/** @addtogroup SD_Exported_Functions_Group1
+ * @{
+ */
+HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo);
+HAL_StatusTypeDef HAL_SD_DeInit (SD_HandleTypeDef *hsd);
+void HAL_SD_MspInit(SD_HandleTypeDef *hsd);
+void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd);
+/**
+ * @}
+ */
+
+/* I/O operation functions *****************************************************/
+/** @addtogroup SD_Exported_Functions_Group2
+ * @{
+ */
+/* Blocking mode: Polling */
+HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
+HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
+HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t Startaddr, uint64_t Endaddr);
+
+/* Non-Blocking mode: Interrupt */
+void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd);
+
+/* Callback in non blocking modes (DMA) */
+void HAL_SD_DMA_RxCpltCallback(DMA_HandleTypeDef *hdma);
+void HAL_SD_DMA_RxErrorCallback(DMA_HandleTypeDef *hdma);
+void HAL_SD_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma);
+void HAL_SD_DMA_TxErrorCallback(DMA_HandleTypeDef *hdma);
+void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd);
+void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd);
+
+/* Non-Blocking mode: DMA */
+HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
+HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
+HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);
+HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);
+/**
+ * @}
+ */
+
+/* Peripheral Control functions ************************************************/
+/** @addtogroup SD_Exported_Functions_Group3
+ * @{
+ */
+HAL_SD_ErrorTypedef HAL_SD_Get_CardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *pCardInfo);
+HAL_SD_ErrorTypedef HAL_SD_WideBusOperation_Config(SD_HandleTypeDef *hsd, uint32_t WideMode);
+HAL_SD_ErrorTypedef HAL_SD_StopTransfer(SD_HandleTypeDef *hsd);
+HAL_SD_ErrorTypedef HAL_SD_HighSpeed (SD_HandleTypeDef *hsd);
+/**
+ * @}
+ */
+
+/* Peripheral State functions **************************************************/
+/** @addtogroup SD_Exported_Functions_Group4
+ * @{
+ */
+HAL_SD_ErrorTypedef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus);
+HAL_SD_ErrorTypedef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypedef *pCardStatus);
+HAL_SD_TransferStateTypedef HAL_SD_GetStatus(SD_HandleTypeDef *hsd);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* __STM32F1xx_HAL_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h
new file mode 100644
index 0000000..2c46ca8
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h
@@ -0,0 +1,201 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_sram.h
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief Header file of SRAM HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_SRAM_H
+#define __STM32F1xx_HAL_SRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_fsmc.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
+
+/** @addtogroup SRAM
+ * @{
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Types SRAM Exported Types
+ * @{
+ */
+/**
+ * @brief HAL SRAM State structures definition
+ */
+typedef enum
+{
+ HAL_SRAM_STATE_RESET = 0x00, /*!< SRAM not yet initialized or disabled */
+ HAL_SRAM_STATE_READY = 0x01, /*!< SRAM initialized and ready for use */
+ HAL_SRAM_STATE_BUSY = 0x02, /*!< SRAM internal process is ongoing */
+ HAL_SRAM_STATE_ERROR = 0x03, /*!< SRAM error state */
+ HAL_SRAM_STATE_PROTECTED = 0x04 /*!< SRAM peripheral NORSRAM device write protected */
+
+}HAL_SRAM_StateTypeDef;
+
+/**
+ * @brief SRAM handle Structure definition
+ */
+typedef struct
+{
+ FSMC_NORSRAM_TypeDef *Instance; /*!< Register base address */
+
+ FSMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */
+
+ FSMC_NORSRAM_InitTypeDef Init; /*!< SRAM device control configuration parameters */
+
+ HAL_LockTypeDef Lock; /*!< SRAM locking object */
+
+ __IO HAL_SRAM_StateTypeDef State; /*!< SRAM device access state */
+
+ DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */
+
+}SRAM_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Macros SRAM Exported Macros
+ * @{
+ */
+
+/** @brief Reset SRAM handle state
+ * @param __HANDLE__: SRAM handle
+ * @retval None
+ */
+#define __HAL_SRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SRAM_STATE_RESET)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup SRAM_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group1
+ * @{
+ */
+
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming);
+HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram);
+void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram);
+void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram);
+
+void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma);
+void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma);
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group2
+ * @{
+ */
+
+/* I/O operation functions *****************************************************/
+HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize);
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group3
+ * @{
+ */
+
+/* SRAM Control functions ******************************************************/
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram);
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram);
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group4
+ * @{
+ */
+
+/* SRAM State functions *********************************************************/
+HAL_SRAM_StateTypeDef HAL_SRAM_GetState(SRAM_HandleTypeDef *hsram);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_SRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h
new file mode 100644
index 0000000..7632d8e
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h
@@ -0,0 +1,1077 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_fsmc.h
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief Header file of FSMC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_FSMC_H
+#define __STM32F1xx_LL_FSMC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined(FSMC_BANK1)
+
+/** @addtogroup FSMC_LL
+ * @{
+ */
+
+/** @addtogroup FSMC_LL_Private_Macros
+ * @{
+ */
+
+#define IS_FSMC_NORSRAM_BANK(__BANK__) (((__BANK__) == FSMC_NORSRAM_BANK1) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK2) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK3) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK4))
+
+#define IS_FSMC_MUX(__MUX__) (((__MUX__) == FSMC_DATA_ADDRESS_MUX_DISABLE) || \
+ ((__MUX__) == FSMC_DATA_ADDRESS_MUX_ENABLE))
+
+#define IS_FSMC_MEMORY(__MEMORY__) (((__MEMORY__) == FSMC_MEMORY_TYPE_SRAM) || \
+ ((__MEMORY__) == FSMC_MEMORY_TYPE_PSRAM)|| \
+ ((__MEMORY__) == FSMC_MEMORY_TYPE_NOR))
+
+#define IS_FSMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_8) || \
+ ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_16) || \
+ ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_32))
+
+#define IS_FSMC_WRITE_BURST(__BURST__) (((__BURST__) == FSMC_WRITE_BURST_DISABLE) || \
+ ((__BURST__) == FSMC_WRITE_BURST_ENABLE))
+
+#define IS_FSMC_ACCESS_MODE(__MODE__) (((__MODE__) == FSMC_ACCESS_MODE_A) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_B) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_C) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_D))
+
+#define IS_FSMC_NAND_BANK(__BANK__) (((__BANK__) == FSMC_NAND_BANK2) || \
+ ((__BANK__) == FSMC_NAND_BANK3))
+
+#define IS_FSMC_WAIT_FEATURE(__FEATURE__) (((__FEATURE__) == FSMC_NAND_PCC_WAIT_FEATURE_DISABLE) || \
+ ((__FEATURE__) == FSMC_NAND_PCC_WAIT_FEATURE_ENABLE))
+
+#define IS_FSMC_NAND_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) || \
+ ((__WIDTH__) == FSMC_NAND_PCC_MEM_BUS_WIDTH_16))
+
+#define IS_FSMC_ECC_STATE(__STATE__) (((__STATE__) == FSMC_NAND_ECC_DISABLE) || \
+ ((__STATE__) == FSMC_NAND_ECC_ENABLE))
+
+#define IS_FSMC_ECCPAGE_SIZE(__SIZE__) (((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_256BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_512BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_8192BYTE))
+
+/** @defgroup FSMC_TCLR_Setup_Time FSMC_TCLR_Setup_Time
+ * @{
+ */
+#define IS_FSMC_TCLR_TIME(__TIME__) ((__TIME__) <= 255)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_TAR_Setup_Time FSMC_TAR_Setup_Time
+ * @{
+ */
+#define IS_FSMC_TAR_TIME(__TIME__) ((__TIME__) <= 255)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Setup_Time FSMC_Setup_Time
+ * @{
+ */
+#define IS_FSMC_SETUP_TIME(__TIME__) ((__TIME__) <= 255)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Setup_Time FSMC_Wait_Setup_Time
+ * @{
+ */
+#define IS_FSMC_WAIT_TIME(__TIME__) ((__TIME__) <= 255)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Hold_Setup_Time FSMC_Hold_Setup_Time
+ * @{
+ */
+#define IS_FSMC_HOLD_TIME(__TIME__) ((__TIME__) <= 255)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_HiZ_Setup_Time FSMC_HiZ_Setup_Time
+ * @{
+ */
+#define IS_FSMC_HIZ_TIME(__TIME__) ((__TIME__) <= 255)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Device_Instance FSMC NOR/SRAM Device Instance
+ * @{
+ */
+
+#define IS_FSMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_DEVICE)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_EXTENDED_Device_Instance FSMC NOR/SRAM EXTENDED Device Instance
+ * @{
+ */
+
+#define IS_FSMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_EXTENDED_DEVICE)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NAND_Device_Instance FSMC NAND Device Instance
+ * @{
+ */
+#define IS_FSMC_NAND_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NAND_DEVICE)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCCARD_Device_Instance FSMC PCCARD Device Instance
+ * @{
+ */
+#define IS_FSMC_PCCARD_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_PCCARD_DEVICE)
+
+/**
+ * @}
+ */
+#define IS_FSMC_BURSTMODE(__STATE__) (((__STATE__) == FSMC_BURST_ACCESS_MODE_DISABLE) || \
+ ((__STATE__) == FSMC_BURST_ACCESS_MODE_ENABLE))
+
+#define IS_FSMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_LOW) || \
+ ((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_HIGH))
+
+#define IS_FSMC_WRAP_MODE(__MODE__) (((__MODE__) == FSMC_WRAP_MODE_DISABLE) || \
+ ((__MODE__) == FSMC_WRAP_MODE_ENABLE))
+
+#define IS_FSMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FSMC_WAIT_TIMING_BEFORE_WS) || \
+ ((__ACTIVE__) == FSMC_WAIT_TIMING_DURING_WS))
+
+#define IS_FSMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FSMC_WRITE_OPERATION_DISABLE) || \
+ ((__OPERATION__) == FSMC_WRITE_OPERATION_ENABLE))
+
+#define IS_FSMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FSMC_WAIT_SIGNAL_DISABLE) || \
+ ((__SIGNAL__) == FSMC_WAIT_SIGNAL_ENABLE))
+
+#define IS_FSMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FSMC_EXTENDED_MODE_DISABLE) || \
+ ((__MODE__) == FSMC_EXTENDED_MODE_ENABLE))
+
+#define IS_FSMC_ASYNWAIT(__STATE__) (((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_DISABLE) || \
+ ((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_ENABLE))
+
+#define IS_FSMC_CLK_DIV(__DIV__) (((__DIV__) > 1) && ((__DIV__) <= 16))
+
+/** @defgroup FSMC_Data_Latency FSMC Data Latency
+ * @{
+ */
+#define IS_FSMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1) && ((__LATENCY__) <= 17))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Address_Setup_Time FSMC Address Setup Time
+ * @{
+ */
+#define IS_FSMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Address_Hold_Time FSMC Address Hold Time
+ * @{
+ */
+#define IS_FSMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 15))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Setup_Time FSMC Data Setup Time
+ * @{
+ */
+#define IS_FSMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 255))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Bus_Turn_around_Duration FSMC Bus Turn around Duration
+ * @{
+ */
+#define IS_FSMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+
+/** @defgroup FSMC_NORSRAM_Exported_typedef FSMC Low Layer Exported Types
+ * @{
+ */
+
+#define FSMC_NORSRAM_TypeDef FSMC_Bank1_TypeDef
+#define FSMC_NORSRAM_EXTENDED_TypeDef FSMC_Bank1E_TypeDef
+#define FSMC_NAND_TypeDef FSMC_Bank2_3_TypeDef
+#define FSMC_PCCARD_TypeDef FSMC_Bank4_TypeDef
+
+#define FSMC_NORSRAM_DEVICE FSMC_Bank1
+#define FSMC_NORSRAM_EXTENDED_DEVICE FSMC_Bank1E
+#define FSMC_NAND_DEVICE FSMC_Bank2_3
+#define FSMC_PCCARD_DEVICE FSMC_Bank4
+
+/**
+ * @brief FSMC_NORSRAM Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used.
+ This parameter can be a value of @ref FSMC_NORSRAM_Bank */
+
+ uint32_t DataAddressMux; /*!< Specifies whether the address and data values are
+ multiplexed on the data bus or not.
+ This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */
+
+ uint32_t MemoryType; /*!< Specifies the type of external memory attached to
+ the corresponding memory device.
+ This parameter can be a value of @ref FSMC_Memory_Type */
+
+ uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be a value of @ref FSMC_NORSRAM_Data_Width */
+
+ uint32_t BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory,
+ valid only with synchronous burst Flash memories.
+ This parameter can be a value of @ref FSMC_Burst_Access_Mode */
+
+ uint32_t WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing
+ the Flash memory in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */
+
+ uint32_t WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash
+ memory, valid only when accessing Flash memories in burst mode.
+ This parameter can be a value of @ref FSMC_Wrap_Mode */
+
+ uint32_t WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one
+ clock cycle before the wait state or during the wait state,
+ valid only when accessing memories in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Timing */
+
+ uint32_t WriteOperation; /*!< Enables or disables the write operation in the selected device by the FSMC.
+ This parameter can be a value of @ref FSMC_Write_Operation */
+
+ uint32_t WaitSignal; /*!< Enables or disables the wait state insertion via wait
+ signal, valid for Flash memory access in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Signal */
+
+ uint32_t ExtendedMode; /*!< Enables or disables the extended mode.
+ This parameter can be a value of @ref FSMC_Extended_Mode */
+
+ uint32_t AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers,
+ valid only with asynchronous Flash memories.
+ This parameter can be a value of @ref FSMC_AsynchronousWait */
+
+ uint32_t WriteBurst; /*!< Enables or disables the write burst operation.
+ This parameter can be a value of @ref FSMC_Write_Burst */
+
+}FSMC_NORSRAM_InitTypeDef;
+
+/**
+ * @brief FSMC_NORSRAM Timing parameters structure definition
+ */
+typedef struct
+{
+ uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address setup time.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 15.
+ @note This parameter is not used with synchronous NOR Flash memories. */
+
+ uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address hold time.
+ This parameter can be a value between Min_Data = 1 and Max_Data = 15.
+ @note This parameter is not used with synchronous NOR Flash memories. */
+
+ uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the data setup time.
+ This parameter can be a value between Min_Data = 1 and Max_Data = 255.
+ @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed
+ NOR Flash memories. */
+
+ uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure
+ the duration of the bus turnaround.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 15.
+ @note This parameter is only used for multiplexed NOR Flash memories. */
+
+ uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of
+ HCLK cycles. This parameter can be a value between Min_Data = 2 and Max_Data = 16.
+ @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM
+ accesses. */
+
+ uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue
+ to the memory before getting the first data.
+ The parameter value depends on the memory type as shown below:
+ - It must be set to 0 in case of a CRAM
+ - It is don't care in asynchronous NOR, SRAM or ROM accesses
+ - It may assume a value between Min_Data = 2 and Max_Data = 17 in NOR Flash memories
+ with synchronous burst mode enable */
+
+ uint32_t AccessMode; /*!< Specifies the asynchronous access mode.
+ This parameter can be a value of @ref FSMC_Access_Mode */
+
+}FSMC_NORSRAM_TimingTypeDef;
+
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/**
+ * @brief FSMC_NAND Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t NandBank; /*!< Specifies the NAND memory device that will be used.
+ This parameter can be a value of @ref FSMC_NAND_Bank */
+
+ uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be any value of @ref FSMC_NAND_Data_Width */
+
+ uint32_t EccComputation; /*!< Enables or disables the ECC computation.
+ This parameter can be any value of @ref FSMC_ECC */
+
+ uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC.
+ This parameter can be any value of @ref FSMC_ECC_Page_Size */
+
+ uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+
+}FSMC_NAND_InitTypeDef;
+
+/**
+ * @brief FSMC_NAND_PCCARD Timing parameters structure definition
+ */
+typedef struct
+{
+ uint32_t SetupTime; /*!< Defines the number of HCLK cycles to setup address before
+ the command assertion for NAND-Flash read or write access
+ to common/Attribute or I/O memory space (depending on
+ the memory space timing to be configured).
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the
+ command for NAND-Flash read or write access to
+ common/Attribute or I/O memory space (depending on the
+ memory space timing to be configured).
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address
+ (and data for write access) after the command de-assertion
+ for NAND-Flash read or write access to common/Attribute
+ or I/O memory space (depending on the memory space timing
+ to be configured).
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the
+ data bus is kept in HiZ after the start of a NAND-Flash
+ write access to common/Attribute or I/O memory space (depending
+ on the memory space timing to be configured).
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+
+}FSMC_NAND_PCC_TimingTypeDef;
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/**
+ * @brief FSMC_NAND Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the PCCARD Memory device.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+
+}FSMC_PCCARD_InitTypeDef;
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup FSMC_Exported_Constants FSMC Low Layer Exported Constants
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM_Exported_constants FSMC NOR/SRAM Exported constants
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM_Bank FSMC NOR/SRAM Bank
+ * @{
+ */
+#define FSMC_NORSRAM_BANK1 ((uint32_t)0x00000000)
+#define FSMC_NORSRAM_BANK2 ((uint32_t)0x00000002)
+#define FSMC_NORSRAM_BANK3 ((uint32_t)0x00000004)
+#define FSMC_NORSRAM_BANK4 ((uint32_t)0x00000006)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Address_Bus_Multiplexing FSMC Data Address Bus Multiplexing
+ * @{
+ */
+
+#define FSMC_DATA_ADDRESS_MUX_DISABLE ((uint32_t)0x00000000)
+#define FSMC_DATA_ADDRESS_MUX_ENABLE ((uint32_t)FSMC_BCRx_MUXEN)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Memory_Type FSMC Memory Type
+ * @{
+ */
+
+#define FSMC_MEMORY_TYPE_SRAM ((uint32_t)0x00000000)
+#define FSMC_MEMORY_TYPE_PSRAM ((uint32_t)FSMC_BCRx_MTYP_0)
+#define FSMC_MEMORY_TYPE_NOR ((uint32_t)FSMC_BCRx_MTYP_1)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Data_Width FSMC NOR/SRAM Data Width
+ * @{
+ */
+
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000)
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_16 ((uint32_t)FSMC_BCRx_MWID_0)
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_32 ((uint32_t)FSMC_BCRx_MWID_1)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Flash_Access FSMC NOR/SRAM Flash Access
+ * @{
+ */
+
+#define FSMC_NORSRAM_FLASH_ACCESS_ENABLE ((uint32_t)FSMC_BCRx_FACCEN)
+#define FSMC_NORSRAM_FLASH_ACCESS_DISABLE ((uint32_t)0x00000000)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Burst_Access_Mode FSMC Burst Access Mode
+ * @{
+ */
+
+#define FSMC_BURST_ACCESS_MODE_DISABLE ((uint32_t)0x00000000)
+#define FSMC_BURST_ACCESS_MODE_ENABLE ((uint32_t)FSMC_BCRx_BURSTEN)
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FSMC_Wait_Signal_Polarity FSMC Wait Signal Polarity
+ * @{
+ */
+
+#define FSMC_WAIT_SIGNAL_POLARITY_LOW ((uint32_t)0x00000000)
+#define FSMC_WAIT_SIGNAL_POLARITY_HIGH ((uint32_t)FSMC_BCRx_WAITPOL)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wrap_Mode FSMC Wrap Mode
+ * @{
+ */
+
+#define FSMC_WRAP_MODE_DISABLE ((uint32_t)0x00000000)
+#define FSMC_WRAP_MODE_ENABLE ((uint32_t)FSMC_BCRx_WRAPMOD)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Timing FSMC Wait Timing
+ * @{
+ */
+
+#define FSMC_WAIT_TIMING_BEFORE_WS ((uint32_t)0x00000000)
+#define FSMC_WAIT_TIMING_DURING_WS ((uint32_t)FSMC_BCRx_WAITCFG)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Operation FSMC Write Operation
+ * @{
+ */
+
+#define FSMC_WRITE_OPERATION_DISABLE ((uint32_t)0x00000000)
+#define FSMC_WRITE_OPERATION_ENABLE ((uint32_t)FSMC_BCRx_WREN)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal FSMC Wait Signal
+ * @{
+ */
+
+#define FSMC_WAIT_SIGNAL_DISABLE ((uint32_t)0x00000000)
+#define FSMC_WAIT_SIGNAL_ENABLE ((uint32_t)FSMC_BCRx_WAITEN)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Extended_Mode FSMC Extended Mode
+ * @{
+ */
+
+#define FSMC_EXTENDED_MODE_DISABLE ((uint32_t)0x00000000)
+#define FSMC_EXTENDED_MODE_ENABLE ((uint32_t)FSMC_BCRx_EXTMOD)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_AsynchronousWait FSMC Asynchronous Wait
+ * @{
+ */
+
+#define FSMC_ASYNCHRONOUS_WAIT_DISABLE ((uint32_t)0x00000000)
+#define FSMC_ASYNCHRONOUS_WAIT_ENABLE ((uint32_t)FSMC_BCRx_ASYNCWAIT)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Burst FSMC Write Burst
+ * @{
+ */
+
+#define FSMC_WRITE_BURST_DISABLE ((uint32_t)0x00000000)
+#define FSMC_WRITE_BURST_ENABLE ((uint32_t)FSMC_BCRx_CBURSTRW)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Access_Mode FSMC Access Mode
+ * @{
+ */
+
+#define FSMC_ACCESS_MODE_A ((uint32_t)0x00000000)
+#define FSMC_ACCESS_MODE_B ((uint32_t)FSMC_BTRx_ACCMOD_0)
+#define FSMC_ACCESS_MODE_C ((uint32_t)FSMC_BTRx_ACCMOD_1)
+#define FSMC_ACCESS_MODE_D ((uint32_t)(FSMC_BTRx_ACCMOD_0 | FSMC_BTRx_ACCMOD_1))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @defgroup FSMC_NAND_Controller FSMC NAND and PCCARD Controller
+ * @{
+ */
+
+/** @defgroup FSMC_NAND_Bank FSMC NAND Bank
+ * @{
+ */
+#define FSMC_NAND_BANK2 ((uint32_t)0x00000010)
+#define FSMC_NAND_BANK3 ((uint32_t)0x00000100)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_feature FSMC Wait feature
+ * @{
+ */
+#define FSMC_NAND_PCC_WAIT_FEATURE_DISABLE ((uint32_t)0x00000000)
+#define FSMC_NAND_PCC_WAIT_FEATURE_ENABLE ((uint32_t)FSMC_PCRx_PWAITEN)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCR_Memory_Type FSMC PCR Memory Type
+ * @{
+ */
+#define FSMC_PCR_MEMORY_TYPE_PCCARD ((uint32_t)0x00000000)
+#define FSMC_PCR_MEMORY_TYPE_NAND ((uint32_t)FSMC_PCRx_PTYP)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NAND_Data_Width FSMC NAND Data Width
+ * @{
+ */
+#define FSMC_NAND_PCC_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000)
+#define FSMC_NAND_PCC_MEM_BUS_WIDTH_16 ((uint32_t)FSMC_PCRx_PWID_0)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_ECC FSMC NAND ECC
+ * @{
+ */
+#define FSMC_NAND_ECC_DISABLE ((uint32_t)0x00000000)
+#define FSMC_NAND_ECC_ENABLE ((uint32_t)FSMC_PCRx_ECCEN)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_ECC_Page_Size FSMC ECC Page Size
+ * @{
+ */
+#define FSMC_NAND_ECC_PAGE_SIZE_256BYTE ((uint32_t)0x00000000)
+#define FSMC_NAND_ECC_PAGE_SIZE_512BYTE ((uint32_t)FSMC_PCRx_ECCPS_0)
+#define FSMC_NAND_ECC_PAGE_SIZE_1024BYTE ((uint32_t)FSMC_PCRx_ECCPS_1)
+#define FSMC_NAND_ECC_PAGE_SIZE_2048BYTE ((uint32_t)FSMC_PCRx_ECCPS_0|FSMC_PCRx_ECCPS_1)
+#define FSMC_NAND_ECC_PAGE_SIZE_4096BYTE ((uint32_t)FSMC_PCRx_ECCPS_2)
+#define FSMC_NAND_ECC_PAGE_SIZE_8192BYTE ((uint32_t)FSMC_PCRx_ECCPS_0|FSMC_PCRx_ECCPS_2)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Interrupt_definition FSMC Interrupt definition
+ * @brief FSMC Interrupt definition
+ * @{
+ */
+#define FSMC_IT_RISING_EDGE ((uint32_t)FSMC_SRx_IREN)
+#define FSMC_IT_LEVEL ((uint32_t)FSMC_SRx_ILEN)
+#define FSMC_IT_FALLING_EDGE ((uint32_t)FSMC_SRx_IFEN)
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Flag_definition FSMC Flag definition
+ * @brief FSMC Flag definition
+ * @{
+ */
+#define FSMC_FLAG_RISING_EDGE ((uint32_t)FSMC_SRx_IRS)
+#define FSMC_FLAG_LEVEL ((uint32_t)FSMC_SRx_ILS)
+#define FSMC_FLAG_FALLING_EDGE ((uint32_t)FSMC_SRx_IFS)
+#define FSMC_FLAG_FEMPT ((uint32_t)FSMC_SRx_FEMPT)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup FSMC_Exported_Macros FSMC Low Layer Exported Macros
+ * @{
+ */
+
+/** @defgroup FSMC_NOR_Macros FSMC NOR/SRAM Exported Macros
+ * @brief macros to handle NOR device enable/disable and read/write operations
+ * @{
+ */
+
+/**
+ * @brief Enable the NORSRAM device access.
+ * @param __INSTANCE__ FSMC_NORSRAM Instance
+ * @param __BANK__ FSMC_NORSRAM Bank
+ * @retval none
+ */
+#define __FSMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) SET_BIT((__INSTANCE__)->BTCR[(__BANK__)], FSMC_BCRx_MBKEN)
+
+/**
+ * @brief Disable the NORSRAM device access.
+ * @param __INSTANCE__ FSMC_NORSRAM Instance
+ * @param __BANK__ FSMC_NORSRAM Bank
+ * @retval none
+ */
+#define __FSMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) CLEAR_BIT((__INSTANCE__)->BTCR[(__BANK__)], FSMC_BCRx_MBKEN)
+
+/**
+ * @}
+ */
+
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @defgroup FSMC_NAND_Macros FSMC NAND Macros
+ * @brief macros to handle NAND device enable/disable
+ * @{
+ */
+
+/**
+ * @brief Enable the NAND device access.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @retval None
+ */
+#define __FSMC_NAND_ENABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? SET_BIT((__INSTANCE__)->PCR2, FSMC_PCRx_PBKEN): \
+ SET_BIT((__INSTANCE__)->PCR3, FSMC_PCRx_PBKEN))
+
+/**
+ * @brief Disable the NAND device access.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @retval None
+ */
+#define __FSMC_NAND_DISABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->PCR2, FSMC_PCRx_PBKEN): \
+ CLEAR_BIT((__INSTANCE__)->PCR3, FSMC_PCRx_PBKEN))
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCCARD_Macros FSMC PCCARD Macros
+ * @brief macros to handle PCCARD read/write operations
+ * @{
+ */
+
+/**
+ * @brief Enable the PCCARD device access.
+ * @param __INSTANCE__ FSMC_PCCARD Instance
+ * @retval None
+ */
+#define __FSMC_PCCARD_ENABLE(__INSTANCE__) SET_BIT((__INSTANCE__)->PCR4, FSMC_PCRx_PBKEN)
+
+/**
+ * @brief Disable the PCCARD device access.
+ * @param __INSTANCE__ FSMC_PCCARD Instance
+ * @retval None
+ */
+#define __FSMC_PCCARD_DISABLE(__INSTANCE__) CLEAR_BIT((__INSTANCE__)->PCR4, FSMC_PCRx_PBKEN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Interrupt FSMC Interrupt
+ * @brief macros to handle FSMC interrupts
+ * @{
+ */
+
+/**
+ * @brief Enable the NAND device interrupt.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @param __INTERRUPT__ FSMC_NAND interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_NAND_ENABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2)? SET_BIT((__INSTANCE__)->SR2, (__INTERRUPT__)): \
+ SET_BIT((__INSTANCE__)->SR3, (__INTERRUPT__)))
+
+/**
+ * @brief Disable the NAND device interrupt.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @param __INTERRUPT__ FSMC_NAND interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_NAND_DISABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->SR2, (__INTERRUPT__)): \
+ CLEAR_BIT((__INSTANCE__)->SR3, (__INTERRUPT__)))
+
+/**
+ * @brief Get flag status of the NAND device.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @param __FLAG__ FSMC_NAND flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT FIFO empty flag.
+ * @retval The state of FLAG (SET or RESET).
+ */
+#define __FSMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2)? (((__INSTANCE__)->SR2 &(__FLAG__)) == (__FLAG__)): \
+ (((__INSTANCE__)->SR3 &(__FLAG__)) == (__FLAG__)))
+
+/**
+ * @brief Clear flag status of the NAND device.
+ * @param __INSTANCE__ FSMC_NAND Instance
+ * @param __BANK__ FSMC_NAND Bank
+ * @param __FLAG__ FSMC_NAND flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT FIFO empty flag.
+ * @retval None
+ */
+#define __FSMC_NAND_CLEAR_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->SR2, (__FLAG__)): \
+ CLEAR_BIT((__INSTANCE__)->SR3, (__FLAG__)))
+
+/**
+ * @brief Enable the PCCARD device interrupt.
+ * @param __INSTANCE__ FSMC_PCCARD Instance
+ * @param __INTERRUPT__ FSMC_PCCARD interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_PCCARD_ENABLE_IT(__INSTANCE__, __INTERRUPT__) SET_BIT((__INSTANCE__)->SR4, (__INTERRUPT__))
+
+/**
+ * @brief Disable the PCCARD device interrupt.
+ * @param __INSTANCE__ FSMC_PCCARD Instance
+ * @param __INTERRUPT__ FSMC_PCCARD interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_PCCARD_DISABLE_IT(__INSTANCE__, __INTERRUPT__) CLEAR_BIT((__INSTANCE__)->SR4, (__INTERRUPT__))
+
+/**
+ * @brief Get flag status of the PCCARD device.
+ * @param __INSTANCE__ FSMC_PCCARD Instance
+ * @param __FLAG__ FSMC_PCCARD flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT FIFO empty flag.
+ * @retval The state of FLAG (SET or RESET).
+ */
+#define __FSMC_PCCARD_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SR4 &(__FLAG__)) == (__FLAG__))
+
+/**
+ * @brief Clear flag status of the PCCARD device.
+ * @param __INSTANCE__ FSMC_PCCARD Instance
+ * @param __FLAG__ FSMC_PCCARD flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT FIFO empty flag.
+ * @retval None
+ */
+#define __FSMC_PCCARD_CLEAR_FLAG(__INSTANCE__, __FLAG__) CLEAR_BIT((__INSTANCE__)->SR4, (__FLAG__))
+
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup FSMC_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup FSMC_NORSRAM
+ * @{
+ */
+
+/** @addtogroup FSMC_NORSRAM_Group1
+ * @{
+ */
+
+/* FSMC_NORSRAM Controller functions ******************************************/
+/* Initialization/de-initialization functions */
+HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode);
+HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank);
+
+/**
+ * @}
+ */
+
+/** @addtogroup FSMC_NORSRAM_Group2
+ * @{
+ */
+
+/* FSMC_NORSRAM Control functions */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @addtogroup FSMC_NAND
+ * @{
+ */
+
+/* FSMC_NAND Controller functions **********************************************/
+/* Initialization/de-initialization functions */
+/** @addtogroup FSMC_NAND_Exported_Functions_Group1
+ * @{
+ */
+
+HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+
+/**
+ * @}
+ */
+
+/* FSMC_NAND Control functions */
+/** @addtogroup FSMC_NAND_Exported_Functions_Group2
+ * @{
+ */
+
+HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FSMC_PCCARD
+ * @{
+ */
+
+/* FSMC_PCCARD Controller functions ********************************************/
+/* Initialization/de-initialization functions */
+/** @addtogroup FSMC_PCCARD_Exported_Functions_Group1
+ * @{
+ */
+
+HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* FSMC_BANK1 */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_FSMC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h
new file mode 100644
index 0000000..a3dec1d
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h
@@ -0,0 +1,876 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_sdmmc.h
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief Header file of low layer SDMMC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __stm32f1xx_LL_SD_H
+#define __stm32f1xx_LL_SD_H
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SDMMC_LL
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup SDMMC_LL_Exported_Types SDMMC_LL Exported Types
+ * @{
+ */
+
+/**
+ * @brief SDMMC Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t ClockEdge; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref SDMMC_LL_Clock_Edge */
+
+ uint32_t ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is
+ enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_Clock_Bypass */
+
+ uint32_t ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or
+ disabled when the bus is idle.
+ This parameter can be a value of @ref SDMMC_LL_Clock_Power_Save */
+
+ uint32_t BusWide; /*!< Specifies the SDIO bus width.
+ This parameter can be a value of @ref SDMMC_LL_Bus_Wide */
+
+ uint32_t HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_Hardware_Flow_Control */
+
+ uint32_t ClockDiv; /*!< Specifies the clock frequency of the SDIO controller.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+}SDIO_InitTypeDef;
+
+
+/**
+ * @brief SDIO Command Control structure
+ */
+typedef struct
+{
+ uint32_t Argument; /*!< Specifies the SDIO command argument which is sent
+ to a card as part of a command message. If a command
+ contains an argument, it must be loaded into this register
+ before writing the command to the command register. */
+
+ uint32_t CmdIndex; /*!< Specifies the SDIO command index. It must be Min_Data = 0 and
+ Max_Data = 64 */
+
+ uint32_t Response; /*!< Specifies the SDIO response type.
+ This parameter can be a value of @ref SDMMC_LL_Response_Type */
+
+ uint32_t WaitForInterrupt; /*!< Specifies whether SDIO wait for interrupt request is
+ enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_Wait_Interrupt_State */
+
+ uint32_t CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM)
+ is enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_CPSM_State */
+}SDIO_CmdInitTypeDef;
+
+
+/**
+ * @brief SDIO Data Control structure
+ */
+typedef struct
+{
+ uint32_t DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */
+
+ uint32_t DataLength; /*!< Specifies the number of data bytes to be transferred. */
+
+ uint32_t DataBlockSize; /*!< Specifies the data block size for block transfer.
+ This parameter can be a value of @ref SDMMC_LL_Data_Block_Size */
+
+ uint32_t TransferDir; /*!< Specifies the data transfer direction, whether the transfer
+ is a read or write.
+ This parameter can be a value of @ref SDMMC_LL_Transfer_Direction */
+
+ uint32_t TransferMode; /*!< Specifies whether data transfer is in stream or block mode.
+ This parameter can be a value of @ref SDMMC_LL_Transfer_Type */
+
+ uint32_t DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM)
+ is enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_DPSM_State */
+}SDIO_DataInitTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SDMMC_LL_Exported_Constants SDMMC_LL Exported Constants
+ * @{
+ */
+
+/** @defgroup SDMMC_LL_Clock_Edge Clock Edge
+ * @{
+ */
+#define SDIO_CLOCK_EDGE_RISING ((uint32_t)0x00000000)
+#define SDIO_CLOCK_EDGE_FALLING SDIO_CLKCR_NEGEDGE
+
+#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_CLOCK_EDGE_RISING) || \
+ ((EDGE) == SDIO_CLOCK_EDGE_FALLING))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Clock_Bypass Clock Bypass
+ * @{
+ */
+#define SDIO_CLOCK_BYPASS_DISABLE ((uint32_t)0x00000000)
+#define SDIO_CLOCK_BYPASS_ENABLE SDIO_CLKCR_BYPASS
+
+#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_CLOCK_BYPASS_DISABLE) || \
+ ((BYPASS) == SDIO_CLOCK_BYPASS_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Clock_Power_Save Clock Power Saving
+ * @{
+ */
+#define SDIO_CLOCK_POWER_SAVE_DISABLE ((uint32_t)0x00000000)
+#define SDIO_CLOCK_POWER_SAVE_ENABLE SDIO_CLKCR_PWRSAV
+
+#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_CLOCK_POWER_SAVE_DISABLE) || \
+ ((SAVE) == SDIO_CLOCK_POWER_SAVE_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Bus_Wide Bus Width
+ * @{
+ */
+#define SDIO_BUS_WIDE_1B ((uint32_t)0x00000000)
+#define SDIO_BUS_WIDE_4B SDIO_CLKCR_WIDBUS_0
+#define SDIO_BUS_WIDE_8B SDIO_CLKCR_WIDBUS_1
+
+#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BUS_WIDE_1B) || \
+ ((WIDE) == SDIO_BUS_WIDE_4B) || \
+ ((WIDE) == SDIO_BUS_WIDE_8B))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Hardware_Flow_Control Hardware Flow Control
+ * @{
+ */
+#define SDIO_HARDWARE_FLOW_CONTROL_DISABLE ((uint32_t)0x00000000)
+#define SDIO_HARDWARE_FLOW_CONTROL_ENABLE SDIO_CLKCR_HWFC_EN
+
+#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HARDWARE_FLOW_CONTROL_DISABLE) || \
+ ((CONTROL) == SDIO_HARDWARE_FLOW_CONTROL_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Clock_Division Clock Division
+ * @{
+ */
+#define IS_SDIO_CLKDIV(DIV) ((DIV) <= 0xFF)
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Command_Index Command Index
+ * @{
+ */
+#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40)
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Response_Type Response Type
+ * @{
+ */
+#define SDIO_RESPONSE_NO ((uint32_t)0x00000000)
+#define SDIO_RESPONSE_SHORT SDIO_CMD_WAITRESP_0
+#define SDIO_RESPONSE_LONG SDIO_CMD_WAITRESP
+
+#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_RESPONSE_NO) || \
+ ((RESPONSE) == SDIO_RESPONSE_SHORT) || \
+ ((RESPONSE) == SDIO_RESPONSE_LONG))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Wait_Interrupt_State Wait Interrupt
+ * @{
+ */
+#define SDIO_WAIT_NO ((uint32_t)0x00000000)
+#define SDIO_WAIT_IT SDIO_CMD_WAITINT
+#define SDIO_WAIT_PEND SDIO_CMD_WAITPEND
+
+#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_WAIT_NO) || \
+ ((WAIT) == SDIO_WAIT_IT) || \
+ ((WAIT) == SDIO_WAIT_PEND))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_CPSM_State CPSM State
+ * @{
+ */
+#define SDIO_CPSM_DISABLE ((uint32_t)0x00000000)
+#define SDIO_CPSM_ENABLE SDIO_CMD_CPSMEN
+
+#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_DISABLE) || \
+ ((CPSM) == SDIO_CPSM_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Response_Registers Response Register
+ * @{
+ */
+#define SDIO_RESP1 ((uint32_t)0x00000000)
+#define SDIO_RESP2 ((uint32_t)0x00000004)
+#define SDIO_RESP3 ((uint32_t)0x00000008)
+#define SDIO_RESP4 ((uint32_t)0x0000000C)
+
+#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || \
+ ((RESP) == SDIO_RESP2) || \
+ ((RESP) == SDIO_RESP3) || \
+ ((RESP) == SDIO_RESP4))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Data_Length Data Lenght
+ * @{
+ */
+#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF)
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Data_Block_Size Data Block Size
+ * @{
+ */
+#define SDIO_DATABLOCK_SIZE_1B ((uint32_t)0x00000000)
+#define SDIO_DATABLOCK_SIZE_2B SDIO_DCTRL_DBLOCKSIZE_0
+#define SDIO_DATABLOCK_SIZE_4B SDIO_DCTRL_DBLOCKSIZE_1
+#define SDIO_DATABLOCK_SIZE_8B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1)
+#define SDIO_DATABLOCK_SIZE_16B SDIO_DCTRL_DBLOCKSIZE_2
+#define SDIO_DATABLOCK_SIZE_32B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_2)
+#define SDIO_DATABLOCK_SIZE_64B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2)
+#define SDIO_DATABLOCK_SIZE_128B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2)
+#define SDIO_DATABLOCK_SIZE_256B SDIO_DCTRL_DBLOCKSIZE_3
+#define SDIO_DATABLOCK_SIZE_512B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_1024B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_2048B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_4096B (SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_8192B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_16384B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
+
+#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DATABLOCK_SIZE_1B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_2B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_4B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_8B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_16B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_32B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_64B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_128B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_256B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_512B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_1024B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_2048B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_4096B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_8192B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_16384B))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Transfer_Direction Transfer Direction
+ * @{
+ */
+#define SDIO_TRANSFER_DIR_TO_CARD ((uint32_t)0x00000000)
+#define SDIO_TRANSFER_DIR_TO_SDIO SDIO_DCTRL_DTDIR
+
+#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TRANSFER_DIR_TO_CARD) || \
+ ((DIR) == SDIO_TRANSFER_DIR_TO_SDIO))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Transfer_Type Transfer Type
+ * @{
+ */
+#define SDIO_TRANSFER_MODE_BLOCK ((uint32_t)0x00000000)
+#define SDIO_TRANSFER_MODE_STREAM SDIO_DCTRL_DTMODE
+
+#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TRANSFER_MODE_BLOCK) || \
+ ((MODE) == SDIO_TRANSFER_MODE_STREAM))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_DPSM_State DPSM State
+ * @{
+ */
+#define SDIO_DPSM_DISABLE ((uint32_t)0x00000000)
+#define SDIO_DPSM_ENABLE SDIO_DCTRL_DTEN
+
+#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_DISABLE) ||\
+ ((DPSM) == SDIO_DPSM_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Read_Wait_Mode Read Wait Mode
+ * @{
+ */
+#define SDIO_READ_WAIT_MODE_DATA2 ((uint32_t)0x00000000)
+#define SDIO_READ_WAIT_MODE_CLK (SDIO_DCTRL_RWMOD)
+
+#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_READ_WAIT_MODE_CLK) || \
+ ((MODE) == SDIO_READ_WAIT_MODE_DATA2))
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Interrupt_sources Interrupt Sources
+ * @{
+ */
+#define SDIO_IT_CCRCFAIL SDIO_STA_CCRCFAIL
+#define SDIO_IT_DCRCFAIL SDIO_STA_DCRCFAIL
+#define SDIO_IT_CTIMEOUT SDIO_STA_CTIMEOUT
+#define SDIO_IT_DTIMEOUT SDIO_STA_DTIMEOUT
+#define SDIO_IT_TXUNDERR SDIO_STA_TXUNDERR
+#define SDIO_IT_RXOVERR SDIO_STA_RXOVERR
+#define SDIO_IT_CMDREND SDIO_STA_CMDREND
+#define SDIO_IT_CMDSENT SDIO_STA_CMDSENT
+#define SDIO_IT_DATAEND SDIO_STA_DATAEND
+#define SDIO_IT_STBITERR SDIO_STA_STBITERR
+#define SDIO_IT_DBCKEND SDIO_STA_DBCKEND
+#define SDIO_IT_CMDACT SDIO_STA_CMDACT
+#define SDIO_IT_TXACT SDIO_STA_TXACT
+#define SDIO_IT_RXACT SDIO_STA_RXACT
+#define SDIO_IT_TXFIFOHE SDIO_STA_TXFIFOHE
+#define SDIO_IT_RXFIFOHF SDIO_STA_RXFIFOHF
+#define SDIO_IT_TXFIFOF SDIO_STA_TXFIFOF
+#define SDIO_IT_RXFIFOF SDIO_STA_RXFIFOF
+#define SDIO_IT_TXFIFOE SDIO_STA_TXFIFOE
+#define SDIO_IT_RXFIFOE SDIO_STA_RXFIFOE
+#define SDIO_IT_TXDAVL SDIO_STA_TXDAVL
+#define SDIO_IT_RXDAVL SDIO_STA_RXDAVL
+#define SDIO_IT_SDIOIT SDIO_STA_SDIOIT
+#define SDIO_IT_CEATAEND SDIO_STA_CEATAEND
+
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Flags Flags
+ * @{
+ */
+#define SDIO_FLAG_CCRCFAIL SDIO_STA_CCRCFAIL
+#define SDIO_FLAG_DCRCFAIL SDIO_STA_DCRCFAIL
+#define SDIO_FLAG_CTIMEOUT SDIO_STA_CTIMEOUT
+#define SDIO_FLAG_DTIMEOUT SDIO_STA_DTIMEOUT
+#define SDIO_FLAG_TXUNDERR SDIO_STA_TXUNDERR
+#define SDIO_FLAG_RXOVERR SDIO_STA_RXOVERR
+#define SDIO_FLAG_CMDREND SDIO_STA_CMDREND
+#define SDIO_FLAG_CMDSENT SDIO_STA_CMDSENT
+#define SDIO_FLAG_DATAEND SDIO_STA_DATAEND
+#define SDIO_FLAG_STBITERR SDIO_STA_STBITERR
+#define SDIO_FLAG_DBCKEND SDIO_STA_DBCKEND
+#define SDIO_FLAG_CMDACT SDIO_STA_CMDACT
+#define SDIO_FLAG_TXACT SDIO_STA_TXACT
+#define SDIO_FLAG_RXACT SDIO_STA_RXACT
+#define SDIO_FLAG_TXFIFOHE SDIO_STA_TXFIFOHE
+#define SDIO_FLAG_RXFIFOHF SDIO_STA_RXFIFOHF
+#define SDIO_FLAG_TXFIFOF SDIO_STA_TXFIFOF
+#define SDIO_FLAG_RXFIFOF SDIO_STA_RXFIFOF
+#define SDIO_FLAG_TXFIFOE SDIO_STA_TXFIFOE
+#define SDIO_FLAG_RXFIFOE SDIO_STA_RXFIFOE
+#define SDIO_FLAG_TXDAVL SDIO_STA_TXDAVL
+#define SDIO_FLAG_RXDAVL SDIO_STA_RXDAVL
+#define SDIO_FLAG_SDIOIT SDIO_STA_SDIOIT
+#define SDIO_FLAG_CEATAEND SDIO_STA_CEATAEND
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup SDMMC_LL_Exported_macros SDMMC_LL Exported Macros
+ * @{
+ */
+
+/** @defgroup SDMMC_LL_Register Bits And Addresses Definitions
+ * @brief SDMMC_LL registers bit address in the alias region
+ * @{
+ */
+
+/* ---------------------- SDIO registers bit mask --------------------------- */
+/* --- CLKCR Register ---*/
+/* CLKCR register clear mask */
+#define CLKCR_CLEAR_MASK ((uint32_t)(SDIO_CLKCR_CLKDIV | SDIO_CLKCR_PWRSAV |\
+ SDIO_CLKCR_BYPASS | SDIO_CLKCR_WIDBUS |\
+ SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN))
+
+/* --- DCTRL Register ---*/
+/* SDIO DCTRL Clear Mask */
+#define DCTRL_CLEAR_MASK ((uint32_t)(SDIO_DCTRL_DTEN | SDIO_DCTRL_DTDIR |\
+ SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE))
+
+/* --- CMD Register ---*/
+/* CMD Register clear mask */
+#define CMD_CLEAR_MASK ((uint32_t)(SDIO_CMD_CMDINDEX | SDIO_CMD_WAITRESP |\
+ SDIO_CMD_WAITINT | SDIO_CMD_WAITPEND |\
+ SDIO_CMD_CPSMEN | SDIO_CMD_SDIOSUSPEND))
+
+/* SDIO RESP Registers Address */
+#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14))
+
+/* SDIO Intialization Frequency (400KHz max) */
+#define SDIO_INIT_CLK_DIV ((uint8_t)0xC3)
+
+/* SDIO Data Transfer Frequency */
+#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x9)
+
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Interrupt_Clock Interrupt And Clock Configuration
+ * @brief macros to handle interrupts and specific clock configurations
+ * @{
+ */
+
+/**
+ * @brief Enable the SDIO device.
+ * @param __INSTANCE__: SDIO Instance
+ * @retval None
+ */
+#define __SDIO_ENABLE(__INSTANCE__) ((__INSTANCE__)->CLKCR |= SDIO_CLKCR_CLKEN)
+
+/**
+ * @brief Disable the SDIO device.
+ * @param __INSTANCE__: SDIO Instance
+ * @retval None
+ */
+#define __SDIO_DISABLE(__INSTANCE__) ((__INSTANCE__)->CLKCR &= ~SDIO_CLKCR_CLKEN)
+
+/**
+ * @brief Enable the SDIO DMA transfer.
+ * @param None
+ * @retval None
+ */
+#define __SDIO_DMA_ENABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL |= SDIO_DCTRL_DMAEN)
+/**
+ * @brief Disable the SDIO DMA transfer.
+ * @param None
+ * @retval None
+ */
+#define __SDIO_DMA_DISABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL &= ~SDIO_DCTRL_DMAEN)
+
+/**
+ * @brief Enable the SDIO device interrupt.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __INTERRUPT__ : specifies the SDIO interrupt sources to be enabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt
+ * @retval None
+ */
+#define __SDIO_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK |= (__INTERRUPT__))
+
+/**
+ * @brief Disable the SDIO device interrupt.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __INTERRUPT__ : specifies the SDIO interrupt sources to be disabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt
+ * @retval None
+ */
+#define __SDIO_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK &= ~(__INTERRUPT__))
+
+/**
+ * @brief Checks whether the specified SDIO flag is set or not.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode.
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_CMDACT: Command transfer in progress
+ * @arg SDIO_FLAG_TXACT: Data transmit in progress
+ * @arg SDIO_FLAG_RXACT: Data receive in progress
+ * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
+ * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
+ * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
+ * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
+ * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
+ * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
+ * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
+ * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval The new state of SDIO_FLAG (SET or RESET).
+ */
+#define __SDIO_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->STA &(__FLAG__)) != RESET)
+
+
+/**
+ * @brief Clears the SDIO pending flags.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval None
+ */
+#define __SDIO_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->ICR = (__FLAG__))
+
+/**
+ * @brief Checks whether the specified SDIO interrupt has occurred or not.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __INTERRUPT__: specifies the SDIO interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt
+ * @retval The new state of SDIO_IT (SET or RESET).
+ */
+#define __SDIO_GET_IT (__INSTANCE__, __INTERRUPT__) (((__INSTANCE__)->STA &(__INTERRUPT__)) == (__INTERRUPT__))
+
+/**
+ * @brief Clears the SDIO's interrupt pending bits.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval None
+ */
+#define __SDIO_CLEAR_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->ICR = (__INTERRUPT__))
+
+/**
+ * @brief Enable Start the SD I/O Read Wait operation.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_START_READWAIT_ENABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL |= SDIO_DCTRL_RWSTART)
+
+/**
+ * @brief Disable Start the SD I/O Read Wait operations.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_START_READWAIT_DISABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL &= ~SDIO_DCTRL_RWSTART)
+
+/**
+ * @brief Enable Start the SD I/O Read Wait operation.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_STOP_READWAIT_ENABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL |= SDIO_DCTRL_RWSTOP)
+
+/**
+ * @brief Disable Stop the SD I/O Read Wait operations.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_STOP_READWAIT_DISABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL &= ~SDIO_DCTRL_RWSTOP)
+
+/**
+ * @brief Enable the SD I/O Mode Operation.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_OPERATION_ENABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL |= SDIO_DCTRL_SDIOEN)
+
+/**
+ * @brief Disable the SD I/O Mode Operation.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_OPERATION_DISABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL &= ~SDIO_DCTRL_SDIOEN)
+
+/**
+ * @brief Enable the SD I/O Suspend command sending.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_SUSPEND_CMD_ENABLE(__INSTANCE__) ((__INSTANCE__)->CMD |= SDIO_CMD_SDIOSUSPEND)
+
+/**
+ * @brief Disable the SD I/O Suspend command sending.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_SUSPEND_CMD_DISABLE(__INSTANCE__) ((__INSTANCE__)->CMD &= ~SDIO_CMD_SDIOSUSPEND)
+
+/**
+ * @brief Enable the command completion signal.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_CEATA_CMD_COMPLETION_ENABLE(__INSTANCE__) ((__INSTANCE__)->CMD |= SDIO_CMD_ENCMDCOMPL)
+
+/**
+ * @brief Disable the command completion signal.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_CEATA_CMD_COMPLETION_DISABLE(__INSTANCE__) ((__INSTANCE__)->CMD &= ~SDIO_CMD_ENCMDCOMPL)
+
+/**
+ * @brief Enable the CE-ATA interrupt.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_CEATA_ENABLE_IT(__INSTANCE__) ((__INSTANCE__)->CMD &= ~SDIO_CMD_NIEN)
+
+/**
+ * @brief Disable the CE-ATA interrupt.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_CEATA_DISABLE_IT(__INSTANCE__) ((__INSTANCE__)->CMD |= SDIO_CMD_NIEN)
+
+/**
+ * @brief Enable send CE-ATA command (CMD61).
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_CEATA_SENDCMD_ENABLE(__INSTANCE__) ((__INSTANCE__)->CMD |= SDIO_CMD_CEATACMD)
+
+/**
+ * @brief Disable send CE-ATA command (CMD61).
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_CEATA_SENDCMD_DISABLE(__INSTANCE__) ((__INSTANCE__)->CMD &= ~SDIO_CMD_CEATACMD)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SDMMC_LL_Exported_Functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions **********************************/
+/** @addtogroup HAL_SDMMC_LL_Group1
+ * @{
+ */
+HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init);
+/**
+ * @}
+ */
+
+/* I/O operation functions *****************************************************/
+/** @addtogroup HAL_SDMMC_LL_Group2
+ * @{
+ */
+/* Blocking mode: Polling */
+uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx);
+HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData);
+/**
+ * @}
+ */
+
+/* Peripheral Control functions ************************************************/
+/** @addtogroup HAL_SDMMC_LL_Group3
+ * @{
+ */
+HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx);
+HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx);
+uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx);
+
+/* Command path state machine (CPSM) management functions */
+HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command);
+uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx);
+uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response);
+
+/* Data path state machine (DPSM) management functions */
+HAL_StatusTypeDef SDIO_DataConfig(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data);
+uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx);
+uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx);
+
+/* SDIO Cards mode management functions */
+HAL_StatusTypeDef SDIO_SetSDIOReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* __stm32f1xx_LL_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c
new file mode 100644
index 0000000..33c848a
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c
@@ -0,0 +1,3458 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_sd.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief SD card HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Secure Digital (SD) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver implements a high level communication layer for read and write from/to
+ this memory. The needed STM32 hardware resources (SDIO and GPIO) are performed by
+ the user in HAL_SD_MspInit() function (MSP layer).
+ Basically, the MSP layer configuration should be the same as we provide in the
+ examples.
+ You can easily tailor this configuration according to hardware resources.
+
+ [..]
+ This driver is a generic layered driver for SDIO memories which uses the HAL
+ SDIO driver functions to interface with SD and uSD cards devices.
+ It is used as follows:
+
+ (#)Initialize the SDIO low level resources by implement the HAL_SD_MspInit() API:
+ (##) Enable the SDIO interface clock using __HAL_RCC_SDIO_CLK_ENABLE();
+ (##) SDIO pins configuration for SD card
+ (+++) Enable the clock for the SDIO GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
+ (+++) Configure these SDIO pins as alternate function pull-up using HAL_GPIO_Init()
+ and according to your pin assignment;
+ (##) DMA Configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA()
+ and HAL_SD_WriteBlocks_DMA() APIs).
+ (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
+ (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
+ (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
+ (+++) Configure the SDIO and DMA interrupt priorities using functions
+ HAL_NVIC_SetPriority(); DMA priority is superior to SDIO's priority
+ (+++) Enable the NVIC DMA and SDIO IRQs using function HAL_NVIC_EnableIRQ()
+ (+++) SDIO interrupts are managed using the macros __HAL_SD_SDIO_ENABLE_IT()
+ and __HAL_SD_SDIO_DISABLE_IT() inside the communication process.
+ (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_SDIO_GET_IT()
+ and __HAL_SD_SDIO_CLEAR_IT()
+ (#) At this stage, you can perform SD read/write/erase operations after SD card initialization
+
+
+ *** SD Card Initialization and configuration ***
+ ================================================
+ [..]
+ To initialize the SD Card, use the HAL_SD_Init() function. It Initializes
+ the SD Card and put it into StandBy State (Ready for data transfer).
+ This function provide the following operations:
+
+ (#) Apply the SD Card initialization process at 400KHz and check the SD Card
+ type (Standard Capacity or High Capacity). You can change or adapt this
+ frequency by adjusting the "ClockDiv" field.
+ The SD Card frequency (SDIO_CK) is computed as follows:
+
+ SDIO_CK = SDIOCLK / (ClockDiv + 2)
+
+ In initialization mode and according to the SD Card standard,
+ make sure that the SDIO_CK frequency doesn't exceed 400KHz.
+
+ (#) Get the SD CID and CSD data. All these information are managed by the SDCardInfo
+ structure. This structure provide also ready computed SD Card capacity
+ and Block size.
+
+ -@- These information are stored in SD handle structure in case of future use.
+
+ (#) Configure the SD Card Data transfer frequency. The card transfer
+ frequency is set to SDIOCLK / (SDIO_TRANSFER_CLK_DIV + 2). You can change or adapt this frequency by adjusting
+ the "ClockDiv" field.
+ The SD Card frequency (SDIO_CK) is computed as follows:
+
+ SDIO_CK = SDIOCLK / (ClockDiv + 2)
+
+ In transfer mode and according to the SD Card standard, make sure that the
+ SDIO_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
+
+ (#) Select the corresponding SD Card according to the address read with the step 2.
+
+ (#) Configure the SD Card in wide bus mode: 4-bits data.
+
+ *** SD Card Read operation ***
+ ==============================
+ [..]
+ (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks().
+ This function support only 512-bytes block length (the block size should be
+ chosen as 512 bytes).
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+
+ (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().
+ This function support only 512-bytes block length (the block size should be
+ chosen as 512 bytes).
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to call the function HAL_SD_CheckReadOperation(), to insure
+ that the read transfer is done correctly in both DMA and SD sides.
+
+ *** SD Card Write operation ***
+ ===============================
+ [..]
+ (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks().
+ This function support only 512-bytes block length (the block size should be
+ chosen as 512 bytes).
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+
+ (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA().
+ This function support only 512-bytes block length (the block size should be
+ chosen as 512 byte).
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to call the function HAL_SD_CheckWriteOperation(), to insure
+ that the write transfer is done correctly in both DMA and SD sides.
+
+ *** SD card status ***
+ ======================
+ [..]
+ (+) At any time, you can check the SD Card status and get the SD card state
+ by using the HAL_SD_GetStatus() function. This function checks first if the
+ SD card is still connected and then get the internal SD Card transfer state.
+ (+) You can also get the SD card SD Status register by using the HAL_SD_SendSDStatus()
+ function.
+
+ *** SD HAL driver macros list ***
+ ==================================
+ [..]
+ Below the list of most used macros in SD HAL driver.
+ (+) __HAL_SD_SDIO_ENABLE : Enable the SD device
+ (+) __HAL_SD_SDIO_DISABLE : Disable the SD device
+ (+) __HAL_SD_SDIO_DMA_ENABLE: Enable the SDIO DMA transfer
+ (+) __HAL_SD_SDIO_DMA_DISABLE: Disable the SDIO DMA transfer
+ (+) __HAL_SD_SDIO_ENABLE_IT: Enable the SD device interrupt
+ (+) __HAL_SD_SDIO_DISABLE_IT: Disable the SD device interrupt
+ (+) __HAL_SD_SDIO_GET_FLAG:Check whether the specified SD flag is set or not
+ (+) __HAL_SD_SDIO_CLEAR_FLAG: Clear the SD's pending flags
+
+ -@- You can refer to the SD HAL driver header file for more useful macros
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+#ifdef HAL_SD_MODULE_ENABLED
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup SD SD
+ * @brief SD HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup SD_Private_Define SD Private Constant
+ * @{
+ */
+/**
+ * @brief SDIO Data block size
+ */
+#define DATA_BLOCK_SIZE ((uint32_t)(9 << 4))
+/**
+ * @brief SDIO Static flags, TimeOut, FIFO Address
+ */
+#define SDIO_STATIC_FLAGS ((uint32_t)(SDIO_FLAG_CCRCFAIL | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_CTIMEOUT |\
+ SDIO_FLAG_DTIMEOUT | SDIO_FLAG_TXUNDERR | SDIO_FLAG_RXOVERR |\
+ SDIO_FLAG_CMDREND | SDIO_FLAG_CMDSENT | SDIO_FLAG_DATAEND |\
+ SDIO_FLAG_DBCKEND))
+
+#define SDIO_CMD0TIMEOUT ((uint32_t)0x00010000)
+
+/**
+ * @brief Mask for errors Card Status R1 (OCR Register)
+ */
+#define SD_OCR_ADDR_OUT_OF_RANGE ((uint32_t)0x80000000)
+#define SD_OCR_ADDR_MISALIGNED ((uint32_t)0x40000000)
+#define SD_OCR_BLOCK_LEN_ERR ((uint32_t)0x20000000)
+#define SD_OCR_ERASE_SEQ_ERR ((uint32_t)0x10000000)
+#define SD_OCR_BAD_ERASE_PARAM ((uint32_t)0x08000000)
+#define SD_OCR_WRITE_PROT_VIOLATION ((uint32_t)0x04000000)
+#define SD_OCR_LOCK_UNLOCK_FAILED ((uint32_t)0x01000000)
+#define SD_OCR_COM_CRC_FAILED ((uint32_t)0x00800000)
+#define SD_OCR_ILLEGAL_CMD ((uint32_t)0x00400000)
+#define SD_OCR_CARD_ECC_FAILED ((uint32_t)0x00200000)
+#define SD_OCR_CC_ERROR ((uint32_t)0x00100000)
+#define SD_OCR_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00080000)
+#define SD_OCR_STREAM_READ_UNDERRUN ((uint32_t)0x00040000)
+#define SD_OCR_STREAM_WRITE_OVERRUN ((uint32_t)0x00020000)
+#define SD_OCR_CID_CSD_OVERWRITE ((uint32_t)0x00010000)
+#define SD_OCR_WP_ERASE_SKIP ((uint32_t)0x00008000)
+#define SD_OCR_CARD_ECC_DISABLED ((uint32_t)0x00004000)
+#define SD_OCR_ERASE_RESET ((uint32_t)0x00002000)
+#define SD_OCR_AKE_SEQ_ERROR ((uint32_t)0x00000008)
+#define SD_OCR_ERRORBITS ((uint32_t)0xFDFFE008)
+
+/**
+ * @brief Masks for R6 Response
+ */
+#define SD_R6_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00002000)
+#define SD_R6_ILLEGAL_CMD ((uint32_t)0x00004000)
+#define SD_R6_COM_CRC_FAILED ((uint32_t)0x00008000)
+
+#define SD_VOLTAGE_WINDOW_SD ((uint32_t)0x80100000)
+#define SD_HIGH_CAPACITY ((uint32_t)0x40000000)
+#define SD_STD_CAPACITY ((uint32_t)0x00000000)
+#define SD_CHECK_PATTERN ((uint32_t)0x000001AA)
+
+#define SD_MAX_VOLT_TRIAL ((uint32_t)0x0000FFFF)
+#define SD_ALLZERO ((uint32_t)0x00000000)
+
+#define SD_WIDE_BUS_SUPPORT ((uint32_t)0x00040000)
+#define SD_SINGLE_BUS_SUPPORT ((uint32_t)0x00010000)
+#define SD_CARD_LOCKED ((uint32_t)0x02000000)
+
+#define SD_DATATIMEOUT ((uint32_t)0xFFFFFFFF)
+#define SD_0TO7BITS ((uint32_t)0x000000FF)
+#define SD_8TO15BITS ((uint32_t)0x0000FF00)
+#define SD_16TO23BITS ((uint32_t)0x00FF0000)
+#define SD_24TO31BITS ((uint32_t)0xFF000000)
+#define SD_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFF)
+
+#define SD_HALFFIFO ((uint32_t)0x00000008)
+#define SD_HALFFIFOBYTES ((uint32_t)0x00000020)
+
+/**
+ * @brief Command Class Supported
+ */
+#define SD_CCCC_LOCK_UNLOCK ((uint32_t)0x00000080)
+#define SD_CCCC_WRITE_PROT ((uint32_t)0x00000040)
+#define SD_CCCC_ERASE ((uint32_t)0x00000020)
+
+/**
+ * @brief Following commands are SD Card Specific commands.
+ * SDIO_APP_CMD should be sent before sending these commands.
+ */
+#define SD_SDIO_SEND_IF_COND ((uint32_t)SD_CMD_HS_SEND_EXT_CSD)
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup SD_Private_Functions SD Private Functions
+ * @{
+ */
+
+static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t Addr);
+static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus);
+static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus);
+static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD);
+static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA);
+static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd);
+static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR);
+static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma);
+static void SD_DMA_RxError(DMA_HandleTypeDef *hdma);
+static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma);
+static void SD_DMA_TxError(DMA_HandleTypeDef *hdma);
+
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions SD Exported Functions
+ * @{
+ */
+
+/** @defgroup SD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize the SD
+ card device to be ready for use.
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the SD card according to the specified parameters in the
+ SD_HandleTypeDef and create the associated handle.
+ * @param hsd: SD handle
+ * @param SDCardInfo: HAL_SD_CardInfoTypedef structure for SD card information
+ * @retval HAL SD error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo)
+{
+ __IO HAL_SD_ErrorTypedef errorstate = SD_OK;
+ SD_InitTypeDef tmpinit = {0};
+
+ /* Initialize the low level hardware (MSP) */
+ HAL_SD_MspInit(hsd);
+
+ /* Default SDIO peripheral configuration for SD card initialization */
+ tmpinit.ClockEdge = SDIO_CLOCK_EDGE_RISING;
+ tmpinit.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
+ tmpinit.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
+ tmpinit.BusWide = SDIO_BUS_WIDE_1B;
+ tmpinit.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
+ tmpinit.ClockDiv = SDIO_INIT_CLK_DIV;
+
+ /* Initialize SDIO peripheral interface with default configuration */
+ SDIO_Init(hsd->Instance, tmpinit);
+
+ /* Identify card operating voltage */
+ errorstate = SD_PowerON(hsd);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Initialize the present SDIO card(s) and put them in idle state */
+ errorstate = SD_Initialize_Cards(hsd);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Read CSD/CID MSD registers */
+ errorstate = HAL_SD_Get_CardInfo(hsd, SDCardInfo);
+
+ if (errorstate == SD_OK)
+ {
+ /* Select the Card */
+ errorstate = SD_Select_Deselect(hsd, (uint32_t)(((uint32_t)SDCardInfo->RCA) << 16));
+ }
+
+ /* Configure SDIO peripheral interface */
+ SDIO_Init(hsd->Instance, hsd->Init);
+
+ return errorstate;
+}
+
+/**
+ * @brief De-Initializes the SD card.
+ * @param hsd: SD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)
+{
+
+ /* Set SD power state to off */
+ SD_PowerOFF(hsd);
+
+ /* De-Initialize the MSP layer */
+ HAL_SD_MspDeInit(hsd);
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Initializes the SD MSP.
+ * @param hsd: SD handle
+ * @retval None
+ */
+__weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief De-Initialize SD MSP.
+ * @param hsd: SD handle
+ * @retval None
+ */
+__weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions_Group2 IO operation functions
+ * @brief Data transfer functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the data
+ transfer from/to SD card.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads block(s) from a specified address in a card. The Data transfer
+ * is managed by polling mode.
+ * @param hsd: SD handle
+ * @param pReadBuffer: pointer to the buffer that will contain the received data
+ * @param ReadAddr: Address from where data is to be read
+ * @param BlockSize: SD card Data block size (in bytes)
+ * This parameter should be 512
+ * @param NumberOfBlocks: Number of SD blocks to read
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ SDIO_DataInitTypeDef sdio_datainitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t count = 0, *tempbuff = (uint32_t *)pReadBuffer;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0;
+
+ if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
+ {
+ BlockSize = 512;
+ ReadAddr /= 512;
+ }
+
+ /* Set Block Size for Card */
+ sdio_cmdinitstructure.Argument = (uint32_t) BlockSize;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
+ sdio_datainitstructure.DataLength = NumberOfBlocks * BlockSize;
+ sdio_datainitstructure.DataBlockSize = DATA_BLOCK_SIZE;
+ sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
+
+ if(NumberOfBlocks > 1)
+ {
+ /* Send CMD18 READ_MULT_BLOCK with argument data address */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_MULT_BLOCK;
+ }
+ else
+ {
+ /* Send CMD17 READ_SINGLE_BLOCK */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
+ }
+
+ sdio_cmdinitstructure.Argument = (uint32_t)ReadAddr;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Read block(s) in polling mode */
+ if(NumberOfBlocks > 1)
+ {
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Poll on SDIO flags */
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
+ {
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
+ {
+ /* Read data from SDIO Rx FIFO */
+ for (count = 0; count < 8; count++)
+ {
+ *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);
+ }
+
+ tempbuff += 8;
+ }
+ }
+ }
+ else
+ {
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* In case of single block transfer, no need of stop transfer at all */
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))
+ {
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
+ {
+ /* Read data from SDIO Rx FIFO */
+ for (count = 0; count < 8; count++)
+ {
+ *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);
+ }
+
+ tempbuff += 8;
+ }
+ }
+ }
+
+ /* Send stop transmission command in case of multiblock read */
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1))
+ {
+ if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) ||\
+ (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
+ (hsd->CardType == HIGH_CAPACITY_SD_CARD))
+ {
+ /* Send stop transmission command */
+ errorstate = HAL_SD_StopTransfer(hsd);
+ }
+ }
+
+ /* Get error state */
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
+
+ errorstate = SD_DATA_TIMEOUT;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
+
+ errorstate = SD_DATA_CRC_FAIL;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
+
+ errorstate = SD_RX_OVERRUN;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);
+
+ errorstate = SD_START_BIT_ERR;
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ count = SD_DATATIMEOUT;
+
+ /* Empty FIFO if there is still any data */
+ while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0))
+ {
+ *tempbuff = SDIO_ReadFIFO(hsd->Instance);
+ tempbuff++;
+ count--;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ return errorstate;
+}
+
+/**
+ * @brief Allows to write block(s) to a specified address in a card. The Data
+ * transfer is managed by polling mode.
+ * @param hsd: SD handle
+ * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit
+ * @param WriteAddr: Address from where data is to be written
+ * @param BlockSize: SD card Data block size (in bytes)
+ * This parameter should be 512.
+ * @param NumberOfBlocks: Number of SD blocks to write
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ SDIO_DataInitTypeDef sdio_datainitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t totalnumberofbytes = 0, bytestransferred = 0, count = 0, restwords = 0;
+ uint32_t *tempbuff = (uint32_t *)pWriteBuffer;
+ uint8_t cardstate = 0;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0;
+
+ if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
+ {
+ BlockSize = 512;
+ WriteAddr /= 512;
+ }
+
+ /* Set Block Size for Card */
+ sdio_cmdinitstructure.Argument = (uint32_t)BlockSize;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ if(NumberOfBlocks > 1)
+ {
+ /* Send CMD25 WRITE_MULT_BLOCK with argument data address */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
+ }
+ else
+ {
+ /* Send CMD24 WRITE_SINGLE_BLOCK */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
+ }
+
+ sdio_cmdinitstructure.Argument = (uint32_t)WriteAddr;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ if(NumberOfBlocks > 1)
+ {
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK);
+ }
+ else
+ {
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK);
+ }
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Set total number of bytes to write */
+ totalnumberofbytes = NumberOfBlocks * BlockSize;
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
+ sdio_datainitstructure.DataLength = NumberOfBlocks * BlockSize;
+ sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
+ sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
+
+ /* Write block(s) in polling mode */
+ if(NumberOfBlocks > 1)
+ {
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
+ {
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE))
+ {
+ if ((totalnumberofbytes - bytestransferred) < 32)
+ {
+ restwords = ((totalnumberofbytes - bytestransferred) % 4 == 0) ? ((totalnumberofbytes - bytestransferred) / 4) : (( totalnumberofbytes - bytestransferred) / 4 + 1);
+
+ /* Write data to SDIO Tx FIFO */
+ for (count = 0; count < restwords; count++)
+ {
+ SDIO_WriteFIFO(hsd->Instance, tempbuff);
+ tempbuff++;
+ bytestransferred += 4;
+ }
+ }
+ else
+ {
+ /* Write data to SDIO Tx FIFO */
+ for (count = 0; count < 8; count++)
+ {
+ SDIO_WriteFIFO(hsd->Instance, (tempbuff + count));
+ }
+
+ tempbuff += 8;
+ bytestransferred += 32;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* In case of single data block transfer no need of stop command at all */
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))
+ {
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE))
+ {
+ if ((totalnumberofbytes - bytestransferred) < 32)
+ {
+ restwords = ((totalnumberofbytes - bytestransferred) % 4 == 0) ? ((totalnumberofbytes - bytestransferred) / 4) : (( totalnumberofbytes - bytestransferred) / 4 + 1);
+
+ /* Write data to SDIO Tx FIFO */
+ for (count = 0; count < restwords; count++)
+ {
+ SDIO_WriteFIFO(hsd->Instance, tempbuff);
+ tempbuff++;
+ bytestransferred += 4;
+ }
+ }
+ else
+ {
+ /* Write data to SDIO Tx FIFO */
+ for (count = 0; count < 8; count++)
+ {
+ SDIO_WriteFIFO(hsd->Instance, (tempbuff + count));
+ }
+
+ tempbuff += 8;
+ bytestransferred += 32;
+ }
+ }
+ }
+ }
+
+ /* Send stop transmission command in case of multiblock write */
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1))
+ {
+ if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
+ (hsd->CardType == HIGH_CAPACITY_SD_CARD))
+ {
+ /* Send stop transmission command */
+ errorstate = HAL_SD_StopTransfer(hsd);
+ }
+ }
+
+ /* Get error state */
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
+
+ errorstate = SD_DATA_TIMEOUT;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
+
+ errorstate = SD_DATA_CRC_FAIL;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_TXUNDERR);
+
+ errorstate = SD_TX_UNDERRUN;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);
+
+ errorstate = SD_START_BIT_ERR;
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ /* Wait till the card is in programming state */
+ errorstate = SD_IsCardProgramming(hsd, &cardstate);
+
+ while ((errorstate == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
+ {
+ errorstate = SD_IsCardProgramming(hsd, &cardstate);
+ }
+
+ return errorstate;
+}
+
+/**
+ * @brief Reads block(s) from a specified address in a card. The Data transfer
+ * is managed by DMA mode.
+ * @note This API should be followed by the function HAL_SD_CheckReadOperation()
+ * to check the completion of the read process
+ * @param hsd: SD handle
+ * @param pReadBuffer: Pointer to the buffer that will contain the received data
+ * @param ReadAddr: Address from where data is to be read
+ * @param BlockSize: SD card Data block size
+ * @note BlockSize must be 512 bytes.
+ * @param NumberOfBlocks: Number of blocks to read.
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ SDIO_DataInitTypeDef sdio_datainitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0;
+
+ /* Initialize handle flags */
+ hsd->SdTransferCplt = 0;
+ hsd->DmaTransferCplt = 0;
+ hsd->SdTransferErr = SD_OK;
+
+ /* Initialize SD Read operation */
+ if(NumberOfBlocks > 1)
+ {
+ hsd->SdOperation = SD_READ_MULTIPLE_BLOCK;
+ }
+ else
+ {
+ hsd->SdOperation = SD_READ_SINGLE_BLOCK;
+ }
+
+ /* Enable transfer interrupts */
+ __HAL_SD_SDIO_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL |\
+ SDIO_IT_DTIMEOUT |\
+ SDIO_IT_DATAEND |\
+ SDIO_IT_RXOVERR |\
+ SDIO_IT_STBITERR));
+
+ /* Enable SDIO DMA transfer */
+ __HAL_SD_SDIO_DMA_ENABLE(hsd);
+
+ /* Configure DMA user callbacks */
+ hsd->hdmarx->XferCpltCallback = SD_DMA_RxCplt;
+ hsd->hdmarx->XferErrorCallback = SD_DMA_RxError;
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks)/4);
+
+ if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
+ {
+ BlockSize = 512;
+ ReadAddr /= 512;
+ }
+
+ /* Set Block Size for Card */
+ sdio_cmdinitstructure.Argument = (uint32_t)BlockSize;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
+ sdio_datainitstructure.DataLength = BlockSize * NumberOfBlocks;
+ sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
+
+ /* Check number of blocks command */
+ if(NumberOfBlocks > 1)
+ {
+ /* Send CMD18 READ_MULT_BLOCK with argument data address */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_MULT_BLOCK;
+ }
+ else
+ {
+ /* Send CMD17 READ_SINGLE_BLOCK */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
+ }
+
+ sdio_cmdinitstructure.Argument = (uint32_t)ReadAddr;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ if(NumberOfBlocks > 1)
+ {
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK);
+ }
+ else
+ {
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK);
+ }
+
+ /* Update the SD transfer error in SD handle */
+ hsd->SdTransferErr = errorstate;
+
+ return errorstate;
+}
+
+
+/**
+ * @brief Writes block(s) to a specified address in a card. The Data transfer
+ * is managed by DMA mode.
+ * @note This API should be followed by the function HAL_SD_CheckWriteOperation()
+ * to check the completion of the write process (by SD current status polling).
+ * @param hsd: SD handle
+ * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit
+ * @param WriteAddr: Address from where data is to be read
+ * @param BlockSize: the SD card Data block size
+ * @note BlockSize must be 512 bytes.
+ * @param NumberOfBlocks: Number of blocks to write
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ SDIO_DataInitTypeDef sdio_datainitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0;
+
+ /* Initialize handle flags */
+ hsd->SdTransferCplt = 0;
+ hsd->DmaTransferCplt = 0;
+ hsd->SdTransferErr = SD_OK;
+
+ /* Initialize SD Write operation */
+ if(NumberOfBlocks > 1)
+ {
+ hsd->SdOperation = SD_WRITE_MULTIPLE_BLOCK;
+ }
+ else
+ {
+ hsd->SdOperation = SD_WRITE_SINGLE_BLOCK;
+ }
+
+ /* Enable transfer interrupts */
+ __HAL_SD_SDIO_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL |\
+ SDIO_IT_DTIMEOUT |\
+ SDIO_IT_DATAEND |\
+ SDIO_IT_TXUNDERR |\
+ SDIO_IT_STBITERR));
+
+ /* Configure DMA user callbacks */
+ hsd->hdmatx->XferCpltCallback = SD_DMA_TxCplt;
+ hsd->hdmatx->XferErrorCallback = SD_DMA_TxError;
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pWriteBuffer, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BlockSize * NumberOfBlocks)/4);
+
+ /* Enable SDIO DMA transfer */
+ __HAL_SD_SDIO_DMA_ENABLE(hsd);
+
+ if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
+ {
+ BlockSize = 512;
+ WriteAddr /= 512;
+ }
+
+ /* Set Block Size for Card */
+ sdio_cmdinitstructure.Argument = (uint32_t)BlockSize;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Check number of blocks command */
+ if(NumberOfBlocks <= 1)
+ {
+ /* Send CMD24 WRITE_SINGLE_BLOCK */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
+ }
+ else
+ {
+ /* Send CMD25 WRITE_MULT_BLOCK with argument data address */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
+ }
+
+ sdio_cmdinitstructure.Argument = (uint32_t)WriteAddr;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ if(NumberOfBlocks > 1)
+ {
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK);
+ }
+ else
+ {
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK);
+ }
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
+ sdio_datainitstructure.DataLength = BlockSize * NumberOfBlocks;
+ sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
+ sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
+
+ hsd->SdTransferErr = errorstate;
+
+ return errorstate;
+}
+
+/**
+ * @brief This function waits until the SD DMA data read transfer is finished.
+ * This API should be called after HAL_SD_ReadBlocks_DMA() function
+ * to insure that all data sent by the card is already transferred by the
+ * DMA controller.
+ * @param hsd: SD handle
+ * @param Timeout: Timeout duration
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t timeout = Timeout;
+ uint32_t tmp1, tmp2;
+ HAL_SD_ErrorTypedef tmp3;
+
+ /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */
+ tmp1 = hsd->DmaTransferCplt;
+ tmp2 = hsd->SdTransferCplt;
+ tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
+
+ while (((tmp1 & tmp2) == 0) && (tmp3 == SD_OK) && (timeout > 0))
+ {
+ tmp1 = hsd->DmaTransferCplt;
+ tmp2 = hsd->SdTransferCplt;
+ tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
+ timeout--;
+ }
+
+ timeout = Timeout;
+
+ /* Wait until the Rx transfer is no longer active */
+ while((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXACT)) && (timeout > 0))
+ {
+ timeout--;
+ }
+
+ /* Send stop command in multiblock read */
+ if (hsd->SdOperation == SD_READ_MULTIPLE_BLOCK)
+ {
+ errorstate = HAL_SD_StopTransfer(hsd);
+ }
+
+ if ((timeout == 0) && (errorstate == SD_OK))
+ {
+ errorstate = SD_DATA_TIMEOUT;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ /* Return error state */
+ if (hsd->SdTransferErr != SD_OK)
+ {
+ return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);
+ }
+
+ return errorstate;
+}
+
+/**
+ * @brief This function waits until the SD DMA data write transfer is finished.
+ * This API should be called after HAL_SD_WriteBlocks_DMA() function
+ * to insure that all data sent by the card is already transferred by the
+ * DMA controller.
+ * @param hsd: SD handle
+ * @param Timeout: Timeout duration
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t timeout = Timeout;
+ uint32_t tmp1, tmp2;
+ HAL_SD_ErrorTypedef tmp3;
+
+ /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */
+ tmp1 = hsd->DmaTransferCplt;
+ tmp2 = hsd->SdTransferCplt;
+ tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
+
+ while (((tmp1 & tmp2) == 0) && (tmp3 == SD_OK) && (timeout > 0))
+ {
+ tmp1 = hsd->DmaTransferCplt;
+ tmp2 = hsd->SdTransferCplt;
+ tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
+ timeout--;
+ }
+
+ timeout = Timeout;
+
+ /* Wait until the Tx transfer is no longer active */
+ while((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXACT)) && (timeout > 0))
+ {
+ timeout--;
+ }
+
+ /* Send stop command in multiblock write */
+ if (hsd->SdOperation == SD_WRITE_MULTIPLE_BLOCK)
+ {
+ errorstate = HAL_SD_StopTransfer(hsd);
+ }
+
+ if ((timeout == 0) && (errorstate == SD_OK))
+ {
+ errorstate = SD_DATA_TIMEOUT;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ /* Return error state */
+ if (hsd->SdTransferErr != SD_OK)
+ {
+ return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);
+ }
+
+ /* Wait until write is complete */
+ while(HAL_SD_GetStatus(hsd) != SD_TRANSFER_OK)
+ {
+ }
+
+ return errorstate;
+}
+
+/**
+ * @brief Erases the specified memory area of the given SD card.
+ * @param hsd: SD handle
+ * @param Startaddr: Start byte address
+ * @param Endaddr: End byte address
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t Startaddr, uint64_t Endaddr)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+
+ uint32_t delay = 0;
+ __IO uint32_t maxdelay = 0;
+ uint8_t cardstate = 0;
+
+ /* Check if the card command class supports erase command */
+ if (((hsd->CSD[1] >> 20) & SD_CCCC_ERASE) == 0)
+ {
+ errorstate = SD_REQUEST_NOT_APPLICABLE;
+
+ return errorstate;
+ }
+
+ /* Get max delay value */
+ maxdelay = 120000 / (((hsd->Instance->CLKCR) & 0xFF) + 2);
+
+ if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)
+ {
+ errorstate = SD_LOCK_UNLOCK_FAILED;
+
+ return errorstate;
+ }
+
+ /* Get start and end block for high capacity cards */
+ if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
+ {
+ Startaddr /= 512;
+ Endaddr /= 512;
+ }
+
+ /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
+ if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
+ (hsd->CardType == HIGH_CAPACITY_SD_CARD))
+ {
+ /* Send CMD32 SD_ERASE_GRP_START with argument as addr */
+ sdio_cmdinitstructure.Argument =(uint32_t)Startaddr;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_ERASE_GRP_START;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_START);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send CMD33 SD_ERASE_GRP_END with argument as addr */
+ sdio_cmdinitstructure.Argument = (uint32_t)Endaddr;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_ERASE_GRP_END;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_END);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+ }
+
+ /* Send CMD38 ERASE */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_ERASE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_ERASE);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ for (; delay < maxdelay; delay++)
+ {
+ }
+
+ /* Wait untill the card is in programming state */
+ errorstate = SD_IsCardProgramming(hsd, &cardstate);
+
+ delay = SD_DATATIMEOUT;
+
+ while ((delay > 0) && (errorstate == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
+ {
+ errorstate = SD_IsCardProgramming(hsd, &cardstate);
+ delay--;
+ }
+
+ return errorstate;
+}
+
+/**
+ * @brief This function handles SD card interrupt request.
+ * @param hsd: SD handle
+ * @retval None
+ */
+void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd)
+{
+ /* Check for SDIO interrupt flags */
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DATAEND))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_IT_DATAEND);
+
+ /* SD transfer is complete */
+ hsd->SdTransferCplt = 1;
+
+ /* No transfer error */
+ hsd->SdTransferErr = SD_OK;
+
+ HAL_SD_XferCpltCallback(hsd);
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DCRCFAIL))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
+
+ hsd->SdTransferErr = SD_DATA_CRC_FAIL;
+
+ HAL_SD_XferErrorCallback(hsd);
+
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DTIMEOUT))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
+
+ hsd->SdTransferErr = SD_DATA_TIMEOUT;
+
+ HAL_SD_XferErrorCallback(hsd);
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_RXOVERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
+
+ hsd->SdTransferErr = SD_RX_OVERRUN;
+
+ HAL_SD_XferErrorCallback(hsd);
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_TXUNDERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_TXUNDERR);
+
+ hsd->SdTransferErr = SD_TX_UNDERRUN;
+
+ HAL_SD_XferErrorCallback(hsd);
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_STBITERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);
+
+ hsd->SdTransferErr = SD_START_BIT_ERR;
+
+ HAL_SD_XferErrorCallback(hsd);
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ /* Disable all SDIO peripheral interrupt sources */
+ __HAL_SD_SDIO_DISABLE_IT(hsd, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |\
+ SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |\
+ SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
+}
+
+
+/**
+ * @brief SD end of transfer callback.
+ * @param hsd: SD handle
+ * @retval None
+ */
+__weak void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_XferCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SD Transfer Error callback.
+ * @param hsd: SD handle
+ * @retval None
+ */
+__weak void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_XferErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SD Transfer complete Rx callback in non blocking mode.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+__weak void HAL_SD_DMA_RxCpltCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_DMA_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SD DMA transfer complete Rx error callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+__weak void HAL_SD_DMA_RxErrorCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_DMA_RxErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SD Transfer complete Tx callback in non blocking mode.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+__weak void HAL_SD_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_DMA_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SD DMA transfer complete error Tx callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+__weak void HAL_SD_DMA_TxErrorCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_DMA_TxErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions_Group3 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the SD card
+ operations.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns information about specific card.
+ * @param hsd: SD handle
+ * @param pCardInfo: Pointer to a HAL_SD_CardInfoTypedef structure that
+ * contains all SD cardinformation
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_Get_CardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *pCardInfo)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t tmp = 0;
+
+ pCardInfo->CardType = (uint8_t)(hsd->CardType);
+ pCardInfo->RCA = (uint16_t)(hsd->RCA);
+
+ /* Byte 0 */
+ tmp = (hsd->CSD[0] & 0xFF000000) >> 24;
+ pCardInfo->SD_csd.CSDStruct = (uint8_t)((tmp & 0xC0) >> 6);
+ pCardInfo->SD_csd.SysSpecVersion = (uint8_t)((tmp & 0x3C) >> 2);
+ pCardInfo->SD_csd.Reserved1 = tmp & 0x03;
+
+ /* Byte 1 */
+ tmp = (hsd->CSD[0] & 0x00FF0000) >> 16;
+ pCardInfo->SD_csd.TAAC = (uint8_t)tmp;
+
+ /* Byte 2 */
+ tmp = (hsd->CSD[0] & 0x0000FF00) >> 8;
+ pCardInfo->SD_csd.NSAC = (uint8_t)tmp;
+
+ /* Byte 3 */
+ tmp = hsd->CSD[0] & 0x000000FF;
+ pCardInfo->SD_csd.MaxBusClkFrec = (uint8_t)tmp;
+
+ /* Byte 4 */
+ tmp = (hsd->CSD[1] & 0xFF000000) >> 24;
+ pCardInfo->SD_csd.CardComdClasses = (uint16_t)(tmp << 4);
+
+ /* Byte 5 */
+ tmp = (hsd->CSD[1] & 0x00FF0000) >> 16;
+ pCardInfo->SD_csd.CardComdClasses |= (uint16_t)((tmp & 0xF0) >> 4);
+ pCardInfo->SD_csd.RdBlockLen = (uint8_t)(tmp & 0x0F);
+
+ /* Byte 6 */
+ tmp = (hsd->CSD[1] & 0x0000FF00) >> 8;
+ pCardInfo->SD_csd.PartBlockRead = (uint8_t)((tmp & 0x80) >> 7);
+ pCardInfo->SD_csd.WrBlockMisalign = (uint8_t)((tmp & 0x40) >> 6);
+ pCardInfo->SD_csd.RdBlockMisalign = (uint8_t)((tmp & 0x20) >> 5);
+ pCardInfo->SD_csd.DSRImpl = (uint8_t)((tmp & 0x10) >> 4);
+ pCardInfo->SD_csd.Reserved2 = 0; /*!< Reserved */
+
+ if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0))
+ {
+ pCardInfo->SD_csd.DeviceSize = (tmp & 0x03) << 10;
+
+ /* Byte 7 */
+ tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF);
+ pCardInfo->SD_csd.DeviceSize |= (tmp) << 2;
+
+ /* Byte 8 */
+ tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24);
+ pCardInfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6;
+
+ pCardInfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3;
+ pCardInfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07);
+
+ /* Byte 9 */
+ tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16);
+ pCardInfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;
+ pCardInfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;
+ pCardInfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1;
+ /* Byte 10 */
+ tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8);
+ pCardInfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7;
+
+ pCardInfo->CardCapacity = (pCardInfo->SD_csd.DeviceSize + 1) ;
+ pCardInfo->CardCapacity *= (1 << (pCardInfo->SD_csd.DeviceSizeMul + 2));
+ pCardInfo->CardBlockSize = 1 << (pCardInfo->SD_csd.RdBlockLen);
+ pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;
+ }
+ else if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
+ {
+ /* Byte 7 */
+ tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF);
+ pCardInfo->SD_csd.DeviceSize = (tmp & 0x3F) << 16;
+
+ /* Byte 8 */
+ tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24);
+
+ pCardInfo->SD_csd.DeviceSize |= (tmp << 8);
+
+ /* Byte 9 */
+ tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16);
+
+ pCardInfo->SD_csd.DeviceSize |= (tmp);
+
+ /* Byte 10 */
+ tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8);
+
+ pCardInfo->CardCapacity = (uint64_t)(((uint64_t)pCardInfo->SD_csd.DeviceSize + 1) * 512 * 1024);
+ pCardInfo->CardBlockSize = 512;
+ }
+ else
+ {
+ /* Not supported card type */
+ errorstate = SD_ERROR;
+ }
+
+ pCardInfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6;
+ pCardInfo->SD_csd.EraseGrMul = (tmp & 0x3F) << 1;
+
+ /* Byte 11 */
+ tmp = (uint8_t)(hsd->CSD[2] & 0x000000FF);
+ pCardInfo->SD_csd.EraseGrMul |= (tmp & 0x80) >> 7;
+ pCardInfo->SD_csd.WrProtectGrSize = (tmp & 0x7F);
+
+ /* Byte 12 */
+ tmp = (uint8_t)((hsd->CSD[3] & 0xFF000000) >> 24);
+ pCardInfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7;
+ pCardInfo->SD_csd.ManDeflECC = (tmp & 0x60) >> 5;
+ pCardInfo->SD_csd.WrSpeedFact = (tmp & 0x1C) >> 2;
+ pCardInfo->SD_csd.MaxWrBlockLen = (tmp & 0x03) << 2;
+
+ /* Byte 13 */
+ tmp = (uint8_t)((hsd->CSD[3] & 0x00FF0000) >> 16);
+ pCardInfo->SD_csd.MaxWrBlockLen |= (tmp & 0xC0) >> 6;
+ pCardInfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5;
+ pCardInfo->SD_csd.Reserved3 = 0;
+ pCardInfo->SD_csd.ContentProtectAppli = (tmp & 0x01);
+
+ /* Byte 14 */
+ tmp = (uint8_t)((hsd->CSD[3] & 0x0000FF00) >> 8);
+ pCardInfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7;
+ pCardInfo->SD_csd.CopyFlag = (tmp & 0x40) >> 6;
+ pCardInfo->SD_csd.PermWrProtect = (tmp & 0x20) >> 5;
+ pCardInfo->SD_csd.TempWrProtect = (tmp & 0x10) >> 4;
+ pCardInfo->SD_csd.FileFormat = (tmp & 0x0C) >> 2;
+ pCardInfo->SD_csd.ECC = (tmp & 0x03);
+
+ /* Byte 15 */
+ tmp = (uint8_t)(hsd->CSD[3] & 0x000000FF);
+ pCardInfo->SD_csd.CSD_CRC = (tmp & 0xFE) >> 1;
+ pCardInfo->SD_csd.Reserved4 = 1;
+
+ /* Byte 0 */
+ tmp = (uint8_t)((hsd->CID[0] & 0xFF000000) >> 24);
+ pCardInfo->SD_cid.ManufacturerID = tmp;
+
+ /* Byte 1 */
+ tmp = (uint8_t)((hsd->CID[0] & 0x00FF0000) >> 16);
+ pCardInfo->SD_cid.OEM_AppliID = tmp << 8;
+
+ /* Byte 2 */
+ tmp = (uint8_t)((hsd->CID[0] & 0x000000FF00) >> 8);
+ pCardInfo->SD_cid.OEM_AppliID |= tmp;
+
+ /* Byte 3 */
+ tmp = (uint8_t)(hsd->CID[0] & 0x000000FF);
+ pCardInfo->SD_cid.ProdName1 = tmp << 24;
+
+ /* Byte 4 */
+ tmp = (uint8_t)((hsd->CID[1] & 0xFF000000) >> 24);
+ pCardInfo->SD_cid.ProdName1 |= tmp << 16;
+
+ /* Byte 5 */
+ tmp = (uint8_t)((hsd->CID[1] & 0x00FF0000) >> 16);
+ pCardInfo->SD_cid.ProdName1 |= tmp << 8;
+
+ /* Byte 6 */
+ tmp = (uint8_t)((hsd->CID[1] & 0x0000FF00) >> 8);
+ pCardInfo->SD_cid.ProdName1 |= tmp;
+
+ /* Byte 7 */
+ tmp = (uint8_t)(hsd->CID[1] & 0x000000FF);
+ pCardInfo->SD_cid.ProdName2 = tmp;
+
+ /* Byte 8 */
+ tmp = (uint8_t)((hsd->CID[2] & 0xFF000000) >> 24);
+ pCardInfo->SD_cid.ProdRev = tmp;
+
+ /* Byte 9 */
+ tmp = (uint8_t)((hsd->CID[2] & 0x00FF0000) >> 16);
+ pCardInfo->SD_cid.ProdSN = tmp << 24;
+
+ /* Byte 10 */
+ tmp = (uint8_t)((hsd->CID[2] & 0x0000FF00) >> 8);
+ pCardInfo->SD_cid.ProdSN |= tmp << 16;
+
+ /* Byte 11 */
+ tmp = (uint8_t)(hsd->CID[2] & 0x000000FF);
+ pCardInfo->SD_cid.ProdSN |= tmp << 8;
+
+ /* Byte 12 */
+ tmp = (uint8_t)((hsd->CID[3] & 0xFF000000) >> 24);
+ pCardInfo->SD_cid.ProdSN |= tmp;
+
+ /* Byte 13 */
+ tmp = (uint8_t)((hsd->CID[3] & 0x00FF0000) >> 16);
+ pCardInfo->SD_cid.Reserved1 |= (tmp & 0xF0) >> 4;
+ pCardInfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8;
+
+ /* Byte 14 */
+ tmp = (uint8_t)((hsd->CID[3] & 0x0000FF00) >> 8);
+ pCardInfo->SD_cid.ManufactDate |= tmp;
+
+ /* Byte 15 */
+ tmp = (uint8_t)(hsd->CID[3] & 0x000000FF);
+ pCardInfo->SD_cid.CID_CRC = (tmp & 0xFE) >> 1;
+ pCardInfo->SD_cid.Reserved2 = 1;
+
+ return errorstate;
+}
+
+/**
+ * @brief Enables wide bus operation for the requested card if supported by
+ * card.
+ * @param hsd: SD handle
+ * @param WideMode: Specifies the SD card wide bus mode
+ * This parameter can be one of the following values:
+ * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer (Only for MMC)
+ * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
+ * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_WideBusOperation_Config(SD_HandleTypeDef *hsd, uint32_t WideMode)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ SDIO_InitTypeDef init = {0};
+
+ /* MMC Card does not support this feature */
+ if (hsd->CardType == MULTIMEDIA_CARD)
+ {
+ errorstate = SD_UNSUPPORTED_FEATURE;
+ }
+ else if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
+ (hsd->CardType == HIGH_CAPACITY_SD_CARD))
+ {
+ if (WideMode == SDIO_BUS_WIDE_8B)
+ {
+ errorstate = SD_UNSUPPORTED_FEATURE;
+ }
+ else if (WideMode == SDIO_BUS_WIDE_4B)
+ {
+ errorstate = SD_WideBus_Enable(hsd);
+ }
+ else if (WideMode == SDIO_BUS_WIDE_1B)
+ {
+ errorstate = SD_WideBus_Disable(hsd);
+ }
+ else
+ {
+ /* WideMode is not a valid argument*/
+ errorstate = SD_INVALID_PARAMETER;
+ }
+
+ if (errorstate == SD_OK)
+ {
+ /* Configure the SDIO peripheral */
+ init.ClockEdge = hsd->Init.ClockEdge;
+ init.ClockBypass = hsd->Init.ClockBypass;
+ init.ClockPowerSave = hsd->Init.ClockPowerSave;
+ init.BusWide = WideMode;
+ init.HardwareFlowControl = hsd->Init.HardwareFlowControl;
+ init.ClockDiv = hsd->Init.ClockDiv;
+
+ /* Configure SDIO peripheral interface */
+ SDIO_Init(hsd->Instance, init);
+ }
+ else
+ {
+ /* An error occured while enabling/disabling the wide bus*/
+ }
+ }
+ else
+ {
+ /* Not supported card type */
+ errorstate = SD_ERROR;
+ }
+
+ return errorstate;
+}
+
+/**
+ * @brief Aborts an ongoing data transfer.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_StopTransfer(SD_HandleTypeDef *hsd)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ /* Send CMD12 STOP_TRANSMISSION */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_STOP_TRANSMISSION;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_STOP_TRANSMISSION);
+
+ return errorstate;
+}
+
+/**
+ * @brief Switches the SD card to High Speed mode.
+ * This API must be used after "Transfer State"
+ * @note This operation should be followed by the configuration
+ * of PLL to have SDIOCK clock between 67 and 75 MHz
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_HighSpeed (SD_HandleTypeDef *hsd)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ SDIO_DataInitTypeDef sdio_datainitstructure = {0};
+
+ uint8_t SD_hs[64] = {0};
+ uint32_t SD_scr[2] = {0, 0};
+ uint32_t SD_SPEC = 0 ;
+ uint32_t count = 0, *tempbuff = (uint32_t *)SD_hs;
+
+ /* Initialize the Data control register */
+ hsd->Instance->DCTRL = 0;
+
+ /* Get SCR Register */
+ errorstate = SD_FindSCR(hsd, SD_scr);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Test the Version supported by the card*/
+ SD_SPEC = (SD_scr[1] & 0x01000000) | (SD_scr[1] & 0x02000000);
+
+ if (SD_SPEC != SD_ALLZERO)
+ {
+ /* Set Block Size for Card */
+ sdio_cmdinitstructure.Argument = (uint32_t)64;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
+ sdio_datainitstructure.DataLength = 64;
+ sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_64B ;
+ sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
+
+ /* Send CMD6 switch mode */
+ sdio_cmdinitstructure.Argument = 0x80FFFF01;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_HS_SWITCH;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_HS_SWITCH);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))
+ {
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
+ {
+ for (count = 0; count < 8; count++)
+ {
+ *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);
+ }
+
+ tempbuff += 8;
+ }
+ }
+
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
+
+ errorstate = SD_DATA_TIMEOUT;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
+
+ errorstate = SD_DATA_CRC_FAIL;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
+
+ errorstate = SD_RX_OVERRUN;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);
+
+ errorstate = SD_START_BIT_ERR;
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ count = SD_DATATIMEOUT;
+
+ while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0))
+ {
+ *tempbuff = SDIO_ReadFIFO(hsd->Instance);
+ tempbuff++;
+ count--;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ /* Test if the switch mode HS is ok */
+ if ((SD_hs[13]& 2) != 2)
+ {
+ errorstate = SD_UNSUPPORTED_FEATURE;
+ }
+ }
+
+ return errorstate;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in runtime the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the current SD card's status.
+ * @param hsd: SD handle
+ * @param pSDstatus: Pointer to the buffer that will contain the SD card status
+ * SD Status register)
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ SDIO_DataInitTypeDef sdio_datainitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t count = 0;
+
+ /* Check SD response */
+ if ((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)
+ {
+ errorstate = SD_LOCK_UNLOCK_FAILED;
+
+ return errorstate;
+ }
+
+ /* Set block size for card if it is not equal to current block size for card */
+ sdio_cmdinitstructure.Argument = 64;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send CMD55 */
+ sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
+ sdio_datainitstructure.DataLength = 64;
+ sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;
+ sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
+
+ /* Send ACMD13 (SD_APP_STAUS) with argument as card's RCA */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_STATUS;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_STATUS);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Get status data */
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))
+ {
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
+ {
+ for (count = 0; count < 8; count++)
+ {
+ *(pSDstatus + count) = SDIO_ReadFIFO(hsd->Instance);
+ }
+
+ pSDstatus += 8;
+ }
+ }
+
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
+
+ errorstate = SD_DATA_TIMEOUT;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
+
+ errorstate = SD_DATA_CRC_FAIL;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
+
+ errorstate = SD_RX_OVERRUN;
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);
+
+ errorstate = SD_START_BIT_ERR;
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ count = SD_DATATIMEOUT;
+ while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0))
+ {
+ *pSDstatus = SDIO_ReadFIFO(hsd->Instance);
+ pSDstatus++;
+ count--;
+ }
+
+ /* Clear all the static status flags*/
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ return errorstate;
+}
+
+/**
+ * @brief Gets the current sd card data status.
+ * @param hsd: SD handle
+ * @retval Data Transfer state
+ */
+HAL_SD_TransferStateTypedef HAL_SD_GetStatus(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_CardStateTypedef cardstate = SD_CARD_TRANSFER;
+
+ /* Get SD card state */
+ cardstate = SD_GetState(hsd);
+
+ /* Find SD status according to card state*/
+ if (cardstate == SD_CARD_TRANSFER)
+ {
+ return SD_TRANSFER_OK;
+ }
+ else if(cardstate == SD_CARD_ERROR)
+ {
+ return SD_TRANSFER_ERROR;
+ }
+ else
+ {
+ return SD_TRANSFER_BUSY;
+ }
+}
+
+/**
+ * @brief Gets the SD card status.
+ * @param hsd: SD handle
+ * @param pCardStatus: Pointer to the HAL_SD_CardStatusTypedef structure that
+ * will contain the SD card status information
+ * @retval SD Card error state
+ */
+HAL_SD_ErrorTypedef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypedef *pCardStatus)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t tmp = 0;
+ uint32_t sd_status[16];
+
+ errorstate = HAL_SD_SendSDStatus(hsd, sd_status);
+
+ if (errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Byte 0 */
+ tmp = (sd_status[0] & 0xC0) >> 6;
+ pCardStatus->DAT_BUS_WIDTH = (uint8_t)tmp;
+
+ /* Byte 0 */
+ tmp = (sd_status[0] & 0x20) >> 5;
+ pCardStatus->SECURED_MODE = (uint8_t)tmp;
+
+ /* Byte 2 */
+ tmp = (sd_status[2] & 0xFF);
+ pCardStatus->SD_CARD_TYPE = (uint8_t)(tmp << 8);
+
+ /* Byte 3 */
+ tmp = (sd_status[3] & 0xFF);
+ pCardStatus->SD_CARD_TYPE |= (uint8_t)tmp;
+
+ /* Byte 4 */
+ tmp = (sd_status[4] & 0xFF);
+ pCardStatus->SIZE_OF_PROTECTED_AREA = (uint8_t)(tmp << 24);
+
+ /* Byte 5 */
+ tmp = (sd_status[5] & 0xFF);
+ pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 16);
+
+ /* Byte 6 */
+ tmp = (sd_status[6] & 0xFF);
+ pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 8);
+
+ /* Byte 7 */
+ tmp = (sd_status[7] & 0xFF);
+ pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)tmp;
+
+ /* Byte 8 */
+ tmp = (sd_status[8] & 0xFF);
+ pCardStatus->SPEED_CLASS = (uint8_t)tmp;
+
+ /* Byte 9 */
+ tmp = (sd_status[9] & 0xFF);
+ pCardStatus->PERFORMANCE_MOVE = (uint8_t)tmp;
+
+ /* Byte 10 */
+ tmp = (sd_status[10] & 0xF0) >> 4;
+ pCardStatus->AU_SIZE = (uint8_t)tmp;
+
+ /* Byte 11 */
+ tmp = (sd_status[11] & 0xFF);
+ pCardStatus->ERASE_SIZE = (uint8_t)(tmp << 8);
+
+ /* Byte 12 */
+ tmp = (sd_status[12] & 0xFF);
+ pCardStatus->ERASE_SIZE |= (uint8_t)tmp;
+
+ /* Byte 13 */
+ tmp = (sd_status[13] & 0xFC) >> 2;
+ pCardStatus->ERASE_TIMEOUT = (uint8_t)tmp;
+
+ /* Byte 13 */
+ tmp = (sd_status[13] & 0x3);
+ pCardStatus->ERASE_OFFSET = (uint8_t)tmp;
+
+ return errorstate;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup SD_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief SD DMA transfer complete Rx callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ /* DMA transfer is complete */
+ hsd->DmaTransferCplt = 1;
+
+ /* Wait until SD transfer is complete */
+ while(hsd->SdTransferCplt == 0)
+ {
+ }
+
+ /* Transfer complete user callback */
+ HAL_SD_DMA_RxCpltCallback(hsd->hdmarx);
+}
+
+/**
+ * @brief SD DMA transfer Error Rx callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SD_DMA_RxError(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ /* Transfer complete user callback */
+ HAL_SD_DMA_RxErrorCallback(hsd->hdmarx);
+}
+
+/**
+ * @brief SD DMA transfer complete Tx callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ /* DMA transfer is complete */
+ hsd->DmaTransferCplt = 1;
+
+ /* Wait until SD transfer is complete */
+ while(hsd->SdTransferCplt == 0)
+ {
+ }
+
+ /* Transfer complete user callback */
+ HAL_SD_DMA_TxCpltCallback(hsd->hdmatx);
+}
+
+/**
+ * @brief SD DMA transfer Error Tx callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SD_DMA_TxError(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef *hsd = ( SD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Transfer complete user callback */
+ HAL_SD_DMA_TxErrorCallback(hsd->hdmatx);
+}
+
+/**
+ * @brief Returns the SD current state.
+ * @param hsd: SD handle
+ * @retval SD card current state
+ */
+static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd)
+{
+ uint32_t resp1 = 0;
+
+ if (SD_SendStatus(hsd, &resp1) != SD_OK)
+ {
+ return SD_CARD_ERROR;
+ }
+ else
+ {
+ return (HAL_SD_CardStateTypedef)((resp1 >> 9) & 0x0F);
+ }
+}
+
+/**
+ * @brief Initializes all cards or single card as the case may be Card(s) come
+ * into standby state.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint16_t sd_rca = 1;
+
+ if(SDIO_GetPowerState(hsd->Instance) == 0) /* Power off */
+ {
+ errorstate = SD_REQUEST_NOT_APPLICABLE;
+
+ return errorstate;
+ }
+
+ if(hsd->CardType != SECURE_DIGITAL_IO_CARD)
+ {
+ /* Send CMD2 ALL_SEND_CID */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_ALL_SEND_CID;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_LONG;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp2Error(hsd);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Get Card identification number data */
+ hsd->CID[0] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+ hsd->CID[1] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
+ hsd->CID[2] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
+ hsd->CID[3] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
+ }
+
+ if((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
+ (hsd->CardType == SECURE_DIGITAL_IO_COMBO_CARD) || (hsd->CardType == HIGH_CAPACITY_SD_CARD))
+ {
+ /* Send CMD3 SET_REL_ADDR with argument 0 */
+ /* SD Card publishes its RCA. */
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_REL_ADDR;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp6Error(hsd, SD_CMD_SET_REL_ADDR, &sd_rca);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+ }
+
+ if (hsd->CardType != SECURE_DIGITAL_IO_CARD)
+ {
+ /* Get the SD card RCA */
+ hsd->RCA = sd_rca;
+
+ /* Send CMD9 SEND_CSD with argument as card's RCA */
+ sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SEND_CSD;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_LONG;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp2Error(hsd);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Get Card Specific Data */
+ hsd->CSD[0] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+ hsd->CSD[1] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
+ hsd->CSD[2] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
+ hsd->CSD[3] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
+ }
+
+ /* All cards are initialized */
+ return errorstate;
+}
+
+/**
+ * @brief Selects od Deselects the corresponding card.
+ * @param hsd: SD handle
+ * @param Addr: Address of the card to be selected
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t Addr)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ /* Send CMD7 SDIO_SEL_DESEL_CARD */
+ sdio_cmdinitstructure.Argument = (uint32_t)Addr;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SEL_DESEL_CARD;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SEL_DESEL_CARD);
+
+ return errorstate;
+}
+
+/**
+ * @brief Enquires cards about their operating voltage and configures clock
+ * controls and stores SD information that will be needed in future
+ * in the SD handle.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ __IO HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t response = 0, count = 0, validvoltage = 0;
+ uint32_t sdtype = SD_STD_CAPACITY;
+
+ /* Power ON Sequence -------------------------------------------------------*/
+ /* Disable SDIO Clock */
+ __HAL_SD_SDIO_DISABLE(hsd);
+
+ /* Set Power State to ON */
+ SDIO_PowerState_ON(hsd->Instance);
+
+ /* 1ms: required power up waiting time before starting the SD initialization
+ sequence */
+ HAL_Delay(1);
+
+ /* Enable SDIO Clock */
+ __HAL_SD_SDIO_ENABLE(hsd);
+
+ /* CMD0: GO_IDLE_STATE -----------------------------------------------------*/
+ /* No CMD response required */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_GO_IDLE_STATE;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_NO;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdError(hsd);
+
+ if(errorstate != SD_OK)
+ {
+ /* CMD Response TimeOut (wait for CMDSENT flag) */
+ return errorstate;
+ }
+
+ /* CMD8: SEND_IF_COND ------------------------------------------------------*/
+ /* Send CMD8 to verify SD card interface operating condition */
+ /* Argument: - [31:12]: Reserved (shall be set to '0')
+ - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
+ - [7:0]: Check Pattern (recommended 0xAA) */
+ /* CMD Response: R7 */
+ sdio_cmdinitstructure.Argument = SD_CHECK_PATTERN;
+ sdio_cmdinitstructure.CmdIndex = SD_SDIO_SEND_IF_COND;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp7Error(hsd);
+
+ if (errorstate == SD_OK)
+ {
+ /* SD Card 2.0 */
+ hsd->CardType = STD_CAPACITY_SD_CARD_V2_0;
+ sdtype = SD_HIGH_CAPACITY;
+ }
+
+ /* Send CMD55 */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
+
+ /* If errorstate is Command TimeOut, it is a MMC card */
+ /* If errorstate is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch)
+ or SD card 1.x */
+ if(errorstate == SD_OK)
+ {
+ /* SD CARD */
+ /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
+ while((!validvoltage) && (count < SD_MAX_VOLT_TRIAL))
+ {
+
+ /* SEND CMD55 APP_CMD with RCA as 0 */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send CMD41 */
+ sdio_cmdinitstructure.Argument = SD_VOLTAGE_WINDOW_SD | sdtype;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_OP_COND;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp3Error(hsd);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Get command response */
+ response = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+
+ /* Get operating voltage*/
+ validvoltage = (((response >> 31) == 1) ? 1 : 0);
+
+ count++;
+ }
+
+ if(count >= SD_MAX_VOLT_TRIAL)
+ {
+ errorstate = SD_INVALID_VOLTRANGE;
+
+ return errorstate;
+ }
+
+ if((response & SD_HIGH_CAPACITY) == SD_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */
+ {
+ hsd->CardType = HIGH_CAPACITY_SD_CARD;
+ }
+
+ } /* else MMC Card */
+
+ return errorstate;
+}
+
+/**
+ * @brief Turns the SDIO output signals off.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ /* Set Power State to OFF */
+ SDIO_PowerState_OFF(hsd->Instance);
+
+ return errorstate;
+}
+
+/**
+ * @brief Returns the current card's status.
+ * @param hsd: SD handle
+ * @param pCardStatus: pointer to the buffer that will contain the SD card
+ * status (Card Status register)
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ if(pCardStatus == NULL)
+ {
+ errorstate = SD_INVALID_PARAMETER;
+
+ return errorstate;
+ }
+
+ /* Send Status command */
+ sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SEND_STATUS;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SEND_STATUS);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Get SD card status */
+ *pCardStatus = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+
+ return errorstate;
+}
+
+/**
+ * @brief Checks for error conditions for CMD0.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t timeout = SDIO_CMD0TIMEOUT, tmp;
+
+ tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDSENT);
+
+ while((timeout > 0) && (!tmp))
+ {
+ tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDSENT);
+ timeout--;
+ }
+
+ if(timeout == 0)
+ {
+ errorstate = SD_CMD_RSP_TIMEOUT;
+ return errorstate;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ return errorstate;
+}
+
+/**
+ * @brief Checks for error conditions for R7 response.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_ERROR;
+ uint32_t timeout = SDIO_CMD0TIMEOUT, tmp;
+
+ tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT);
+
+ while((!tmp) && (timeout > 0))
+ {
+ tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT);
+ timeout--;
+ }
+
+ tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT);
+
+ if((timeout == 0) || tmp)
+ {
+ /* Card is not V2.0 compliant or card does not support the set voltage range */
+ errorstate = SD_CMD_RSP_TIMEOUT;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);
+
+ return errorstate;
+ }
+
+ if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDREND))
+ {
+ /* Card is SD V2.0 compliant */
+ errorstate = SD_OK;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CMDREND);
+
+ return errorstate;
+ }
+
+ return errorstate;
+}
+
+/**
+ * @brief Checks for error conditions for R1 response.
+ * @param hsd: SD handle
+ * @param SD_CMD: The sent command index
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t response_r1 = 0;
+
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))
+ {
+ }
+
+ if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))
+ {
+ errorstate = SD_CMD_RSP_TIMEOUT;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);
+
+ return errorstate;
+ }
+ else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL))
+ {
+ errorstate = SD_CMD_CRC_FAIL;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL);
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ /* Check response received is of desired command */
+ if(SDIO_GetCommandResponse(hsd->Instance) != SD_CMD)
+ {
+ errorstate = SD_ILLEGAL_CMD;
+
+ return errorstate;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ /* We have received response, retrieve it for analysis */
+ response_r1 = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+
+ if((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO)
+ {
+ return errorstate;
+ }
+
+ if((response_r1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE)
+ {
+ return(SD_ADDR_OUT_OF_RANGE);
+ }
+
+ if((response_r1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED)
+ {
+ return(SD_ADDR_MISALIGNED);
+ }
+
+ if((response_r1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR)
+ {
+ return(SD_BLOCK_LEN_ERR);
+ }
+
+ if((response_r1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR)
+ {
+ return(SD_ERASE_SEQ_ERR);
+ }
+
+ if((response_r1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM)
+ {
+ return(SD_BAD_ERASE_PARAM);
+ }
+
+ if((response_r1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION)
+ {
+ return(SD_WRITE_PROT_VIOLATION);
+ }
+
+ if((response_r1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED)
+ {
+ return(SD_LOCK_UNLOCK_FAILED);
+ }
+
+ if((response_r1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED)
+ {
+ return(SD_COM_CRC_FAILED);
+ }
+
+ if((response_r1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)
+ {
+ return(SD_ILLEGAL_CMD);
+ }
+
+ if((response_r1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED)
+ {
+ return(SD_CARD_ECC_FAILED);
+ }
+
+ if((response_r1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR)
+ {
+ return(SD_CC_ERROR);
+ }
+
+ if((response_r1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)
+ {
+ return(SD_GENERAL_UNKNOWN_ERROR);
+ }
+
+ if((response_r1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN)
+ {
+ return(SD_STREAM_READ_UNDERRUN);
+ }
+
+ if((response_r1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN)
+ {
+ return(SD_STREAM_WRITE_OVERRUN);
+ }
+
+ if((response_r1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE)
+ {
+ return(SD_CID_CSD_OVERWRITE);
+ }
+
+ if((response_r1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP)
+ {
+ return(SD_WP_ERASE_SKIP);
+ }
+
+ if((response_r1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED)
+ {
+ return(SD_CARD_ECC_DISABLED);
+ }
+
+ if((response_r1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET)
+ {
+ return(SD_ERASE_RESET);
+ }
+
+ if((response_r1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR)
+ {
+ return(SD_AKE_SEQ_ERROR);
+ }
+
+ return errorstate;
+}
+
+/**
+ * @brief Checks for error conditions for R3 (OCR) response.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ while (!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))
+ {
+ }
+
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))
+ {
+ errorstate = SD_CMD_RSP_TIMEOUT;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);
+
+ return errorstate;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ return errorstate;
+}
+
+/**
+ * @brief Checks for error conditions for R2 (CID or CSD) response.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ while (!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))
+ {
+ }
+
+ if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))
+ {
+ errorstate = SD_CMD_RSP_TIMEOUT;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);
+
+ return errorstate;
+ }
+ else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL))
+ {
+ errorstate = SD_CMD_CRC_FAIL;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL);
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ return errorstate;
+}
+
+/**
+ * @brief Checks for error conditions for R6 (RCA) response.
+ * @param hsd: SD handle
+ * @param SD_CMD: The sent command index
+ * @param pRCA: Pointer to the variable that will contain the SD card relative
+ * address RCA
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA)
+{
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t response_r1 = 0;
+
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))
+ {
+ }
+
+ if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))
+ {
+ errorstate = SD_CMD_RSP_TIMEOUT;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);
+
+ return errorstate;
+ }
+ else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL))
+ {
+ errorstate = SD_CMD_CRC_FAIL;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL);
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ /* Check response received is of desired command */
+ if(SDIO_GetCommandResponse(hsd->Instance) != SD_CMD)
+ {
+ errorstate = SD_ILLEGAL_CMD;
+
+ return errorstate;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ /* We have received response, retrieve it. */
+ response_r1 = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+
+ if((response_r1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED)) == SD_ALLZERO)
+ {
+ *pRCA = (uint16_t) (response_r1 >> 16);
+
+ return errorstate;
+ }
+
+ if((response_r1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR)
+ {
+ return(SD_GENERAL_UNKNOWN_ERROR);
+ }
+
+ if((response_r1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD)
+ {
+ return(SD_ILLEGAL_CMD);
+ }
+
+ if((response_r1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED)
+ {
+ return(SD_COM_CRC_FAILED);
+ }
+
+ return errorstate;
+}
+
+/**
+ * @brief Enables the SDIO wide bus mode.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ uint32_t scr[2] = {0, 0};
+
+ if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)
+ {
+ errorstate = SD_LOCK_UNLOCK_FAILED;
+
+ return errorstate;
+ }
+
+ /* Get SCR Register */
+ errorstate = SD_FindSCR(hsd, scr);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* If requested card supports wide bus operation */
+ if((scr[1] & SD_WIDE_BUS_SUPPORT) != SD_ALLZERO)
+ {
+ /* Send CMD55 APP_CMD with argument as card's RCA.*/
+ sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
+ sdio_cmdinitstructure.Argument = 2;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ return errorstate;
+ }
+ else
+ {
+ errorstate = SD_REQUEST_NOT_APPLICABLE;
+
+ return errorstate;
+ }
+}
+
+/**
+ * @brief Disables the SDIO wide bus mode.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+
+ uint32_t scr[2] = {0, 0};
+
+ if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)
+ {
+ errorstate = SD_LOCK_UNLOCK_FAILED;
+
+ return errorstate;
+ }
+
+ /* Get SCR Register */
+ errorstate = SD_FindSCR(hsd, scr);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* If requested card supports 1 bit mode operation */
+ if((scr[1] & SD_SINGLE_BUS_SUPPORT) != SD_ALLZERO)
+ {
+ /* Send CMD55 APP_CMD with argument as card's RCA */
+ sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ return errorstate;
+ }
+ else
+ {
+ errorstate = SD_REQUEST_NOT_APPLICABLE;
+
+ return errorstate;
+ }
+}
+
+
+/**
+ * @brief Finds the SD card SCR register value.
+ * @param hsd: SD handle
+ * @param pSCR: pointer to the buffer that will contain the SCR value
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ SDIO_DataInitTypeDef sdio_datainitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ uint32_t index = 0;
+ uint32_t tempscr[2] = {0, 0};
+
+ /* Set Block Size To 8 Bytes */
+ /* Send CMD55 APP_CMD with argument as card's RCA */
+ sdio_cmdinitstructure.Argument = (uint32_t)8;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send CMD55 APP_CMD with argument as card's RCA */
+ sdio_cmdinitstructure.Argument = (uint32_t)((hsd->RCA) << 16);
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+ sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
+ sdio_datainitstructure.DataLength = 8;
+ sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_8B;
+ sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
+
+ /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */
+ sdio_cmdinitstructure.Argument = 0;
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_SEND_SCR;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ /* Check for error conditions */
+ errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_SEND_SCR);
+
+ if(errorstate != SD_OK)
+ {
+ return errorstate;
+ }
+
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))
+ {
+ if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL))
+ {
+ *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance);
+ index++;
+ }
+ }
+
+ if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
+
+ errorstate = SD_DATA_TIMEOUT;
+
+ return errorstate;
+ }
+ else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
+
+ errorstate = SD_DATA_CRC_FAIL;
+
+ return errorstate;
+ }
+ else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
+
+ errorstate = SD_RX_OVERRUN;
+
+ return errorstate;
+ }
+ else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))
+ {
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);
+
+ errorstate = SD_START_BIT_ERR;
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ *(pSCR + 1) = ((tempscr[0] & SD_0TO7BITS) << 24) | ((tempscr[0] & SD_8TO15BITS) << 8) |\
+ ((tempscr[0] & SD_16TO23BITS) >> 8) | ((tempscr[0] & SD_24TO31BITS) >> 24);
+
+ *(pSCR) = ((tempscr[1] & SD_0TO7BITS) << 24) | ((tempscr[1] & SD_8TO15BITS) << 8) |\
+ ((tempscr[1] & SD_16TO23BITS) >> 8) | ((tempscr[1] & SD_24TO31BITS) >> 24);
+
+ return errorstate;
+}
+
+/**
+ * @brief Checks if the SD card is in programming state.
+ * @param hsd: SD handle
+ * @param pStatus: pointer to the variable that will contain the SD card state
+ * @retval SD Card error state
+ */
+static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus)
+{
+ SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0};
+ HAL_SD_ErrorTypedef errorstate = SD_OK;
+ __IO uint32_t responseR1 = 0;
+
+ sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
+ sdio_cmdinitstructure.CmdIndex = SD_CMD_SEND_STATUS;
+ sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT;
+ sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+ sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+
+ while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))
+ {
+ }
+
+ if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT))
+ {
+ errorstate = SD_CMD_RSP_TIMEOUT;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT);
+
+ return errorstate;
+ }
+ else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL))
+ {
+ errorstate = SD_CMD_CRC_FAIL;
+
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL);
+
+ return errorstate;
+ }
+ else
+ {
+ /* No error flag set */
+ }
+
+ /* Check response received is of desired command */
+ if((uint32_t)SDIO_GetCommandResponse(hsd->Instance) != SD_CMD_SEND_STATUS)
+ {
+ errorstate = SD_ILLEGAL_CMD;
+
+ return errorstate;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+
+ /* We have received response, retrieve it for analysis */
+ responseR1 = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+
+ /* Find out card status */
+ *pStatus = (uint8_t)((responseR1 >> 9) & 0x0000000F);
+
+ if((responseR1 & SD_OCR_ERRORBITS) == SD_ALLZERO)
+ {
+ return errorstate;
+ }
+
+ if((responseR1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE)
+ {
+ return(SD_ADDR_OUT_OF_RANGE);
+ }
+
+ if((responseR1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED)
+ {
+ return(SD_ADDR_MISALIGNED);
+ }
+
+ if((responseR1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR)
+ {
+ return(SD_BLOCK_LEN_ERR);
+ }
+
+ if((responseR1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR)
+ {
+ return(SD_ERASE_SEQ_ERR);
+ }
+
+ if((responseR1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM)
+ {
+ return(SD_BAD_ERASE_PARAM);
+ }
+
+ if((responseR1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION)
+ {
+ return(SD_WRITE_PROT_VIOLATION);
+ }
+
+ if((responseR1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED)
+ {
+ return(SD_LOCK_UNLOCK_FAILED);
+ }
+
+ if((responseR1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED)
+ {
+ return(SD_COM_CRC_FAILED);
+ }
+
+ if((responseR1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)
+ {
+ return(SD_ILLEGAL_CMD);
+ }
+
+ if((responseR1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED)
+ {
+ return(SD_CARD_ECC_FAILED);
+ }
+
+ if((responseR1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR)
+ {
+ return(SD_CC_ERROR);
+ }
+
+ if((responseR1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)
+ {
+ return(SD_GENERAL_UNKNOWN_ERROR);
+ }
+
+ if((responseR1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN)
+ {
+ return(SD_STREAM_READ_UNDERRUN);
+ }
+
+ if((responseR1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN)
+ {
+ return(SD_STREAM_WRITE_OVERRUN);
+ }
+
+ if((responseR1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE)
+ {
+ return(SD_CID_CSD_OVERWRITE);
+ }
+
+ if((responseR1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP)
+ {
+ return(SD_WP_ERASE_SKIP);
+ }
+
+ if((responseR1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED)
+ {
+ return(SD_CARD_ECC_DISABLED);
+ }
+
+ if((responseR1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET)
+ {
+ return(SD_ERASE_RESET);
+ }
+
+ if((responseR1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR)
+ {
+ return(SD_AKE_SEQ_ERROR);
+ }
+
+ return errorstate;
+}
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* HAL_SD_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c
new file mode 100644
index 0000000..48e79c8
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c
@@ -0,0 +1,692 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_sram.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief SRAM HAL module driver.
+ * This file provides a generic firmware to drive SRAM memories
+ * mounted as external device.
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control SRAM memories. It uses the FSMC layer functions to interface
+ with SRAM devices.
+ The following sequence should be followed to configure the FSMC to interface
+ with SRAM/PSRAM memories:
+
+ (#) Declare a SRAM_HandleTypeDef handle structure, for example:
+ SRAM_HandleTypeDef hsram; and:
+
+ (++) Fill the SRAM_HandleTypeDef handle "Init" field with the allowed
+ values of the structure member.
+
+ (++) Fill the SRAM_HandleTypeDef handle "Instance" field with a predefined
+ base register instance for NOR or SRAM device
+
+ (++) Fill the SRAM_HandleTypeDef handle "Extended" field with a predefined
+ base register instance for NOR or SRAM extended mode
+
+ (#) Declare two FSMC_NORSRAM_TimingTypeDef structures, for both normal and extended
+ mode timings; for example:
+ FSMC_NORSRAM_TimingTypeDef Timing and FSMC_NORSRAM_TimingTypeDef ExTiming;
+ and fill its fields with the allowed values of the structure member.
+
+ (#) Initialize the SRAM Controller by calling the function HAL_SRAM_Init(). This function
+ performs the following sequence:
+
+ (##) MSP hardware layer configuration using the function HAL_SRAM_MspInit()
+ (##) Control register configuration using the FSMC NORSRAM interface function
+ FSMC_NORSRAM_Init()
+ (##) Timing register configuration using the FSMC NORSRAM interface function
+ FSMC_NORSRAM_Timing_Init()
+ (##) Extended mode Timing register configuration using the FSMC NORSRAM interface function
+ FSMC_NORSRAM_Extended_Timing_Init()
+ (##) Enable the SRAM device using the macro __FSMC_NORSRAM_ENABLE()
+
+ (#) At this stage you can perform read/write accesses from/to the memory connected
+ to the NOR/SRAM Bank. You can perform either polling or DMA transfer using the
+ following APIs:
+ (++) HAL_SRAM_Read()/HAL_SRAM_Write() for polling read/write access
+ (++) HAL_SRAM_Read_DMA()/HAL_SRAM_Write_DMA() for DMA read/write transfer
+
+ (#) You can also control the SRAM device by calling the control APIs HAL_SRAM_WriteOperation_Enable()/
+ HAL_SRAM_WriteOperation_Disable() to respectively enable/disable the SRAM write operation
+
+ (#) You can continuously monitor the SRAM device HAL state by calling the function
+ HAL_SRAM_GetState()
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
+
+/** @defgroup SRAM SRAM
+ * @brief SRAM driver modules
+ * @{
+ */
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Functions SRAM Exported Functions
+ * @{
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions.
+ *
+ @verbatim
+ ==============================================================================
+ ##### SRAM Initialization and de_initialization functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to initialize/de-initialize
+ the SRAM memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Performs the SRAM device initialization sequence
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param Timing: Pointer to SRAM control timing structure
+ * @param ExtTiming: Pointer to SRAM extended mode timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming)
+{
+ /* Check the SRAM handle parameter */
+ if(hsram == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if(hsram->State == HAL_SRAM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hsram->Lock = HAL_UNLOCKED;
+
+ /* Initialize the low level hardware (MSP) */
+ HAL_SRAM_MspInit(hsram);
+ }
+
+ /* Initialize SRAM control Interface */
+ FSMC_NORSRAM_Init(hsram->Instance, &(hsram->Init));
+
+ /* Initialize SRAM timing Interface */
+ FSMC_NORSRAM_Timing_Init(hsram->Instance, Timing, hsram->Init.NSBank);
+
+ /* Initialize SRAM extended mode timing Interface */
+ FSMC_NORSRAM_Extended_Timing_Init(hsram->Extended, ExtTiming, hsram->Init.NSBank, hsram->Init.ExtendedMode);
+
+ /* Enable the NORSRAM device */
+ __FSMC_NORSRAM_ENABLE(hsram->Instance, hsram->Init.NSBank);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Performs the SRAM device De-initialization sequence.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram)
+{
+ /* De-Initialize the low level hardware (MSP) */
+ HAL_SRAM_MspDeInit(hsram);
+
+ /* Configure the SRAM registers with their reset values */
+ FSMC_NORSRAM_DeInit(hsram->Instance, hsram->Extended, hsram->Init.NSBank);
+
+ hsram->State = HAL_SRAM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief SRAM MSP Init.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsram);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SRAM MSP DeInit.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsram);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DMA transfer complete callback.
+ * @param hdma: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_DMA_XferCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DMA transfer complete error callback.
+ * @param hdma: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_DMA_XferErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group2 Input Output and memory control functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### SRAM Input and Output functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the SRAM memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads 8-bit buffer from SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to read start address
+ * @param pDstBuffer: Pointer to destination buffer
+ * @param BufferSize: Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize)
+{
+ __IO uint8_t * psramaddress = (uint8_t *)pAddress;
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Read data from memory */
+ for(; BufferSize != 0; BufferSize--)
+ {
+ *pDstBuffer = *(__IO uint8_t *)psramaddress;
+ pDstBuffer++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 8-bit buffer to SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to write start address
+ * @param pSrcBuffer: Pointer to source buffer to write
+ * @param BufferSize: Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize)
+{
+ __IO uint8_t * psramaddress = (uint8_t *)pAddress;
+
+ /* Check the SRAM controller state */
+ if(hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Write data to memory */
+ for(; BufferSize != 0; BufferSize--)
+ {
+ *(__IO uint8_t *)psramaddress = *pSrcBuffer;
+ pSrcBuffer++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads 16-bit buffer from SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to read start address
+ * @param pDstBuffer: Pointer to destination buffer
+ * @param BufferSize: Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize)
+{
+ __IO uint16_t * psramaddress = (uint16_t *)pAddress;
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Read data from memory */
+ for(; BufferSize != 0; BufferSize--)
+ {
+ *pDstBuffer = *(__IO uint16_t *)psramaddress;
+ pDstBuffer++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 16-bit buffer to SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to write start address
+ * @param pSrcBuffer: Pointer to source buffer to write
+ * @param BufferSize: Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize)
+{
+ __IO uint16_t * psramaddress = (uint16_t *)pAddress;
+
+ /* Check the SRAM controller state */
+ if(hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Write data to memory */
+ for(; BufferSize != 0; BufferSize--)
+ {
+ *(__IO uint16_t *)psramaddress = *pSrcBuffer;
+ pSrcBuffer++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads 32-bit buffer from SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to read start address
+ * @param pDstBuffer: Pointer to destination buffer
+ * @param BufferSize: Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)
+{
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Read data from memory */
+ for(; BufferSize != 0; BufferSize--)
+ {
+ *pDstBuffer = *(__IO uint32_t *)pAddress;
+ pDstBuffer++;
+ pAddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 32-bit buffer to SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to write start address
+ * @param pSrcBuffer: Pointer to source buffer to write
+ * @param BufferSize: Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize)
+{
+ /* Check the SRAM controller state */
+ if(hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Write data to memory */
+ for(; BufferSize != 0; BufferSize--)
+ {
+ *(__IO uint32_t *)pAddress = *pSrcBuffer;
+ pSrcBuffer++;
+ pAddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads a Words data from the SRAM memory using DMA transfer.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to read start address
+ * @param pDstBuffer: Pointer to destination buffer
+ * @param BufferSize: Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)
+{
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Configure DMA user callbacks */
+ hsram->hdma->XferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
+ hsram->hdma->XferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, (uint32_t)BufferSize);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes a Words data buffer to SRAM memory using DMA transfer.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to write start address
+ * @param pSrcBuffer: Pointer to source buffer to write
+ * @param BufferSize: Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize)
+{
+ /* Check the SRAM controller state */
+ if(hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Configure DMA user callbacks */
+ hsram->hdma->XferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
+ hsram->hdma->XferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, (uint32_t)BufferSize);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group3 Control functions
+ * @brief Control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### SRAM Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the SRAM interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically SRAM write operation.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram)
+{
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Enable write operation */
+ FSMC_NORSRAM_WriteOperation_Enable(hsram->Instance, hsram->Init.NSBank);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically SRAM write operation.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram)
+{
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Disable write operation */
+ FSMC_NORSRAM_WriteOperation_Disable(hsram->Instance, hsram->Init.NSBank);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_PROTECTED;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### SRAM State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the SRAM controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the SRAM controller state
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL state
+ */
+HAL_SRAM_StateTypeDef HAL_SRAM_GetState(SRAM_HandleTypeDef *hsram)
+{
+ return hsram->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c
new file mode 100644
index 0000000..221d55c
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c
@@ -0,0 +1,1013 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_fsmc.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief FSMC Low Layer HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the Flexible Static Memory Controller (FSMC) peripheral memories:
+ * + Initialization/de-initialization functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ =============================================================================
+ ##### FSMC peripheral features #####
+ =============================================================================
+ [..] The Flexible static memory controller (FSMC) includes following memory controllers:
+ (+) The NOR/PSRAM memory controller
+ (+) The PC Card memory controller
+ (+) The NAND memory controller
+ (PC Card and NAND controllers available only on STM32F101xE, STM32F103xE, STM32F101xG and STM32F103xG)
+
+ [..] The FSMC functional block makes the interface with synchronous and asynchronous static
+ memories and 16-bit PC memory cards. Its main purposes are:
+ (+) to translate AHB transactions into the appropriate external device protocol.
+ (+) to meet the access time requirements of the external memory devices.
+
+ [..] All external memories share the addresses, data and control signals with the controller.
+ Each external device is accessed by means of a unique Chip Select. The FSMC performs
+ only one access at a time to an external device.
+ The main features of the FSMC controller are the following:
+ (+) Interface with static-memory mapped devices including:
+ (++) Static random access memory (SRAM).
+ (++) NOR Flash memory.
+ (++) PSRAM (4 memory banks).
+ (++) 16-bit PC Card compatible devices
+ (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of
+ data
+ (+) Independent Chip Select control for each memory bank
+ (+) Independent configuration for each memory bank
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined(HAL_SRAM_MODULE_ENABLED) || defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED)
+
+#if defined(FSMC_BANK1)
+
+/** @defgroup FSMC_LL FSMC Low Layer
+ * @brief FSMC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup FSMC_LL_Private_Constants FSMC Low Layer Private Constants
+ * @{
+ */
+
+/* ----------------------- FSMC registers bit mask --------------------------- */
+/* --- PCR Register ---*/
+/* PCR register clear mask */
+#define PCR_CLEAR_MASK ((uint32_t)(FSMC_PCRx_PWAITEN | FSMC_PCRx_PBKEN | \
+ FSMC_PCRx_PTYP | FSMC_PCRx_PWID | \
+ FSMC_PCRx_ECCEN | FSMC_PCRx_TCLR | \
+ FSMC_PCRx_TAR | FSMC_PCRx_ECCPS))
+
+/* --- SR Register ---*/
+/* SR register clear mask */
+#define SR_CLEAR_MASK ((uint32_t)(FSMC_SRx_IRS | FSMC_SRx_ILS | FSMC_SRx_IFS | \
+ FSMC_SRx_IREN | FSMC_SRx_ILEN | FSMC_SRx_IFEN))
+
+/* --- PMEM Register ---*/
+/* PMEM register clear mask */
+#define PMEM_CLEAR_MASK ((uint32_t)(FSMC_PMEMx_MEMSETx | FSMC_PMEMx_MEMWAITx |\
+ FSMC_PMEMx_MEMHOLDx | FSMC_PMEMx_MEMHIZx))
+
+/* --- PATT Register ---*/
+/* PATT register clear mask */
+#define PATT_CLEAR_MASK ((uint32_t)(FSMC_PATTx_ATTSETx | FSMC_PATTx_ATTWAITx |\
+ FSMC_PATTx_ATTHOLDx | FSMC_PATTx_ATTHIZx))
+
+/* --- BCR Register ---*/
+/* BCR register clear mask */
+#define BCR_CLEAR_MASK ((uint32_t)(FSMC_BCRx_FACCEN | FSMC_BCRx_MUXEN | \
+ FSMC_BCRx_MTYP | FSMC_BCRx_MWID | \
+ FSMC_BCRx_BURSTEN | FSMC_BCRx_WAITPOL | \
+ FSMC_BCRx_WRAPMOD | FSMC_BCRx_WAITCFG | \
+ FSMC_BCRx_WREN | FSMC_BCRx_WAITEN | \
+ FSMC_BCRx_EXTMOD | FSMC_BCRx_ASYNCWAIT | \
+ FSMC_BCRx_CBURSTRW))
+/* --- BTR Register ---*/
+/* BTR register clear mask */
+#define BTR_CLEAR_MASK ((uint32_t)(FSMC_BTRx_ADDSET | FSMC_BTRx_ADDHLD |\
+ FSMC_BTRx_DATAST | FSMC_BTRx_BUSTURN |\
+ FSMC_BTRx_CLKDIV | FSMC_BTRx_DATLAT |\
+ FSMC_BTRx_ACCMOD))
+
+/* --- BWTR Register ---*/
+/* BWTR register clear mask */
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+#define BWTR_CLEAR_MASK ((uint32_t)(FSMC_BWTRx_ADDSET | FSMC_BWTRx_ADDHLD | \
+ FSMC_BWTRx_DATAST | FSMC_BWTRx_ACCMOD | \
+ FSMC_BWTRx_BUSTURN))
+#else
+#define BWTR_CLEAR_MASK ((uint32_t)(FSMC_BWTRx_ADDSET | FSMC_BWTRx_ADDHLD | \
+ FSMC_BWTRx_DATAST | FSMC_BWTRx_ACCMOD | \
+ FSMC_BWTRx_CLKDIV | FSMC_BWTRx_DATLAT))
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/* --- PIO4 Register ---*/
+/* PIO4 register clear mask */
+#define PIO4_CLEAR_MASK ((uint32_t)(FSMC_PIO4_IOSET4 | FSMC_PIO4_IOWAIT4 | \
+ FSMC_PIO4_IOHOLD4 | FSMC_PIO4_IOHIZ4))
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup FSMC_LL_Private_Macros FSMC Low Layer Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup FSMC_LL_Exported_Functions FSMC Low Layer Exported Functions
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM FSMC NORSRAM Controller functions
+ * @brief NORSRAM Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use NORSRAM device driver #####
+ ==============================================================================
+
+ [..]
+ This driver contains a set of APIs to interface with the FSMC NORSRAM banks in order
+ to run the NORSRAM external devices.
+
+ (+) FSMC NORSRAM bank reset using the function FSMC_NORSRAM_DeInit()
+ (+) FSMC NORSRAM bank control configuration using the function FSMC_NORSRAM_Init()
+ (+) FSMC NORSRAM bank timing configuration using the function FSMC_NORSRAM_Timing_Init()
+ (+) FSMC NORSRAM bank extended timing configuration using the function
+ FSMC_NORSRAM_Extended_Timing_Init()
+ (+) FSMC NORSRAM bank enable/disable write operation using the functions
+ FSMC_NORSRAM_WriteOperation_Enable()/FSMC_NORSRAM_WriteOperation_Disable()
+
+
+@endverbatim
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM_Group1 Initialization/de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC NORSRAM interface
+ (+) De-initialize the FSMC NORSRAM interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the FSMC_NORSRAM device according to the specified
+ * control parameters in the FSMC_NORSRAM_InitTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Init: Pointer to NORSRAM Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef *Init)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Init->NSBank));
+ assert_param(IS_FSMC_MUX(Init->DataAddressMux));
+ assert_param(IS_FSMC_MEMORY(Init->MemoryType));
+ assert_param(IS_FSMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FSMC_BURSTMODE(Init->BurstAccessMode));
+ assert_param(IS_FSMC_WAIT_POLARITY(Init->WaitSignalPolarity));
+ assert_param(IS_FSMC_WRAP_MODE(Init->WrapMode));
+ assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
+ assert_param(IS_FSMC_WRITE_OPERATION(Init->WriteOperation));
+ assert_param(IS_FSMC_WAITE_SIGNAL(Init->WaitSignal));
+ assert_param(IS_FSMC_EXTENDED_MODE(Init->ExtendedMode));
+ assert_param(IS_FSMC_ASYNWAIT(Init->AsynchronousWait));
+ assert_param(IS_FSMC_WRITE_BURST(Init->WriteBurst));
+
+ /* Disable NORSRAM Device */
+ __FSMC_NORSRAM_DISABLE(Device, Init->NSBank);
+
+ /* Set NORSRAM device control parameters */
+ if (Init->MemoryType == FSMC_MEMORY_TYPE_NOR)
+ {
+ MODIFY_REG(Device->BTCR[Init->NSBank], BCR_CLEAR_MASK, (uint32_t)(FSMC_NORSRAM_FLASH_ACCESS_ENABLE
+ | Init->DataAddressMux
+ | Init->MemoryType
+ | Init->MemoryDataWidth
+ | Init->BurstAccessMode
+ | Init->WaitSignalPolarity
+ | Init->WrapMode
+ | Init->WaitSignalActive
+ | Init->WriteOperation
+ | Init->WaitSignal
+ | Init->ExtendedMode
+ | Init->AsynchronousWait
+ | Init->WriteBurst
+ )
+ );
+ }
+ else
+ {
+ MODIFY_REG(Device->BTCR[Init->NSBank], BCR_CLEAR_MASK, (uint32_t)(FSMC_NORSRAM_FLASH_ACCESS_DISABLE
+ | Init->DataAddressMux
+ | Init->MemoryType
+ | Init->MemoryDataWidth
+ | Init->BurstAccessMode
+ | Init->WaitSignalPolarity
+ | Init->WrapMode
+ | Init->WaitSignalActive
+ | Init->WriteOperation
+ | Init->WaitSignal
+ | Init->ExtendedMode
+ | Init->AsynchronousWait
+ | Init->WriteBurst
+ )
+ );
+ }
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief DeInitialize the FSMC_NORSRAM peripheral
+ * @param Device: Pointer to NORSRAM device instance
+ * @param ExDevice: Pointer to NORSRAM extended mode device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Disable the FSMC_NORSRAM device */
+ __FSMC_NORSRAM_DISABLE(Device, Bank);
+
+ /* De-initialize the FSMC_NORSRAM device */
+ /* FSMC_NORSRAM_BANK1 */
+ if (Bank == FSMC_NORSRAM_BANK1)
+ {
+ Device->BTCR[Bank] = 0x000030DB;
+ }
+ /* FSMC_NORSRAM_BANK2, FSMC_NORSRAM_BANK3 or FSMC_NORSRAM_BANK4 */
+ else
+ {
+ Device->BTCR[Bank] = 0x000030D2;
+ }
+
+ Device->BTCR[Bank + 1] = 0x0FFFFFFF;
+ ExDevice->BWTR[Bank] = 0x0FFFFFFF;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Initialize the FSMC_NORSRAM Timing according to the specified
+ * parameters in the FSMC_NORSRAM_TimingTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Timing: Pointer to NORSRAM Timing structure
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
+ assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
+ assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
+ assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
+ assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
+ assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
+ assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Set FSMC_NORSRAM device timing parameters */
+ MODIFY_REG(Device->BTCR[Bank + 1], \
+ BTR_CLEAR_MASK, \
+ (uint32_t)(Timing->AddressSetupTime | \
+ ((Timing->AddressHoldTime) << POSITION_VAL(FSMC_BTRx_ADDHLD)) | \
+ ((Timing->DataSetupTime) << POSITION_VAL(FSMC_BTRx_DATAST)) | \
+ ((Timing->BusTurnAroundDuration) << POSITION_VAL(FSMC_BTRx_BUSTURN)) | \
+ (((Timing->CLKDivision) - 1) << POSITION_VAL(FSMC_BTRx_CLKDIV)) | \
+ (((Timing->DataLatency) - 2) << POSITION_VAL(FSMC_BTRx_DATLAT)) | \
+ (Timing->AccessMode)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the FSMC_NORSRAM Extended mode Timing according to the specified
+ * parameters in the FSMC_NORSRAM_TimingTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Timing: Pointer to NORSRAM Timing structure
+ * @param Bank: NORSRAM bank number
+ * @param ExtendedMode: FSMC Extended Mode
+ * This parameter can be one of the following values:
+ * @arg FSMC_EXTENDED_MODE_DISABLE
+ * @arg FSMC_EXTENDED_MODE_ENABLE
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_EXTENDED_MODE(ExtendedMode));
+
+ /* Set NORSRAM device timing register for write configuration, if extended mode is used */
+ if (ExtendedMode == FSMC_EXTENDED_MODE_ENABLE)
+ {
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(Device));
+ assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
+ assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
+ assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+ assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
+#else
+ assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
+ assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+ assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Set NORSRAM device timing register for write configuration, if extended mode is used */
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+ MODIFY_REG(Device->BWTR[Bank], \
+ BWTR_CLEAR_MASK, \
+ (uint32_t)(Timing->AddressSetupTime | \
+ ((Timing->AddressHoldTime) << POSITION_VAL(FSMC_BWTRx_ADDHLD)) | \
+ ((Timing->DataSetupTime) << POSITION_VAL(FSMC_BWTRx_DATAST)) | \
+ Timing->AccessMode | \
+ ((Timing->BusTurnAroundDuration) << POSITION_VAL(FSMC_BWTRx_BUSTURN))));
+#else
+ MODIFY_REG(Device->BWTR[Bank], \
+ BWTR_CLEAR_MASK, \
+ (uint32_t)(Timing->AddressSetupTime | \
+ ((Timing->AddressHoldTime) << POSITION_VAL(FSMC_BWTRx_ADDHLD)) | \
+ ((Timing->DataSetupTime) << POSITION_VAL(FSMC_BWTRx_DATAST)) | \
+ Timing->AccessMode | \
+ (((Timing->CLKDivision) - 1) << POSITION_VAL(FSMC_BTRx_CLKDIV)) | \
+ (((Timing->DataLatency) - 2) << POSITION_VAL(FSMC_BWTRx_DATLAT))));
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+ }
+ else
+ {
+ Device->BWTR[Bank] = 0x0FFFFFFF;
+ }
+
+ return HAL_OK;
+}
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FSMC_NORSRAM_Group2 Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FSMC_NORSRAM Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FSMC NORSRAM interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically FSMC_NORSRAM write operation.
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Enable write operation */
+ SET_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FSMC_NORSRAM write operation.
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Disable write operation */
+ CLEAR_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#if (defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @defgroup FSMC_NAND FSMC NAND Controller functions
+ * @brief NAND Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use NAND device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FSMC NAND banks in order
+ to run the NAND external devices.
+
+ (+) FSMC NAND bank reset using the function FSMC_NAND_DeInit()
+ (+) FSMC NAND bank control configuration using the function FSMC_NAND_Init()
+ (+) FSMC NAND bank common space timing configuration using the function
+ FSMC_NAND_CommonSpace_Timing_Init()
+ (+) FSMC NAND bank attribute space timing configuration using the function
+ FSMC_NAND_AttributeSpace_Timing_Init()
+ (+) FSMC NAND bank enable/disable ECC correction feature using the functions
+ FSMC_NAND_ECC_Enable()/FSMC_NAND_ECC_Disable()
+ (+) FSMC NAND bank get ECC correction code using the function FSMC_NAND_GetECC()
+
+@endverbatim
+ * @{
+ */
+
+/** @defgroup FSMC_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC NAND interface
+ (+) De-initialize the FSMC NAND interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FSMC_NAND device according to the specified
+ * control parameters in the FSMC_NAND_HandleTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Init: Pointer to NAND Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Init->NandBank));
+ assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FSMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FSMC_ECC_STATE(Init->EccComputation));
+ assert_param(IS_FSMC_ECCPAGE_SIZE(Init->ECCPageSize));
+ assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
+
+ /* Set NAND device control parameters */
+ if (Init->NandBank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ MODIFY_REG(Device->PCR2, PCR_CLEAR_MASK, (Init->Waitfeature | \
+ FSMC_PCR_MEMORY_TYPE_NAND | \
+ Init->MemoryDataWidth | \
+ Init->EccComputation | \
+ Init->ECCPageSize | \
+ ((Init->TCLRSetupTime) << POSITION_VAL(FSMC_PCRx_TCLR)) | \
+ ((Init->TARSetupTime) << POSITION_VAL(FSMC_PCRx_TAR))));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ MODIFY_REG(Device->PCR3, PCR_CLEAR_MASK, (Init->Waitfeature | \
+ FSMC_PCR_MEMORY_TYPE_NAND | \
+ Init->MemoryDataWidth | \
+ Init->EccComputation | \
+ Init->ECCPageSize | \
+ ((Init->TCLRSetupTime) << POSITION_VAL(FSMC_PCRx_TCLR)) | \
+ ((Init->TARSetupTime) << POSITION_VAL(FSMC_PCRx_TAR))));
+ }
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Initializes the FSMC_NAND Common space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Timing: Pointer to NAND timing structure
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Set FMC_NAND device timing parameters */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ MODIFY_REG(Device->PMEM2, PMEM_CLEAR_MASK, (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMWAITx)) | \
+ ((Timing->HoldSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMHOLDx)) | \
+ ((Timing->HiZSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMHIZx))));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ MODIFY_REG(Device->PMEM3, PMEM_CLEAR_MASK, (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMWAITx)) | \
+ ((Timing->HoldSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMHOLDx)) | \
+ ((Timing->HiZSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMHIZx))));
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_NAND Attribute space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Timing: Pointer to NAND timing structure
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Set FMC_NAND device timing parameters */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ MODIFY_REG(Device->PATT2, PATT_CLEAR_MASK, (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << POSITION_VAL(FSMC_PATTx_ATTWAITx)) | \
+ ((Timing->HoldSetupTime) << POSITION_VAL(FSMC_PATTx_ATTHOLDx)) | \
+ ((Timing->HiZSetupTime) << POSITION_VAL(FSMC_PATTx_ATTHIZx))));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ MODIFY_REG(Device->PATT3, PATT_CLEAR_MASK, (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << POSITION_VAL(FSMC_PATTx_ATTWAITx)) | \
+ ((Timing->HoldSetupTime) << POSITION_VAL(FSMC_PATTx_ATTHOLDx)) | \
+ ((Timing->HiZSetupTime) << POSITION_VAL(FSMC_PATTx_ATTHIZx))));
+ }
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief DeInitializes the FSMC_NAND device
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Disable the NAND Bank */
+ __FSMC_NAND_DISABLE(Device, Bank);
+
+ /* De-initialize the NAND Bank */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ /* Set the FSMC_NAND_BANK2 registers to their reset values */
+ WRITE_REG(Device->PCR2, 0x00000018);
+ WRITE_REG(Device->SR2, 0x00000040);
+ WRITE_REG(Device->PMEM2, 0xFCFCFCFC);
+ WRITE_REG(Device->PATT2, 0xFCFCFCFC);
+ }
+ /* FSMC_Bank3_NAND */
+ else
+ {
+ /* Set the FSMC_NAND_BANK3 registers to their reset values */
+ WRITE_REG(Device->PCR3, 0x00000018);
+ WRITE_REG(Device->SR3, 0x00000040);
+ WRITE_REG(Device->PMEM3, 0xFCFCFCFC);
+ WRITE_REG(Device->PATT3, 0xFCFCFCFC);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FSMC_NAND_Exported_Functions_Group2 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FSMC_NAND Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FSMC NAND interface.
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Enables dynamically FSMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Enable ECC feature */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ SET_BIT(Device->PCR2, FSMC_PCRx_ECCEN);
+ }
+ else
+ {
+ SET_BIT(Device->PCR3, FSMC_PCRx_ECCEN);
+ }
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Disables dynamically FSMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Disable ECC feature */
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ CLEAR_BIT(Device->PCR2, FSMC_PCRx_ECCEN);
+ }
+ else
+ {
+ CLEAR_BIT(Device->PCR3, FSMC_PCRx_ECCEN);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FSMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param ECCval: Pointer to ECC value
+ * @param Bank: NAND bank number
+ * @param Timeout: Timeout wait value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout)
+{
+ uint32_t tickstart = 0;
+
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait untill FIFO is empty */
+ while (__FSMC_NAND_GET_FLAG(Device, Bank, FSMC_FLAG_FEMPT) == RESET)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if ((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ if (Bank == FSMC_NAND_BANK2)
+ {
+ /* Get the ECCR2 register value */
+ *ECCval = (uint32_t)Device->ECCR2;
+ }
+ else
+ {
+ /* Get the ECCR3 register value */
+ *ECCval = (uint32_t)Device->ECCR3;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+#if (defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @defgroup FSMC_PCCARD FSMC PCCARD Controller functions
+ * @brief PCCARD Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use PCCARD device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FSMC PCCARD bank in order
+ to run the PCCARD/compact flash external devices.
+
+ (+) FSMC PCCARD bank reset using the function FSMC_PCCARD_DeInit()
+ (+) FSMC PCCARD bank control configuration using the function FSMC_PCCARD_Init()
+ (+) FSMC PCCARD bank common space timing configuration using the function
+ FSMC_PCCARD_CommonSpace_Timing_Init()
+ (+) FSMC PCCARD bank attribute space timing configuration using the function
+ FSMC_PCCARD_AttributeSpace_Timing_Init()
+ (+) FSMC PCCARD bank IO space timing configuration using the function
+ FSMC_PCCARD_IOSpace_Timing_Init()
+
+
+@endverbatim
+ * @{
+ */
+
+/** @defgroup FSMC_PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC PCCARD interface
+ (+) De-initialize the FSMC PCCARD interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FSMC_PCCARD device according to the specified
+ * control parameters in the FSMC_PCCARD_HandleTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Init: Pointer to PCCARD Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
+
+ /* Set FSMC_PCCARD device control parameters */
+ MODIFY_REG(Device->PCR4, \
+ (FSMC_PCRx_PTYP | FSMC_PCRx_PWAITEN | FSMC_PCRx_PWID |
+ FSMC_PCRx_TCLR | FSMC_PCRx_TAR), \
+ (FSMC_PCR_MEMORY_TYPE_PCCARD | \
+ Init->Waitfeature | \
+ FSMC_NAND_PCC_MEM_BUS_WIDTH_16 | \
+ (Init->TCLRSetupTime << POSITION_VAL(FSMC_PCRx_TCLR)) | \
+ (Init->TARSetupTime << POSITION_VAL(FSMC_PCRx_TAR))));
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD Common space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Set PCCARD timing parameters */
+ MODIFY_REG(Device->PMEM4, PMEM_CLEAR_MASK, \
+ (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMWAITx)) | \
+ ((Timing->HoldSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMHOLDx)) | \
+ ((Timing->HiZSetupTime) << POSITION_VAL(FSMC_PMEMx_MEMHIZx))));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD Attribute space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Set PCCARD timing parameters */
+ MODIFY_REG(Device->PATT4, PATT_CLEAR_MASK, \
+ (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << POSITION_VAL(FSMC_PATTx_ATTWAITx)) | \
+ ((Timing->HoldSetupTime) << POSITION_VAL(FSMC_PATTx_ATTHOLDx)) | \
+ ((Timing->HiZSetupTime) << POSITION_VAL(FSMC_PATTx_ATTHIZx))));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD IO space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Set FSMC_PCCARD device timing parameters */
+ MODIFY_REG(Device->PIO4, PIO4_CLEAR_MASK, \
+ (Timing->SetupTime | \
+ (Timing->WaitSetupTime << POSITION_VAL(FSMC_PIO4_IOWAIT4)) | \
+ (Timing->HoldSetupTime << POSITION_VAL(FSMC_PIO4_IOHOLD4)) | \
+ (Timing->HiZSetupTime << POSITION_VAL(FSMC_PIO4_IOHIZ4))));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the FSMC_PCCARD device
+ * @param Device: Pointer to PCCARD device instance
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+
+ /* Disable the FSMC_PCCARD device */
+ __FSMC_PCCARD_DISABLE(Device);
+
+ /* De-initialize the FSMC_PCCARD device */
+ WRITE_REG(Device->PCR4, 0x00000018);
+ WRITE_REG(Device->SR4, 0x00000040);
+ WRITE_REG(Device->PMEM4, 0xFCFCFCFC);
+ WRITE_REG(Device->PATT4, 0xFCFCFCFC);
+ WRITE_REG(Device->PIO4, 0xFCFCFCFC);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* FSMC_BANK1 */
+
+#endif /* defined(HAL_SRAM_MODULE_ENABLED) || defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c
new file mode 100644
index 0000000..788c73a
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c
@@ -0,0 +1,496 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_sdmmc.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief SDMMC Low Layer HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the SDMMC peripheral:
+ * + Initialization/de-initialization functions
+ * + I/O operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### SDMMC peripheral features #####
+ ==============================================================================
+ [..] The SD/SDIO MMC card host interface (SDIO) provides an interface between the APB2
+ peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDIO cards and CE-ATA
+ devices.
+
+ [..] The SDIO features include the following:
+ (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support
+ for three different databus modes: 1-bit (default), 4-bit and 8-bit
+ (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility)
+ (+) Full compliance with SD Memory Card Specifications Version 2.0
+ (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two
+ different data bus modes: 1-bit (default) and 4-bit
+ (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol
+ Rev1.1)
+ (+) Data transfer up to 48 MHz for the 8 bit mode
+ (+) Data and command output enable signals to control external bidirectional drivers.
+
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a considered as a driver of service for external devices drivers
+ that interfaces with the SDIO peripheral.
+ According to the device used (SD card/ MMC card / SDIO card ...), a set of APIs
+ is used in the device's driver to perform SDIO operations and functionalities.
+
+ This driver is almost transparent for the final user, it is only used to implement other
+ functionalities of the external device.
+
+ [..]
+ (+) The SDIO peripheral uses two clock signals:
+ (++) SDIO adapter clock (SDIOCLK = HCLK)
+ (++) AHB bus clock (HCLK/2)
+
+ -@@- PCLK2 and SDIO_CK clock frequencies must respect the following condition:
+ Frequency(PCLK2) >= (3 / 8 x Frequency(SDIO_CK))
+
+ (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDIO
+ peripheral.
+
+ (+) Enable the Power ON State using the SDIO_PowerState_ON(SDIOx)
+ function and disable it using the function SDIO_PowerState_OFF(SDIOx).
+
+ (+) Enable/Disable the clock using the __SDIO_ENABLE()/__SDIO_DISABLE() macros.
+
+ (+) Enable/Disable the peripheral interrupts using the macros __SDIO_ENABLE_IT(hsdio, IT)
+ and __SDIO_DISABLE_IT(hsdio, IT) if you need to use interrupt mode.
+
+ (+) When using the DMA mode
+ (++) Configure the DMA in the MSP layer of the external device
+ (++) Active the needed channel Request
+ (++) Enable the DMA using __SDIO_DMA_ENABLE() macro or Disable it using the macro
+ __SDIO_DMA_DISABLE().
+
+ (+) To control the CPSM (Command Path State Machine) and send
+ commands to the card use the SDIO_SendCommand(),
+ SDIO_GetCommandResponse() and SDIO_GetResponse() functions. First, user has
+ to fill the command structure (pointer to SDIO_CmdInitTypeDef) according
+ to the selected command to be sent.
+ The parameters that should be filled are:
+ (++) Command Argument
+ (++) Command Index
+ (++) Command Response type
+ (++) Command Wait
+ (++) CPSM Status (Enable or Disable).
+
+ -@@- To check if the command is well received, read the SDIO_CMDRESP
+ register using the SDIO_GetCommandResponse().
+ The SDIO responses registers (SDIO_RESP1 to SDIO_RESP2), use the
+ SDIO_GetResponse() function.
+
+ (+) To control the DPSM (Data Path State Machine) and send/receive
+ data to/from the card use the SDIO_DataConfig(), SDIO_GetDataCounter(),
+ SDIO_ReadFIFO(), SDIO_WriteFIFO() and SDIO_GetFIFOCount() functions.
+
+ *** Read Operations ***
+ =======================
+ [..]
+ (#) First, user has to fill the data structure (pointer to
+ SDIO_DataInitTypeDef) according to the selected data type to be received.
+ The parameters that should be filled are:
+ (++) Data TimeOut
+ (++) Data Length
+ (++) Data Block size
+ (++) Data Transfer direction: should be from card (To SDIO)
+ (++) Data Transfer mode
+ (++) DPSM Status (Enable or Disable)
+
+ (#) Configure the SDIO resources to receive the data from the card
+ according to selected transfer mode.
+
+ (#) Send the selected Read command.
+
+ (#) Use the SDIO flags/interrupts to check the transfer status.
+
+ *** Write Operations ***
+ ========================
+ [..]
+ (#) First, user has to fill the data structure (pointer to
+ SDIO_DataInitTypeDef) according to the selected data type to be received.
+ The parameters that should be filled are:
+ (++) Data TimeOut
+ (++) Data Length
+ (++) Data Block size
+ (++) Data Transfer direction: should be to card (To CARD)
+ (++) Data Transfer mode
+ (++) DPSM Status (Enable or Disable)
+
+ (#) Configure the SDIO resources to send the data to the card according to
+ selected transfer mode.
+
+ (#) Send the selected Write command.
+
+ (#) Use the SDIO flags/interrupts to check the transfer status.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+#if defined (HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup SDMMC_LL SDMMC Low Layer
+ * @brief Low layer module for SD and MMC driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup SDMMC_LL_Exported_Functions SDMMC_LL Exported Functions
+ * @{
+ */
+
+/** @defgroup HAL_SDMMC_LL_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization/de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the SDIO according to the specified
+ * parameters in the SDIO_InitTypeDef and create the associated handle.
+ * @param SDIOx: Pointer to SDIO register base
+ * @param Init: SDIO initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_ALL_INSTANCE(SDIOx));
+ assert_param(IS_SDIO_CLOCK_EDGE(Init.ClockEdge));
+ assert_param(IS_SDIO_CLOCK_BYPASS(Init.ClockBypass));
+ assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init.ClockPowerSave));
+ assert_param(IS_SDIO_BUS_WIDE(Init.BusWide));
+ assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
+ assert_param(IS_SDIO_CLKDIV(Init.ClockDiv));
+
+ /* Set SDIO configuration parameters */
+ /* Write to SDIO CLKCR */
+ MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, Init.ClockEdge |\
+ Init.ClockBypass |\
+ Init.ClockPowerSave |\
+ Init.BusWide |\
+ Init.HardwareFlowControl |\
+ Init.ClockDiv);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the SDIO data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Read data (word) from Rx FIFO in blocking mode (polling)
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
+{
+ /* Read data from Rx FIFO */
+ return (SDIOx->FIFO);
+}
+
+/**
+ * @brief Write data (word) to Tx FIFO in blocking mode (polling)
+ * @param SDIOx: Pointer to SDIO register base
+ * @param pWriteData: pointer to data to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
+{
+ /* Write data to FIFO */
+ SDIOx->FIFO = *pWriteData;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the SDIO data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Set SDIO Power state to ON.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
+{
+ /* Set power state to ON */
+ SDIOx->POWER = SDIO_POWER_PWRCTRL;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Set SDIO Power state to OFF.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
+{
+ /* Set power state to OFF */
+ SDIOx->POWER = (uint32_t)0x00000000;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Get SDIO Power state.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval Power status of the controller. The returned value can be one of the
+ * following values:
+ * - 0x00: Power OFF
+ * - 0x02: Power UP
+ * - 0x03: Power ON
+ */
+uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)
+{
+ return (SDIOx->POWER & SDIO_POWER_PWRCTRL);
+}
+
+/**
+ * @brief Configure the SDIO command path according to the specified parameters in
+ * SDIO_CmdInitTypeDef structure and send the command
+ * @param SDIOx: Pointer to SDIO register base
+ * @param Command: pointer to a SDIO_CmdInitTypeDef structure that contains
+ * the configuration information for the SDIO command
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_CMD_INDEX(Command->CmdIndex));
+ assert_param(IS_SDIO_RESPONSE(Command->Response));
+ assert_param(IS_SDIO_WAIT(Command->WaitForInterrupt));
+ assert_param(IS_SDIO_CPSM(Command->CPSM));
+
+ /* Set the SDIO Argument value */
+ SDIOx->ARG = Command->Argument;
+
+ /* Set SDIO command parameters */
+ /* Write to SDIO CMD register */
+ MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, Command->CmdIndex |\
+ Command->Response |\
+ Command->WaitForInterrupt |\
+ Command->CPSM);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Return the command index of last command for which response received
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval Command index of the last command response received
+ */
+uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
+{
+ return (uint8_t)(SDIOx->RESPCMD);
+}
+
+
+/**
+ * @brief Return the response received from the card for the last command
+ * @param SDIO_RESP: Specifies the SDIO response register.
+ * This parameter can be one of the following values:
+ * @arg SDIO_RESP1: Response Register 1
+ * @arg SDIO_RESP2: Response Register 2
+ * @arg SDIO_RESP3: Response Register 3
+ * @arg SDIO_RESP4: Response Register 4
+ * @retval The Corresponding response register value
+ */
+uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_RESP(Response));
+
+ /* Get the response */
+ tmp = SDIO_RESP_ADDR + Response;
+
+ return (*(__IO uint32_t *) tmp);
+}
+
+/**
+ * @brief Configure the SDIO data path according to the specified
+ * parameters in the SDIO_DataInitTypeDef.
+ * @param SDIOx: Pointer to SDIO register base
+ * @param Data : pointer to a SDIO_DataInitTypeDef structure
+ * that contains the configuration information for the SDIO data.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_DataConfig(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_DATA_LENGTH(Data->DataLength));
+ assert_param(IS_SDIO_BLOCK_SIZE(Data->DataBlockSize));
+ assert_param(IS_SDIO_TRANSFER_DIR(Data->TransferDir));
+ assert_param(IS_SDIO_TRANSFER_MODE(Data->TransferMode));
+ assert_param(IS_SDIO_DPSM(Data->DPSM));
+
+ /* Set the SDIO Data TimeOut value */
+ SDIOx->DTIMER = Data->DataTimeOut;
+
+ /* Set the SDIO DataLength value */
+ SDIOx->DLEN = Data->DataLength;
+
+ /* Set the SDIO data configuration parameters */
+ /* Write to SDIO DCTRL */
+ MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, Data->DataBlockSize |\
+ Data->TransferDir |\
+ Data->TransferMode |\
+ Data->DPSM);
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Returns number of remaining data bytes to be transferred.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval Number of remaining data bytes to be transferred
+ */
+uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
+{
+ return (SDIOx->DCOUNT);
+}
+
+/**
+ * @brief Get the FIFO data
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval Data received
+ */
+uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
+{
+ return (SDIOx->FIFO);
+}
+
+
+/**
+ * @brief Sets one of the two options of inserting read wait interval.
+ * @param SDIO_ReadWaitMode: SD I/O Read Wait operation mode.
+ * This parameter can be:
+ * @arg SDIO_READ_WAIT_MODE_CLK: Read Wait control by stopping SDIOCLK
+ * @arg SDIO_READ_WAIT_MODE_DATA2: Read Wait control using SDIO_DATA2
+ * @retval None
+ */
+HAL_StatusTypeDef SDIO_SetSDIOReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode));
+
+ /* Set SDIO read wait mode */
+ MODIFY_REG(SDIO->DCTRL, SDIO_DCTRL_RWMOD, SDIO_ReadWaitMode);
+
+ return HAL_OK;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Inc/bsp_driver_sd.h b/Inc/bsp_driver_sd.h
new file mode 100644
index 0000000..6c5a350
--- /dev/null
+++ b/Inc/bsp_driver_sd.h
@@ -0,0 +1,113 @@
+/**
+ ******************************************************************************
+ * @file bsp_driver_sd.h (based on stm3210e_eval_sd.h)
+ * @brief This file contains the common defines and functions prototypes for
+ * the bsp_driver_sd.c driver.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1XX_SD_H
+#define __STM32F1XX_SD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/* Exported constants --------------------------------------------------------*/
+
+/**
+ * @brief SD Card information structure
+ */
+#ifndef SD_CardInfo
+ #define SD_CardInfo HAL_SD_CardInfoTypedef
+#endif
+
+/**
+ * @brief SD status structure definition
+ */
+#define MSD_OK ((uint8_t)0x00)
+#define MSD_ERROR ((uint8_t)0x01)
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup STM3210E_EVAL_SD_Exported_Constants Exported_Constants
+ * @{
+ */
+#define SD_PRESENT ((uint8_t)0x01)
+#define SD_NOT_PRESENT ((uint8_t)0x00)
+#define SD_DATATIMEOUT ((uint32_t)100000000)
+
+/* USER CODE BEGIN 0 */
+
+#define __SD_DETECT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define SD_DETECT_IRQn EXTI15_10_IRQn
+
+/* DMA definitions for SD DMA transfer */
+/*
+#define __DMAx_TxRx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define SD_DMAx_Tx_INSTANCE DMA2_Channel4
+#define SD_DMAx_Rx_INSTANCE DMA2_Channel4
+#define SD_DMAx_Tx_IRQn DMA2_Channel4_5_IRQn
+#define SD_DMAx_Rx_IRQn DMA2_Channel4_5_IRQn
+#define SD_DMAx_Tx_IRQHandler DMA2_Channel4_5_IRQHandler
+#define SD_DMAx_Rx_IRQHandler DMA2_Channel4_5_IRQHandler
+*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM3210E_EVAL_SD_Exported_Functions
+ * @{
+ */
+uint8_t BSP_SD_Init(void);
+uint8_t BSP_SD_ITConfig(void);
+void BSP_SD_DetectIT(void);
+void BSP_SD_DetectCallback(void);
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks);
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks);
+uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr);
+void BSP_SD_IRQHandler(void);
+void BSP_SD_DMA_Tx_IRQHandler(void);
+void BSP_SD_DMA_Rx_IRQHandler(void);
+HAL_SD_TransferStateTypedef BSP_SD_GetStatus(void);
+void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef *CardInfo);
+uint8_t BSP_SD_IsDetected(void);
+/* USER CODE END 0 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1XX_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Inc/fatfs.h b/Inc/fatfs.h
index aca2291..bd40068 100644
--- a/Inc/fatfs.h
+++ b/Inc/fatfs.h
@@ -41,13 +41,10 @@
#include "ff.h"
#include "ff_gen_drv.h"
-#include "spisd_diskio.h" /* defines SPISD_Driver as external */
-#include "spiflash_w25q16dv.h"
-#include "usbh_diskio.h"
-
-/* USER CODE BEGIN Includes */
-
-/* USER CODE END Includes */
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ #include "spisd_diskio.h" /* defines SPISD_Driver as external */
+ #include "spiflash_w25q16dv.h"
+ #include "usbh_diskio.h"
extern char SPISD_Path[4]; /* SPI SD card logical drive path */
extern char SPIFL_Path[4]; /* SPI Flash logical drive path */
@@ -60,16 +57,18 @@ typedef enum {
SPI_FLASH
} dselect_t;
-void MX_FATFS_Init(void);
-
-/* USER CODE BEGIN Prototypes */
-
void deviceSelect(dselect_t device);
void deviceDeselect();
+#elif defined(STM32F103xE) && defined(CZMINI)
+ #include "sd_diskio.h" /* defines SD_Driver as external */
+
+extern char SD_Path[4]; /* SD logical drive path */
+#endif
+
+void MX_FATFS_Init(void);
FRESULT transferFile(const TCHAR *source, const TCHAR *dest, uint8_t overwrite);
-/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
diff --git a/Inc/mks_conf.h b/Inc/mks_conf.h
index fda19bf..7770cb6 100644
--- a/Inc/mks_conf.h
+++ b/Inc/mks_conf.h
@@ -39,34 +39,54 @@
#include "cmsis_os.h"
#include "fatfs.h"
-#define SPEAKER_Pin GPIO_PIN_2
-#define SPEAKER_GPIO_Port GPIOA
-#define FILAMENT_DI_Pin GPIO_PIN_0
-#define FILAMENT_DI_GPIO_Port GPIOB
-#define POWER_DI_Pin GPIO_PIN_1
-#define POWER_DI_GPIO_Port GPIOB
-#define LCD_nWR_Pin GPIO_PIN_14
-#define LCD_nWR_GPIO_Port GPIOB
-#define LCD_RS_Pin GPIO_PIN_13
-#define LCD_RS_GPIO_Port GPIOD
-#define LCD_BACKLIGHT_Pin GPIO_PIN_14
-#define LCD_BACKLIGHT_GPIO_Port GPIOD
-#define LCD_nRD_Pin GPIO_PIN_15
-#define LCD_nRD_GPIO_Port GPIOD
-#define LCD_nCS_Pin GPIO_PIN_8
-#define LCD_nCS_GPIO_Port GPIOC
-#define SDCARD_nCS_Pin GPIO_PIN_11
-#define SDCARD_nCS_GPIO_Port GPIOD
-#define SDCARD_DETECT_Pin GPIO_PIN_15
-#define SDCARD_DETECT_GPIO_Port GPIOB
-#define TOUCH_DI_Pin GPIO_PIN_5
-#define TOUCH_DI_GPIO_Port GPIOC
-#define TOUCH_nCS_Pin GPIO_PIN_9
-#define TOUCH_nCS_GPIO_Port GPIOC
-#define WIFI_DI_Pin GPIO_PIN_9
-#define WIFI_DI_GPIO_Port GPIOA
-#define FLASH_nCS_Pin GPIO_PIN_9
-#define FLASH_nCS_GPIO_Port GPIOB
+#if defined(STM32F107xC) && defined(MKS_TFT)
+/**
+ * Makerbase MKS-TFT32
+ */
+ #define SPEAKER_Pin GPIO_PIN_2
+ #define SPEAKER_GPIO_Port GPIOA
+ #define FILAMENT_DI_Pin GPIO_PIN_0
+ #define FILAMENT_DI_GPIO_Port GPIOB
+ #define POWER_DI_Pin GPIO_PIN_1
+ #define POWER_DI_GPIO_Port GPIOB
+ #define LCD_nWR_Pin GPIO_PIN_14
+ #define LCD_nWR_GPIO_Port GPIOB
+ #define LCD_RS_Pin GPIO_PIN_13
+ #define LCD_RS_GPIO_Port GPIOD
+ #define LCD_BACKLIGHT_Pin GPIO_PIN_14
+ #define LCD_BACKLIGHT_GPIO_Port GPIOD
+ #define LCD_nRD_Pin GPIO_PIN_15
+ #define LCD_nRD_GPIO_Port GPIOD
+ #define LCD_nCS_Pin GPIO_PIN_8
+ #define LCD_nCS_GPIO_Port GPIOC
+ #define SDCARD_nCS_Pin GPIO_PIN_11
+ #define SDCARD_nCS_GPIO_Port GPIOD
+ #define SDCARD_DETECT_Pin GPIO_PIN_15
+ #define SDCARD_DETECT_GPIO_Port GPIOB
+ #define TOUCH_DI_Pin GPIO_PIN_5
+ #define TOUCH_DI_GPIO_Port GPIOC
+ #define TOUCH_nCS_Pin GPIO_PIN_9
+ #define TOUCH_nCS_GPIO_Port GPIOC
+ #define WIFI_DI_Pin GPIO_PIN_9
+ #define WIFI_DI_GPIO_Port GPIOA
+ #define FLASH_nCS_Pin GPIO_PIN_9
+ #define FLASH_nCS_GPIO_Port GPIOB
+
+ extern SPI_HandleTypeDef hspi3;
+ #define hspi_touch (hspi3)
+
+#elif defined(STM32F103xE) && defined(CZMINI)
+ #define TOUCH_DI_Pin GPIO_PIN_12
+ #define TOUCH_DI_GPIO_Port GPIOB
+ #define TOUCH_nCS_Pin GPIO_PIN_12
+ #define TOUCH_nCS_GPIO_Port GPIOD
+ #define LCD_RESET_Pin GPIO_PIN_1
+ #define LCD_RESET_GPIO_Port GPIOE
+
+ extern SPI_HandleTypeDef hspi2;
+ #define hspi_touch (hspi2)
+
+#endif
#define VERSION_TEXT "1.17beta2R"
diff --git a/Inc/sd_diskio.h b/Inc/sd_diskio.h
new file mode 100644
index 0000000..aac277d
--- /dev/null
+++ b/Inc/sd_diskio.h
@@ -0,0 +1,41 @@
+/**
+ ******************************************************************************
+ * @file sd_diskio.h
+ * @author MCD Application Team
+ * @version V1.3.0
+ * @date 08-May-2015
+ * @brief Header for sd_diskio.c module
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2015 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __SD_DISKIO_H
+#define __SD_DISKIO_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+extern Diskio_drvTypeDef SD_Driver;
+
+#endif /* __SD_DISKIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/Inc/stm32f1xx_hal_conf.h b/Inc/stm32f1xx_hal_conf.h
index ad9d539..d2bc166 100644
--- a/Inc/stm32f1xx_hal_conf.h
+++ b/Inc/stm32f1xx_hal_conf.h
@@ -47,38 +47,23 @@
/**
* @brief This is the list of modules to be used in the HAL driver
*/
-#define HAL_MODULE_ENABLED
-/*#define HAL_ADC_MODULE_ENABLED */
-/*#define HAL_CAN_MODULE_ENABLED */
-/*#define HAL_CEC_MODULE_ENABLED */
-/*#define HAL_CORTEX_MODULE_ENABLED */
-/*#define HAL_CRC_MODULE_ENABLED */
-/*#define HAL_DAC_MODULE_ENABLED */
-/*#define HAL_DMA_MODULE_ENABLED */
-/*#define HAL_ETH_MODULE_ENABLED */
-/*#define HAL_FLASH_MODULE_ENABLED */
-#define HAL_GPIO_MODULE_ENABLED
-#define HAL_I2C_MODULE_ENABLED
-/*#define HAL_I2S_MODULE_ENABLED */
-/*#define HAL_IRDA_MODULE_ENABLED */
-/*#define HAL_IWDG_MODULE_ENABLED */
-/*#define HAL_NOR_MODULE_ENABLED */
-/*#define HAL_NAND_MODULE_ENABLED */
-/*#define HAL_PCCARD_MODULE_ENABLED */
-/*#define HAL_PCD_MODULE_ENABLED */
-#define HAL_HCD_MODULE_ENABLED
-/*#define HAL_PWR_MODULE_ENABLED */
-/*#define HAL_RCC_MODULE_ENABLED */
-/*#define HAL_RTC_MODULE_ENABLED */
-/*#define HAL_SD_MODULE_ENABLED */
-/*#define HAL_SDRAM_MODULE_ENABLED */
-/*#define HAL_SMARTCARD_MODULE_ENABLED */
-#define HAL_SPI_MODULE_ENABLED
-/*#define HAL_SRAM_MODULE_ENABLED */
-#define HAL_TIM_MODULE_ENABLED
-#define HAL_UART_MODULE_ENABLED
-/*#define HAL_USART_MODULE_ENABLED */
-/*#define HAL_WWDG_MODULE_ENABLED */
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ #define HAL_MODULE_ENABLED
+ #define HAL_GPIO_MODULE_ENABLED
+ #define HAL_I2C_MODULE_ENABLED
+ #define HAL_HCD_MODULE_ENABLED
+ #define HAL_SPI_MODULE_ENABLED
+ #define HAL_TIM_MODULE_ENABLED
+ #define HAL_UART_MODULE_ENABLED
+#elif defined(STM32F103xE) && defined(CZMINI)
+ #define HAL_MODULE_ENABLED
+ #define HAL_GPIO_MODULE_ENABLED
+ #define HAL_SD_MODULE_ENABLED
+ #define HAL_SPI_MODULE_ENABLED
+ #define HAL_SRAM_MODULE_ENABLED
+ #define HAL_TIM_MODULE_ENABLED
+ #define HAL_UART_MODULE_ENABLED
+#endif
#define HAL_CORTEX_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
diff --git a/MKS-TFT32.ebp b/MKS-TFT32.ebp
index f25ffc0..508f99c 100644
--- a/MKS-TFT32.ebp
+++ b/MKS-TFT32.ebp
@@ -6,14 +6,20 @@
+
-
-
-
+
+
+
-
+
+
+
+
+
+
@@ -21,16 +27,20 @@
-
+
+
+
+
+
-
-
+
+
@@ -47,26 +57,37 @@
-
-
-
+
+
+
-
+
+
+
+
+
+
-
+
+
+
+
+
+
-
+
+
@@ -150,11 +171,25 @@
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
@@ -191,12 +226,20 @@
+
+
+
+
+
+
+
+
@@ -206,11 +249,19 @@
+
+
+
+
+
+
+
+
-
+
@@ -228,65 +279,129 @@
-
+
+
+
+
+
+
+
+
-
+
+
+
+
-
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
@@ -353,19 +468,29 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -391,32 +516,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -427,11 +570,16 @@
-
+
+
+
+
+
+
-
+
@@ -476,7 +624,7 @@
-
+
diff --git a/STM32F103ZE_FLASH.ld b/STM32F103ZE_FLASH.ld
new file mode 100644
index 0000000..a679781
--- /dev/null
+++ b/STM32F103ZE_FLASH.ld
@@ -0,0 +1,168 @@
+/*
+*****************************************************************************
+**
+
+** File : stm32_flash.ld
+**
+** Abstract : Linker script for STM32F103ZE Device with
+** 512KByte FLASH, 64KByte RAM
+**
+** Set heap size, stack size and stack location according
+** to application requirements.
+**
+** Set memory bank area and size if external memory is used.
+**
+** Target : STMicroelectronics STM32
+**
+** Environment : Atollic TrueSTUDIO(R)
+**
+** Distribution: The file is distributed as is, without any warranty
+** of any kind.
+**
+** (c)Copyright Atollic AB.
+** You may use this file as-is or modify it according to the needs of your
+** project. This file may only be built (assembled or compiled and linked)
+** using the Atollic TrueSTUDIO(R) product. The use of this file together
+** with other tools than Atollic TrueSTUDIO(R) is not permitted.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20010000; /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K
+RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
+}
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(4);
+ } >FLASH
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbols at end of code */
+ } >FLASH
+
+ /* Constant data goes into FLASH */
+ .rodata :
+ {
+ . = ALIGN(4);
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(4);
+ } >FLASH
+
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+ .ARM : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >FLASH
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >FLASH
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >FLASH
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >FLASH
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* Initialized data sections goes into RAM, load LMA copy after code */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end */
+ } >RAM AT> FLASH
+
+
+ /* Uninitialized data section */
+ . = ALIGN(4);
+ .bss :
+ {
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .; /* define a global symbol at bss start */
+ __bss_start__ = _sbss;
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end */
+ __bss_end__ = _ebss;
+ } >RAM
+
+ /* User_heap_stack section, used to check that there is enough RAM left */
+ ._user_heap_stack :
+ {
+ . = ALIGN(4);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(4);
+ } >RAM
+
+
+
+ /* Remove information from the standard libraries */
+ /DISCARD/ :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/Src/FileManager.cpp b/Src/FileManager.cpp
index 1fa45fa..4c38e54 100644
--- a/Src/FileManager.cpp
+++ b/Src/FileManager.cpp
@@ -40,8 +40,11 @@ namespace FileManager
static FileSet gcodeFilesList(evFile, filesRoot, true);
static FileSet macroFilesList(evMacro, macrosRoot, false);
static FileSet * null displayedFileSet = nullptr;
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
static uint8_t numVolumes = 1 + 3;
+#elif defined(STM32F103xE) && defined(CZMINI)
+ static uint8_t numVolumes = 1 + 1;
+#endif
static uint8_t firstOnScrVol = 1; // how many SD card sockets we have (normally 1 or 2)
// Return true if the second string is alphabetically greater then the first, case insensitive
diff --git a/Src/PanelDue.cpp b/Src/PanelDue.cpp
index 05c64d3..fe35c52 100644
--- a/Src/PanelDue.cpp
+++ b/Src/PanelDue.cpp
@@ -22,7 +22,10 @@
#include
#include
-#include "eeprom.h"
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ #include "eeprom.h"
+#endif
+
#include "Mem.h"
#include "Display.h"
#include "UTFT.h"
@@ -127,7 +130,10 @@ struct EEPROMData
};
// FlashData must fit in the area we have reserved
+#if defined(STM32F107xC) && defined(MKS_TFT)
static_assert(sizeof(EEPROMData) <= EEPROM_SIZE, "Flash data too large");
+#endif
+
EEPROMData nvData, savedNvData;
static PrinterStatus status = PrinterStatus::connecting;
@@ -220,13 +226,17 @@ void EEPROMData::SetDefaults()
void EEPROMData::Load()
{
magic = 0xFFFFFFFF; // to make sure we know if the read failed
+#if defined(STM32F107xC) && defined(MKS_TFT)
readEEPROM(0, (uint8_t *)&(this->magic), &(this->dummy) - reinterpret_cast(&(this->magic)));
+#endif
}
// Save parameters to flash memory
void EEPROMData::Save() const
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
writeEEPROM(0, (uint8_t *)&(this->magic), &(this->dummy) - reinterpret_cast(&(this->magic)));
+#endif
}
// Return the host firmware features
@@ -324,13 +334,17 @@ void ShortenTouchDelay()
void TouchBeep()
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
Buzzer::Beep(touchBeepLength);
+#endif
}
void ErrorBeep()
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
while (Buzzer::Noisy()) { }
Buzzer::Beep(errorBeepLength);
+#endif
}
// Draw a spot and wait until the user touches it, returning the touch coordinates in tx and ty.
@@ -445,23 +459,27 @@ int GetBrightness()
// Factory reset
void FactoryReset()
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
while (Buzzer::Noisy()) { }
nvData.SetInvalid();
nvData.Save();
savedNvData = nvData;
Buzzer::Beep(400); // long beep to acknowledge it
while (Buzzer::Noisy()) { }
+#endif
Restart(); // reset the processor
}
// Save settings
void SaveSettings()
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
while (Buzzer::Noisy()) { }
nvData.Save();
// To make sure it worked, load the settings again
savedNvData.Load();
UI::CheckSettingsAreSaved();
+#endif
}
// This is called when the status changes
@@ -1161,6 +1179,7 @@ extern "C" int PanelDueMain(void)
mgr.Refresh(false);
ShowLine;
+#if defined(STM32F107xC) && defined(MKS_TFT)
// 5. Generate a beep if asked to
if (beepFrequency != 0 && beepLength != 0)
{
@@ -1175,7 +1194,7 @@ extern "C" int PanelDueMain(void)
beepFrequency = beepLength = 0;
}
ShowLine;
-
+#endif
// 6. If it is time, poll the printer status.
// When the printer is executing a homing move or other file macro, it may stop responding to polling requests.
// Under these conditions, we slow down the rate of polling to avoid building up a large queue of them.
@@ -1215,6 +1234,6 @@ void PrintDebugText(const char *x)
}
// Pure virtual function call handler, to avoid pulling in large chunks of the standard library
-// extern "C" void __cxa_pure_virtual() { while (1); }
+extern "C" void __cxa_pure_virtual() { while (1); }
// End
diff --git a/Src/UTFT.cpp b/Src/UTFT.cpp
index 986d088..f2ca497 100644
--- a/Src/UTFT.cpp
+++ b/Src/UTFT.cpp
@@ -160,6 +160,7 @@ template inline void swap(T& a, T& b)
b = temp;
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
inline void UTFT::LCD_Write_COM(uint8_t VL)
{
HAL_GPIO_WritePin(LCD_RS_GPIO_Port, LCD_RS_Pin, GPIO_PIN_RESET);
@@ -191,6 +192,34 @@ inline void UTFT::LCD_Write_Repeated_DATA16(uint16_t VHL, uint16_t num)
}
}
+#elif defined(STM32F103xE) && defined(CZMINI)
+
+static volatile uint32_t *pLcdData = (uint32_t *) 0x60080000;
+static volatile uint32_t *pLcdReg = (uint32_t *) 0x60000000;
+
+inline void UTFT::LCD_Write_COM(uint8_t VL)
+{
+ *(uint16_t *) (pLcdReg) = VL;
+}
+
+inline void UTFT::LCD_Write_DATA16(uint16_t VHL)
+{
+ *(uint16_t *) (pLcdData)= VHL;
+}
+
+inline void UTFT::LCD_Write_Repeated_DATA16(uint16_t VHL, uint16_t num) {
+
+ while (num != 0)
+ {
+ LCD_Write_DATA16 (VHL);
+ --num;
+
+ __asm__ __volatile__(""); // prevent GCC to optimize out this cycle
+ }
+}
+
+#endif
+
// Write the data num1 * num2 times, where num1 >= 1
void UTFT::LCD_Write_Repeated_DATA16(uint16_t VHL, uint16_t num1, uint16_t num2)
{
@@ -233,10 +262,17 @@ void UTFT::InitLCD(DisplayOrientation po)
disp_x_size = getDisplayXSize() - 1;
disp_y_size = getDisplayYSize() - 1;
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_nWR_GPIO_Port, LCD_nWR_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LCD_nRD_GPIO_Port, LCD_nRD_Pin, GPIO_PIN_SET);
+#elif defined(STM32F103xE) && defined(CZMINI)
+ HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_RESET);
+ osDelay (300);
+ HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_SET);
+ osDelay (100);
+#endif
switch (orient) {
case DisplayOrientation::SwapXY:
@@ -262,22 +298,26 @@ void UTFT::InitLCD(DisplayOrientation po)
break;
}
- LCD_Write_COM_DATA16(0x0001, R01h); // Driver Output Control Register (R01h)
- LCD_Write_COM_DATA16(0x0002, 0x0700); // LCD Driving Waveform Control (R02h)
- LCD_Write_COM_DATA16(0x0003, R03h); // Entry Mode (R03h)
- LCD_Write_COM_DATA16(0x0004, 0x0000); // Resizing Control Register (R04h), W
+ LCD_Write_COM_DATA16(0x0001, R01h); // Driver Output Control Register (R01h)
+ LCD_Write_COM_DATA16(0x0002, 0x0700); // LCD Driving Waveform Control (R02h)
+ LCD_Write_COM_DATA16(0x0003, R03h); // Entry Mode (R03h)
+ LCD_Write_COM_DATA16(0x0004, 0x0000); // Resizing Control Register (R04h), W
LCD_Write_COM_DATA16(0x0008, 0x0202);
LCD_Write_COM_DATA16(0x0009, 0x0000);
LCD_Write_COM_DATA16(0x000a, 0x0000);
-
+#if defined(STM32F103xE) && defined(CZMINI)
+ LCD_Write_COM_DATA16(0x000c, 0x0001); // RGB Display Interface Control 1 (R0Ch) W, RIM[1:0]=01 (16-bit RGB interface (1 transfer/pixel), DB[17:13] and DB[11:1])
+ LCD_Write_COM_DATA16(0x000d, 0x0000); // Frame Marker Position (R0Dh) W,
+ LCD_Write_COM_DATA16(0x000f, 0x0000); // RGB Display Interface Control 2 (R0Fh)
+#endif
LCD_Write_COM_DATA16(0x0010, 0x0000); // Power Control 1 (R10h)
LCD_Write_COM_DATA16(0x0011, 0x0007); // Power Control 2 (R11h)
LCD_Write_COM_DATA16(0x0012, 0x0000); // Power Control 3 (R12h)
LCD_Write_COM_DATA16(0x0013, 0x0000); // Power Control 4 (R13h)
osDelay(200);
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
LCD_Write_COM_DATA16(0x0010, 0x14B0); // Power Control 1 (R10h)
osDelay(50);
LCD_Write_COM_DATA16(0x0011, 0x0007); // Power Control 2 (R11h)
@@ -299,6 +339,37 @@ void UTFT::InitLCD(DisplayOrientation po)
LCD_Write_COM_DATA16(0x003c, 0x0203); // Gamma Control 9
LCD_Write_COM_DATA16(0x003d, 0x0403); // Gamma Control 10
+#elif defined(STM32F103xE) && defined(CZMINI)
+ LCD_Write_COM_DATA16(0x0010, 0x1590); // Power Control 1 (R10h)
+ /**
+ * AP[2:0]=1 (1.00)
+ * APE = Ó1Ô to start the generation of power supply according to the power supply startup sequence
+ * BT[3:0]=5 DDVDH=Vci1 x2 VCL=-Vci1 VGH=Vci1 x5 VGL=-Vci1 x3
+ **/
+ LCD_Write_COM_DATA16(0x0011, 0x0227); // VC[2:0]=7 (1.0xVci), DC0[2:0]=2(Fosc/4), DC1[2:0]=2(Fosc/16)
+ osDelay(50); /* delay 50 ms */
+ LCD_Write_COM_DATA16(0x0012, 0x009c); // VRH[3:0]=Vci x1.80, PON=1 (VGL output is enable), VCIRE=1 (Internal reference voltage 2.5V)
+ osDelay(50); /* delay 50 ms */
+ LCD_Write_COM_DATA16(0x0013, 0x1900); // Power Control 4 (R13h) VREG1OUT x 0.96
+
+ LCD_Write_COM_DATA16(0x0029, 0x0023); // Power Control 7 (R29h), VCM[5:0] VcomH=VREG1OUT x0.860
+ LCD_Write_COM_DATA16(0x002b, 0x000e); // Frame Rate and Color Control (R2Bh), e=112 fps
+ osDelay(50); /* delay 50 ms */
+
+ /* Gamma Control (R30h ~ R3Dh) */
+ LCD_Write_COM_DATA16(0x0030, 0x0007);
+ LCD_Write_COM_DATA16(0x0031, 0x0707);
+ LCD_Write_COM_DATA16(0x0032, 0x0006);
+ LCD_Write_COM_DATA16(0x0035, 0x0704);
+ LCD_Write_COM_DATA16(0x0036, 0x1f04);
+ LCD_Write_COM_DATA16(0x0037, 0x0004);
+ LCD_Write_COM_DATA16(0x0038, 0x0000);
+ LCD_Write_COM_DATA16(0x0039, 0x0706);
+ LCD_Write_COM_DATA16(0x003c, 0x0701);
+ LCD_Write_COM_DATA16(0x003d, 0x000f);
+ osDelay(50); /* delay 50 ms */
+#endif
+
LCD_Write_COM_DATA16(0x0050, 0x0000); // Window Horizontal RAM Address Start (R50h)
LCD_Write_COM_DATA16(0x0051, 239); // Window Horizontal RAM Address End (R51h)
LCD_Write_COM_DATA16(0x0052, 0x0000); // Window Vertical RAM Address Start (R52h)
@@ -306,17 +377,35 @@ void UTFT::InitLCD(DisplayOrientation po)
LCD_Write_COM_DATA16(0x0060, R60h); // Driver Output Control (R60h)
LCD_Write_COM_DATA16(0x0061, 0x0001); // Driver Output Control (R61h)
+#if defined(STM32F103xE) && defined(CZMINI)
+ LCD_Write_COM_DATA16(0x006a, 0x0000);
+
+ LCD_Write_COM_DATA16(0x0080, 0x0000); // Partial Image 1 Display Position (R80h)
+ LCD_Write_COM_DATA16(0x0081, 0x0000); // Partial Image 1 RAM Start/End Address (R81h, R82h)
+ LCD_Write_COM_DATA16(0x0082, 0x0000);
+ LCD_Write_COM_DATA16(0x0083, 0x0000); // Partial Image 2 Display Position (R83h)
+ LCD_Write_COM_DATA16(0x0084, 0x0000); // Partial Image 2 RAM Start/End Address (R84h, R85h)
+ LCD_Write_COM_DATA16(0x0085, 0x0000);
+#endif
LCD_Write_COM_DATA16(0x0090, 0x0010); // Panel Interface Control 1 (R90h)
-
+#if defined(STM32F103xE) && defined(CZMINI)
+ /**
+ * RTNI[4:0]=10000b (16 clocks) DIVI[1:0]=0 (fosc/1)
+ **/
+ LCD_Write_COM_DATA16(0x0092, 0x0000); // Panel Interface Control 2 (R92h) NOWI[2:0]=0 (o clk)
+ LCD_Write_COM_DATA16(0x0095, 0x0110); // Panel Interface Control 4 (R95h) (RGB interface mode)
+ LCD_Write_COM_DATA16(0x0097, 0x0000); // Panel Interface Control 5 (R97h) (RGB interface mode)
+#endif
LCD_Write_COM_DATA16(0x0007, 0x0133); // Display Control 1 (R07h) W,
osDelay(100);
setColor(0xFFFF);
setBackColor(0);
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
// turn on backlight
HAL_GPIO_WritePin(LCD_BACKLIGHT_GPIO_Port, LCD_BACKLIGHT_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
void UTFT::setXY(uint16_t p_x1, uint16_t p_y1, uint16_t p_x2, uint16_t p_y2)
@@ -530,7 +619,9 @@ void UTFT::drawCircle(int x, int y, int radius)
int x1 = 0;
int y1 = radius;
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
setXY(x, y + radius, x, y + radius);
LCD_Write_DATA16(fcolour);
setXY(x, y - radius, x, y - radius);
@@ -568,7 +659,9 @@ void UTFT::drawCircle(int x, int y, int radius)
setXY(x - y1, y - x1, x - y1, y - x1);
LCD_Write_DATA16(fcolour);
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
void UTFT::fillCircle(int x, int y, int radius)
@@ -578,8 +671,9 @@ void UTFT::fillCircle(int x, int y, int radius)
int ddF_y = -2 * radius;
int x1 = 0;
int y1 = radius;
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
setXY(x, y + radius, x, y + radius);
LCD_Write_DATA16(fcolour);
setXY(x, y - radius, x, y - radius);
@@ -607,23 +701,33 @@ void UTFT::fillCircle(int x, int y, int radius)
setXY(x - y1, y - x1, x + y1, y - x1);
LCD_Write_Repeated_DATA16(fcolour, y1 + y1);
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
void UTFT::fillScr(Colour c, uint16_t leftMargin)
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
setXY(leftMargin, 0, getDisplayXSize() - 1, getDisplayYSize() - 1);
LCD_Write_Repeated_DATA16(c, getDisplayXSize() - leftMargin, getDisplayYSize());
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
void UTFT::drawPixel(int x, int y)
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
setXY(x, y, x, y);
LCD_Write_DATA16(fcolour);
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
void UTFT::drawLine(int x1, int y1, int x2, int y2)
@@ -652,8 +756,9 @@ void UTFT::drawLine(int x1, int y1, int x2, int y2)
int sx = (x1 < x2) ? 1 : -1;
int sy = (y1 < y2) ? 1 : -1;
int err = dx - dy;
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
for (;;)
{
setXY(x1, y1, x1, y1);
@@ -671,24 +776,34 @@ void UTFT::drawLine(int x1, int y1, int x2, int y2)
y1 += sy;
}
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
}
void UTFT::drawHLine(int x, int y, int len)
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
setXY(x, y, x+len, y);
LCD_Write_Repeated_DATA16(fcolour, len + 1);
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
void UTFT::drawVLine(int x, int y, int len)
{
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
setXY(x, y, x, y+len);
LCD_Write_Repeated_DATA16(fcolour, len + 1);
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
// New print functions
@@ -716,11 +831,14 @@ void UTFT::clearToMargin()
{
ySize = getDisplayYSize() - textYpos;
}
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
setXY(textXpos, textYpos, textRightMargin - 1, textYpos + ySize - 1);
LCD_Write_Repeated_DATA16(bcolour, textRightMargin - textXpos, ySize);
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
}
@@ -820,8 +938,9 @@ size_t UTFT::writeNative(uint32_t c)
const uint32_t cmask = (1UL << cfont.ySize()) - 1;
uint8_t nCols = *(uint8_t*)(fontPtr++);
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
-
+#endif
if (lastCharColData != 0) // if we have written anything other than spaces
{
uint8_t numSpaces = cfont.spaces();
@@ -929,7 +1048,9 @@ size_t UTFT::writeNative(uint32_t c)
--nCols;
++textXpos;
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
return 1;
}
@@ -950,7 +1071,9 @@ void UTFT::setFont(const uint8_t* font)
void UTFT::drawBitmap16(int x, int y, int sx, int sy, const uint16_t * data, int scale, bool byCols)
{
int curY = y;
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
for (int ty = 0; ty < sy; ty++)
{
for (int i = 0; i < scale; ++i)
@@ -984,14 +1107,18 @@ void UTFT::drawBitmap16(int x, int y, int sx, int sy, const uint16_t * data, int
++curY;
}
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
// Seaw a bitmap using 4-bit colours and a palette
void UTFT::drawBitmap4(int x, int y, int sx, int sy, const uint8_t * data, Palette palette, int scale, bool byCols)
{
int curY = y;
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
for (int ty = 0; ty < sy; ty++)
{
for (int i = 0; i < scale; ++i)
@@ -1026,7 +1153,9 @@ void UTFT::drawBitmap4(int x, int y, int sx, int sy, const uint8_t * data, Palet
++curY;
}
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
// Draw a compressed bitmap. Data comprises alternate (repeat count - 1, data to write) pairs, both as 16-bit values.
@@ -1036,7 +1165,9 @@ void UTFT::drawCompressedBitmap(int x, int y, int sx, int sy, const uint16_t *da
uint16_t col = 0;
sx += x;
sy += y;
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
for (int tx = x; tx < sx; tx++)
{
for (int ty = y; ty < sy; ty++)
@@ -1054,7 +1185,9 @@ void UTFT::drawCompressedBitmap(int x, int y, int sx, int sy, const uint16_t *da
LCD_Write_DATA16(col);
}
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
// Draw a compressed bitmap. Data comprises alternate (repeat count - 1, data to write) pairs, both as 16-bit values.
@@ -1064,7 +1197,9 @@ void UTFT::drawCompressedBitmapBottomToTop(int x, int y, int sx, int sy, const u
uint16_t col = 0;
sx += x;
sy += y;
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_RESET);
+#endif
for (int ty = sy; ty != 0; )
{
--ty;
@@ -1083,5 +1218,7 @@ void UTFT::drawCompressedBitmapBottomToTop(int x, int y, int sx, int sy, const u
LCD_Write_DATA16(col);
}
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(LCD_nCS_GPIO_Port, LCD_nCS_Pin, GPIO_PIN_SET);
+#endif
}
diff --git a/Src/UTouch.cpp b/Src/UTouch.cpp
index 12b9d82..65dbf80 100644
--- a/Src/UTouch.cpp
+++ b/Src/UTouch.cpp
@@ -7,10 +7,9 @@
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
+#include "mks_conf.h"
#include "UTouch.h"
-extern SPI_HandleTypeDef hspi3;
-
void UTouch::init(uint16_t xp, uint16_t yp, DisplayOrientation orientationAdjust)
{
orientAdjust = orientationAdjust;
@@ -29,9 +28,9 @@ void UTouch::init(uint16_t xp, uint16_t yp, DisplayOrientation orientationAdjust
osDelay(50);
/* warmup */
- HAL_SPI_TransmitReceive(&hspi3, pTxData, pRxData, 3, 1000);
+ HAL_SPI_TransmitReceive(&hspi_touch, pTxData, pRxData, 3, 1000);
pTxData[0] = 0x94;
- HAL_SPI_TransmitReceive(&hspi3, pTxData, pRxData, 3, 1000);
+ HAL_SPI_TransmitReceive(&hspi_touch, pTxData, pRxData, 3, 1000);
// HAL_GPIO_WritePin(TOUCH_nCS_GPIO_Port, TOUCH_nCS_Pin, GPIO_PIN_SET);
}
@@ -102,7 +101,7 @@ bool UTouch::getTouchData(bool wantY, uint16_t &rslt)
uint8_t pRxData[3];
/* warmup */
- HAL_SPI_Transmit(&hspi3, pTxData, 3, 1000);
+ HAL_SPI_Transmit(&hspi_touch, pTxData, 3, 1000);
const size_t numReadings = 6;
const uint16_t maxDiff = 70; // needs to be big enough to handle jitter.
@@ -116,7 +115,7 @@ bool UTouch::getTouchData(bool wantY, uint16_t &rslt)
// Take enough readings to fill the ring buffer
for (size_t i = 0; i < numReadings; ++i)
{
- HAL_SPI_TransmitReceive(&hspi3, pTxData, pRxData, 3, 1000);
+ HAL_SPI_TransmitReceive(&hspi_touch, pTxData, pRxData, 3, 1000);
uint16_t val = (((uint16_t)pRxData[1] << 8) + pRxData[2]) >> 3;
ring[i] = val;
@@ -150,7 +149,7 @@ bool UTouch::getTouchData(bool wantY, uint16_t &rslt)
// Take another reading
sum -= ring[last];
- HAL_SPI_TransmitReceive(&hspi3, pTxData, pRxData, 3, 1000);
+ HAL_SPI_TransmitReceive(&hspi_touch, pTxData, pRxData, 3, 1000);
uint16_t val = (((uint16_t)pRxData[1] << 8) + pRxData[2]) >> 3;
ring[last] = val;
@@ -159,9 +158,9 @@ bool UTouch::getTouchData(bool wantY, uint16_t &rslt)
}
pTxData[0] &= 0xF8;
- HAL_SPI_Transmit(&hspi3, pTxData, 3, 1000);
+ HAL_SPI_Transmit(&hspi_touch, pTxData, 3, 1000);
pTxData[0] = 0;
- HAL_SPI_Transmit(&hspi3, pTxData, 3, 1000); // read the final data
+ HAL_SPI_Transmit(&hspi_touch, pTxData, 3, 1000); // read the final data
rslt = avg;
return ok;
}
diff --git a/Src/bsp_driver_sd.c b/Src/bsp_driver_sd.c
new file mode 100644
index 0000000..ad9e85d
--- /dev/null
+++ b/Src/bsp_driver_sd.c
@@ -0,0 +1,304 @@
+/**
+ ******************************************************************************
+ * @file bsp_driver_sd.c for F1 (based on stm3210e_eval_sd.c)
+ * @brief This file includes a generic uSD card driver.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+#define BUS_4BITS 1
+/* USER CODE BEGIN 0 */
+/* Includes ------------------------------------------------------------------*/
+#include "bsp_driver_sd.h"
+
+/* Extern variables ---------------------------------------------------------*/
+
+extern SD_HandleTypeDef hsd;
+extern HAL_SD_CardInfoTypedef SDCardInfo;
+
+/**
+ * @brief Initializes the SD card device.
+ * @retval SD status
+ */
+uint8_t BSP_SD_Init(void)
+{
+ uint8_t sd_state = MSD_OK;
+ /* Check if the SD card is plugged in the slot */
+ if (BSP_SD_IsDetected() != SD_PRESENT)
+ {
+ return MSD_ERROR;
+ }
+ /* HAL SD initialization */
+ sd_state = HAL_SD_Init(&hsd, &SDCardInfo);
+#ifdef BUS_4BITS
+ /* Configure SD Bus width */
+ if (sd_state == MSD_OK)
+ {
+ /* Enable wide operation */
+ if (HAL_SD_WideBusOperation_Config(&hsd, SDIO_BUS_WIDE_4B) != SD_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+ else
+ {
+ sd_state = MSD_OK;
+ }
+ }
+#endif
+ return sd_state;
+}
+
+/**
+ * @brief Configures Interrupt mode for SD detection pin.
+ * @retval Returns 0 in success otherwise 1.
+ */
+uint8_t BSP_SD_ITConfig(void)
+{
+ /* TBI: add user code here depending on the hardware configuration used */
+
+ return (uint8_t)0;
+}
+
+/** @brief SD detect IT treatment
+ */
+void BSP_SD_DetectIT(void)
+{
+ /* SD detect IT callback */
+ BSP_SD_DetectCallback();
+
+}
+
+/** @brief SD detect IT detection callback
+ */
+__weak void BSP_SD_DetectCallback(void)
+{
+ /* NOTE: This function Should not be modified, when the callback is needed,
+ the BSP_SD_DetectCallback could be implemented in the user file
+ */
+
+}
+
+/**
+ * @brief Reads block(s) from a specified address in an SD card, in polling mode.
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param ReadAddr: Address from where data is to be read
+ * @param BlockSize: SD card data block size, that should be 512
+ * @param NumOfBlocks: Number of SD blocks to read
+ * @retval SD status
+ */
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
+{
+ uint8_t sd_state;
+ if(HAL_SD_ReadBlocks(&hsd, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+ else
+ {
+ sd_state = MSD_OK;
+ }
+ return sd_state;
+}
+
+/**
+ * @brief Writes block(s) to a specified address in an SD card, in polling mode.
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param WriteAddr: Address from where data is to be written
+ * @param BlockSize: SD card data block size, that should be 512
+ * @param NumOfBlocks: Number of SD blocks to write
+ * @retval SD status
+ */
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
+{
+ uint8_t sd_state;
+ if(HAL_SD_WriteBlocks(&hsd, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+ else
+ {
+ sd_state = MSD_OK;
+ }
+ return sd_state;
+}
+
+/**
+ * @brief Reads block(s) from a specified address in an SD card, in DMA mode.
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param ReadAddr: Address from where data is to be read
+ * @param BlockSize: SD card data block size, that should be 512
+ * @param NumOfBlocks: Number of SD blocks to read
+ * @retval SD status
+ */
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
+{
+ uint8_t sd_state = MSD_OK;
+
+ /* Read block(s) in DMA transfer mode */
+ if(HAL_SD_ReadBlocks_DMA(&hsd, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+
+ /* Wait until transfer is complete */
+ if(sd_state == MSD_OK)
+ {
+ if(HAL_SD_CheckReadOperation(&hsd, (uint32_t)SD_DATATIMEOUT) != SD_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+ else
+ {
+ sd_state = MSD_OK;
+ }
+ }
+
+ return sd_state;
+}
+
+/**
+ * @brief Writes block(s) to a specified address in an SD card, in DMA mode.
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param WriteAddr: Address from where data is to be written
+ * @param BlockSize: SD card data block size, that should be 512
+ * @param NumOfBlocks: Number of SD blocks to write
+ * @retval SD status
+ */
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
+{
+ uint8_t sd_state = MSD_OK;
+
+ /* Write block(s) in DMA transfer mode */
+ if(HAL_SD_WriteBlocks_DMA(&hsd, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+
+ /* Wait until transfer is complete */
+ if(sd_state == MSD_OK)
+ {
+ if(HAL_SD_CheckWriteOperation(&hsd, (uint32_t)SD_DATATIMEOUT) != SD_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+ else
+ {
+ sd_state = MSD_OK;
+ }
+ }
+
+ return sd_state;
+}
+
+/**
+ * @brief Erases the specified memory area of the given SD card.
+ * @param StartAddr: Start byte address
+ * @param EndAddr: End byte address
+ * @retval SD status
+ */
+uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr)
+{
+ uint8_t sd_state;
+ if(HAL_SD_Erase(&hsd, StartAddr, EndAddr) != SD_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+ else
+ {
+ sd_state = MSD_OK;
+ }
+ return sd_state;
+}
+
+/**
+ * @brief Handles SD card interrupt request.
+ */
+void BSP_SD_IRQHandler(void)
+{
+ HAL_SD_IRQHandler(&hsd);
+}
+
+/**
+ * @brief Handles SD DMA Tx transfer interrupt request.
+ */
+void BSP_SD_DMA_Tx_IRQHandler(void)
+{
+ HAL_DMA_IRQHandler(hsd.hdmatx);
+}
+
+/**
+ * @brief Handles SD DMA Rx transfer interrupt request.
+ */
+void BSP_SD_DMA_Rx_IRQHandler(void)
+{
+ HAL_DMA_IRQHandler(hsd.hdmarx);
+}
+
+/**
+ * @brief Gets the current SD card data status.
+ * @retval Data transfer state.
+ * This value can be one of the following values:
+ * @arg SD_TRANSFER_OK: No data transfer is acting
+ * @arg SD_TRANSFER_BUSY: Data transfer is acting
+ * @arg SD_TRANSFER_ERROR: Data transfer error
+ */
+HAL_SD_TransferStateTypedef BSP_SD_GetStatus(void)
+{
+ return(HAL_SD_GetStatus(&hsd));
+}
+
+/**
+ * @brief Get SD information about specific SD card.
+ * @param CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
+ */
+void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef* CardInfo)
+{
+ /* Get SD card Information */
+ HAL_SD_Get_CardInfo(&hsd, CardInfo);
+}
+/* USER CODE END 0 */
+
+/**
+ * @brief Detects if SD card is correctly plugged in the memory slot or not.
+ * @retval Returns if SD is detected or not
+ */
+uint8_t BSP_SD_IsDetected(void)
+{
+ __IO uint8_t status = SD_PRESENT;
+
+ /* USER CODE BEGIN 1 */
+ /* user code can be inserted here */
+ /* USER CODE END 1 */
+
+ return status;
+}
+
+/* USER CODE BEGIN AdditionalCode */
+/* user code can be inserted here */
+/* USER CODE END AdditionalCode */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Src/fatfs.c b/Src/fatfs.c
index a055a6c..584527e 100644
--- a/Src/fatfs.c
+++ b/Src/fatfs.c
@@ -34,10 +34,15 @@
#include "fatfs.h"
#include "mks_conf.h"
-char SPISD_Path[4]; /* USER logical drive path */
-char SPIFL_Path[4]; /* SPI Flash logical drive path */
-char USBH_Path[4]; /* USB stick logical drive path */
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
+char SPISD_Path[4]; /* USER logical drive path */
+char SPIFL_Path[4]; /* SPI Flash logical drive path */
+char USBH_Path[4]; /* USB stick logical drive path */
+#elif defined(STM32F103xE) && defined(CZMINI)
+char SD_Path[4]; /* SD logical drive path */
+#endif
+
+#if defined(STM32F107xC) && defined(MKS_TFT)
void deviceSelect(dselect_t device) {
if (device == SPI_SDCARD) {
@@ -53,6 +58,7 @@ void deviceDeselect() {
HAL_GPIO_WritePin(SDCARD_nCS_GPIO_Port, SDCARD_nCS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(FLASH_nCS_GPIO_Port, FLASH_nCS_Pin, GPIO_PIN_SET);
}
+#endif
FRESULT transferFile(const TCHAR *source, const TCHAR *dest, uint8_t overwrite) {
@@ -102,14 +108,14 @@ FRESULT transferFile(const TCHAR *source, const TCHAR *dest, uint8_t overwrite)
void MX_FATFS_Init(void)
{
- /*## FatFS: Link the USER driver ###########################*/
- FATFS_LinkDriver(&SPIFLASH_Driver, SPIFL_Path); // 0:/
- FATFS_LinkDriver(&SPISD_Driver, SPISD_Path); // 1:/
- FATFS_LinkDriver(&USBH_Driver, USBH_Path); // 2:/
-
- /* USER CODE BEGIN Init */
- /* additional user code for init */
- /* USER CODE END Init */
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ /*## FatFS: Link the USER driver ###########################*/
+ FATFS_LinkDriver(&SPIFLASH_Driver, SPIFL_Path); // 0:/
+ FATFS_LinkDriver(&SPISD_Driver, SPISD_Path); // 1:/
+ FATFS_LinkDriver(&USBH_Driver, USBH_Path); // 2:/
+#elif defined(STM32F103xE) && defined(CZMINI)
+ FATFS_LinkDriver(&SD_Driver, SD_Path);
+#endif
}
/**
@@ -119,9 +125,9 @@ void MX_FATFS_Init(void)
*/
DWORD get_fattime(void)
{
- /* USER CODE BEGIN get_fattime */
- return 0;
- /* USER CODE END get_fattime */
+ /* USER CODE BEGIN get_fattime */
+ return 0;
+ /* USER CODE END get_fattime */
}
/* USER CODE BEGIN Application */
diff --git a/Src/main.c b/Src/main.c
index 3e22270..a66cc10 100644
--- a/Src/main.c
+++ b/Src/main.c
@@ -34,32 +34,50 @@
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include "fatfs.h"
-#include "usb_host.h"
-/* USER CODE BEGIN Includes */
#include "mks_conf.h"
-#include "Buzzer.h"
-/* USER CODE END Includes */
+#if defined(STM32F107xC) && defined(MKS_TFT)
+# include "usb_host.h"
+# include "Buzzer.h"
-/* Private variables ---------------------------------------------------------*/
+FATFS flashFileSystem; // 0:/
+FATFS usbFileSystem; // 2:/
+
+UART_HandleTypeDef huart3;
I2C_HandleTypeDef hi2c1;
SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi3;
+TIM_HandleTypeDef htim2;
-UART_HandleTypeDef huart2;
-UART_HandleTypeDef huart3;
-DMA_HandleTypeDef hdma_usart2_rx;
+static void MX_USART3_UART_Init(void);
-TIM_HandleTypeDef htim2;
+static void MX_I2C1_Init(void);
+static void MX_SPI1_Init(void);
+static void MX_SPI3_Init(void);
+
+static void MX_TIM2_Init(void);
+
+#elif defined(STM32F103xE) && defined(CZMINI)
+# include "bsp_driver_sd.h"
+
+SD_HandleTypeDef hsd;
+SRAM_HandleTypeDef hsram1;
+HAL_SD_CardInfoTypedef SDCardInfo;
+
+SPI_HandleTypeDef hspi2;
+
+static void MX_SDIO_SD_Init(void);
+static void MX_FSMC_Init(void);
+static void MX_SPI2_Init(void);
+
+#endif
-FATFS flashFileSystem; // 0:/
FATFS sdFileSystem; // 1:/
-FATFS usbFileSystem; // 2:/
-/* USER CODE BEGIN PV */
-/* Private variables ---------------------------------------------------------*/
+UART_HandleTypeDef huart2;
+DMA_HandleTypeDef hdma_usart2_rx;
static osThreadId uiTaskHandle; // UI thread
static osThreadId serviceTaskHandle; // low latency tasks
@@ -71,23 +89,12 @@ static osThreadId serviceTaskHandle; // low latency tasks
// QueueHandle_t xUIEventQueue;
// QueueHandle_t xPCommEventQueue;
-/* USER CODE END PV */
-
-/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
-static void MX_TIM2_Init(void);
-static void MX_I2C1_Init(void);
-static void MX_SPI1_Init(void);
-static void MX_SPI3_Init(void);
-
-static void MX_USART3_UART_Init(void);
-/* USER CODE BEGIN PFP */
-/* Private function prototypes -----------------------------------------------*/
void StartUITask(void const * argument);
void StartServiceTask(void const * argument);
@@ -95,9 +102,7 @@ void StartServiceTask(void const * argument);
// void StartComm2Task(void const * argument);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
-/* USER CODE END PFP */
-/* USER CODE BEGIN 0 */
SemaphoreHandle_t xSDSemaphore;
SemaphoreHandle_t xUSBSemaphore;
volatile uint8_t usbEvent;
@@ -106,28 +111,35 @@ volatile uint8_t usbEvent;
// static SemaphoreHandle_t xComm2Semaphore;
int PanelDueMain(void);
-/* USER CODE END 0 */
int main(void)
{
HAL_Init();
- /* Configure the system clock */
SystemClock_Config();
- /* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
+
+#if defined(STM32F107xC) && defined(MKS_TFT)
MX_TIM2_Init();
MX_I2C1_Init();
MX_SPI1_Init();
MX_SPI3_Init();
MX_USART3_UART_Init();
+#endif
+
+#if defined(STM32F103xE) && defined(CZMINI)
+ MX_SDIO_SD_Init();
+ MX_FSMC_Init();
+ MX_SPI2_Init();
+#endif
MX_FATFS_Init();
+#if defined(STM32F107xC) && defined(MKS_TFT)
MX_USB_HOST_Init();
-
+#endif
xSDSemaphore = xSemaphoreCreateBinary();
xUSBSemaphore = xSemaphoreCreateBinary();
@@ -164,147 +176,249 @@ int main(void)
*/
void SystemClock_Config(void)
{
+ RCC_OscInitTypeDef RCC_OscInitStruct;
+ RCC_ClkInitTypeDef RCC_ClkInitStruct;
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ RCC_PeriphCLKInitTypeDef PeriphClkInit;
+#endif
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
+ RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
+ RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
+ RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
+ RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
+#endif
+#if defined(STM32F103xE) && defined(CZMINI)
+ RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
+#endif
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ Error_Handler();
+
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
+ Error_Handler();
+
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
+ PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV3;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ Error_Handler();
+#endif
- RCC_OscInitTypeDef RCC_OscInitStruct;
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
- RCC_PeriphCLKInitTypeDef PeriphClkInit;
-
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
- RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
- RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
- RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
- RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
-
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
- {
- Error_Handler();
- }
-
- PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
- PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV3;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
- {
- Error_Handler();
- }
-
- HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
-
- HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
-
- __HAL_RCC_PLLI2S_ENABLE();
-
- /* SysTick_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
+ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
+ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ __HAL_RCC_PLLI2S_ENABLE();
+#endif
+ HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
}
-/* I2C1 init function */
+#if defined(STM32F107xC) && defined(MKS_TFT)
static void MX_I2C1_Init(void)
{
-
- hi2c1.Instance = I2C1;
- hi2c1.Init.ClockSpeed = I2C_FAST_MODE_MAX_CLK;
- hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
- hi2c1.Init.OwnAddress1 = 0;
- hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
- hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
- hi2c1.Init.OwnAddress2 = 0;
- hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
- hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
- if (HAL_I2C_Init(&hi2c1) != HAL_OK)
- {
- Error_Handler();
- }
+ hi2c1.Instance = I2C1;
+ hi2c1.Init.ClockSpeed = I2C_FAST_MODE_MAX_CLK;
+ hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
+ hi2c1.Init.OwnAddress1 = 0;
+ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+ hi2c1.Init.OwnAddress2 = 0;
+ hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+ hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+ if (HAL_I2C_Init(&hi2c1) != HAL_OK)
+ Error_Handler();
}
-/* SPI1 init function */
static void MX_SPI1_Init(void)
{
-
- hspi1.Instance = SPI1;
- hspi1.Init.Mode = SPI_MODE_MASTER;
- hspi1.Init.Direction = SPI_DIRECTION_2LINES;
- hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
- hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
- hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
- hspi1.Init.NSS = SPI_NSS_SOFT;
- hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // was: 32
- hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
- hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
- hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
- hspi1.Init.CRCPolynomial = 10;
- if (HAL_SPI_Init(&hspi1) != HAL_OK)
- {
- Error_Handler();
- }
+ hspi1.Instance = SPI1;
+ hspi1.Init.Mode = SPI_MODE_MASTER;
+ hspi1.Init.Direction = SPI_DIRECTION_2LINES;
+ hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
+ hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
+ hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
+ hspi1.Init.NSS = SPI_NSS_SOFT;
+ hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // was: 32
+ hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
+ hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
+ hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+ hspi1.Init.CRCPolynomial = 10;
+ if (HAL_SPI_Init(&hspi1) != HAL_OK)
+ Error_Handler();
}
-/* SPI3 init function */
static void MX_SPI3_Init(void)
{
-
- hspi3.Instance = SPI3;
- hspi3.Init.Mode = SPI_MODE_MASTER;
- hspi3.Init.Direction = SPI_DIRECTION_2LINES;
- hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
- hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
- hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
- hspi3.Init.NSS = SPI_NSS_SOFT;
- hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
- hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
- hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
- hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
- hspi3.Init.CRCPolynomial = 10;
- if (HAL_SPI_Init(&hspi3) != HAL_OK)
- {
- Error_Handler();
- }
+ hspi3.Instance = SPI3;
+ hspi3.Init.Mode = SPI_MODE_MASTER;
+ hspi3.Init.Direction = SPI_DIRECTION_2LINES;
+ hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
+ hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
+ hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
+ hspi3.Init.NSS = SPI_NSS_SOFT;
+ hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
+ hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
+ hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
+ hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+ hspi3.Init.CRCPolynomial = 10;
+ if (HAL_SPI_Init(&hspi3) != HAL_OK)
+ Error_Handler();
}
-/* USART3 init function */
static void MX_USART3_UART_Init(void)
{
+ huart3.Instance = USART3;
+ huart3.Init.BaudRate = 115200;
+ huart3.Init.WordLength = UART_WORDLENGTH_8B;
+ huart3.Init.StopBits = UART_STOPBITS_1;
+ huart3.Init.Parity = UART_PARITY_NONE;
+ huart3.Init.Mode = UART_MODE_TX_RX;
+ huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart3.Init.OverSampling = UART_OVERSAMPLING_16;
+ if (HAL_UART_Init(&huart3) != HAL_OK)
+ Error_Handler();
+}
- huart3.Instance = USART3;
- huart3.Init.BaudRate = 115200;
- huart3.Init.WordLength = UART_WORDLENGTH_8B;
- huart3.Init.StopBits = UART_STOPBITS_1;
- huart3.Init.Parity = UART_PARITY_NONE;
- huart3.Init.Mode = UART_MODE_TX_RX;
- huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- huart3.Init.OverSampling = UART_OVERSAMPLING_16;
- if (HAL_UART_Init(&huart3) != HAL_OK)
- {
- Error_Handler();
- }
+/* TIM2 init function */
+static void MX_TIM2_Init(void)
+{
+ TIM_ClockConfigTypeDef sClockSourceConfig;
+ TIM_MasterConfigTypeDef sMasterConfig;
+ TIM_OC_InitTypeDef sConfigOC;
+
+ htim2.Instance = TIM2;
+ htim2.Init.Prescaler = 0;
+ htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
+ htim2.Init.Period = 14399;
+ htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+ if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
+ Error_Handler();
+ }
+
+ sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
+ if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
+ Error_Handler();
+ }
+
+ if (HAL_TIM_OC_Init(&htim2) != HAL_OK) {
+ Error_Handler();
+ }
+
+ sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC3REF;
+ sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+ if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig)
+ != HAL_OK) {
+ Error_Handler();
+ }
+
+ sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
+ sConfigOC.Pulse = 1;
+ sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
+ sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
+ if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) {
+ Error_Handler();
+ }
+
+ HAL_TIM_MspPostInit(&htim2);
}
+#elif defined(STM32F103xE) && defined(CZMINI)
+static void MX_SDIO_SD_Init(void)
+{
+ hsd.Instance = SDIO;
+ hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
+ hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
+ hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
+ hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
+ hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
+ hsd.Init.ClockDiv = 2;
+
+}
+
+static void MX_SPI2_Init(void)
+{
+ hspi2.Instance = SPI2;
+ hspi2.Init.Mode = SPI_MODE_MASTER;
+ hspi2.Init.Direction = SPI_DIRECTION_2LINES;
+ hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
+ hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
+ hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
+ hspi2.Init.NSS = SPI_NSS_SOFT;
+ hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
+ hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
+ hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
+ hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+ hspi2.Init.CRCPolynomial = 10;
+ if (HAL_SPI_Init(&hspi2) != HAL_OK)
+ Error_Handler();
+}
+
+/* FSMC initialization function */
+static void MX_FSMC_Init(void)
+{
+ FSMC_NORSRAM_TimingTypeDef Timing;
+
+ /** Perform the SRAM1 memory initialization sequence
+ */
+ hsram1.Instance = FSMC_NORSRAM_DEVICE;
+ hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
+ /* hsram1.Init */
+ hsram1.Init.NSBank = FSMC_NORSRAM_BANK1;
+ hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
+ hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
+ hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
+ hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
+ hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
+ hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
+ hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
+ hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
+ hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
+ hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
+ hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
+ hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
+ /* Timing */
+ Timing.AddressSetupTime = 1;
+ Timing.AddressHoldTime = 1;
+ Timing.DataSetupTime = 2;
+ Timing.BusTurnAroundDuration = 0;
+ Timing.CLKDivision = 16;
+ Timing.DataLatency = 17;
+ Timing.AccessMode = FSMC_ACCESS_MODE_A;
+ /* ExtTiming */
+
+ if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
+ Error_Handler();
+
+ /** Disconnect NADV
+ */
+
+ __HAL_AFIO_FSMCNADV_DISCONNECTED();
+}
+
+#endif
+
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
- /* DMA controller clock enable */
- __HAL_RCC_DMA1_CLK_ENABLE();
+ /* DMA controller clock enable */
+ __HAL_RCC_DMA1_CLK_ENABLE();
- /* DMA interrupt init */
- /* DMA1_Channel6_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
+ /* DMA interrupt init */
+ /* DMA1_Channel6_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
}
/** Configure pins as
@@ -326,38 +440,34 @@ static void MX_GPIO_Init(void)
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
- /*Configure GPIO pin Output Level */
+#if defined(STM32F107xC) && defined(MKS_TFT)
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9
|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET);
-
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOB, LCD_nWR_Pin|FLASH_nCS_Pin, GPIO_PIN_RESET);
-
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOD, SDCARD_nCS_Pin|LCD_RS_Pin|LCD_BACKLIGHT_Pin|LCD_nRD_Pin, GPIO_PIN_RESET);
-
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOC, LCD_nCS_Pin|TOUCH_nCS_Pin, GPIO_PIN_RESET);
-
- /*Configure GPIO pins : PE2 PE3 PE4 PE5
- PE6 PE7 PE8 PE9
- PE10 PE11 PE12 PE13
- PE14 PE15 PE0 PE1 */
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9
|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+#elif defined(STM32F103xE) && defined(CZMINI)
+ HAL_GPIO_WritePin(GPIOE, LCD_RESET_Pin, GPIO_PIN_RESET);
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+#endif
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pin : TOUCH_DI_Pin */
GPIO_InitStruct.Pin = TOUCH_DI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // FALLING - touch, RISING - no touch
GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+ HAL_GPIO_Init(TOUCH_DI_GPIO_Port, &GPIO_InitStruct);
+
+#if defined(STM32F107xC) && defined(MKS_TFT)
+ HAL_GPIO_WritePin(GPIOB, LCD_nWR_Pin|FLASH_nCS_Pin, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOD, SDCARD_nCS_Pin|LCD_RS_Pin|LCD_BACKLIGHT_Pin|LCD_nRD_Pin, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOC, LCD_nCS_Pin|TOUCH_nCS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : FILAMENT_DI_Pin POWER_DI_Pin */
GPIO_InitStruct.Pin = FILAMENT_DI_Pin|POWER_DI_Pin;
@@ -407,49 +517,19 @@ static void MX_GPIO_Init(void)
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0); // touch irq
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
-}
-/* TIM2 init function */
-static void MX_TIM2_Init(void)
-{
- TIM_ClockConfigTypeDef sClockSourceConfig;
- TIM_MasterConfigTypeDef sMasterConfig;
- TIM_OC_InitTypeDef sConfigOC;
+#elif defined(STM32F103xE) && defined(CZMINI)
- htim2.Instance = TIM2;
- htim2.Init.Prescaler = 0;
- htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim2.Init.Period = 14399;
- htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
- Error_Handler();
- }
-
- sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
- if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
- Error_Handler();
- }
-
- if (HAL_TIM_OC_Init(&htim2) != HAL_OK) {
- Error_Handler();
- }
-
- sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC3REF;
- sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
- if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig)
- != HAL_OK) {
- Error_Handler();
- }
-
- sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
- sConfigOC.Pulse = 1;
- sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
- sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
- if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) {
- Error_Handler();
- }
+ /*Configure GPIO pin : TOUCH_nCS_Pin */
+ GPIO_InitStruct.Pin = TOUCH_nCS_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(TOUCH_nCS_GPIO_Port, &GPIO_InitStruct);
- HAL_TIM_MspPostInit(&htim2);
+ /* EXTI interrupt init*/
+ HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
+ HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
+#endif
}
/* USER CODE BEGIN 4 */
@@ -465,6 +545,7 @@ void vApplicationMallocFailedHook(void) {
* (BYTE *) 0 = 0;
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
@@ -479,16 +560,22 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
break;
}
}
+#endif
void StartServiceTask(void const * argument) {
BYTE power;
+#if defined(STM32F107xC) && defined(MKS_TFT)
f_mount(&flashFileSystem, SPIFL_Path, 1); // mount flash
if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(SDCARD_DETECT_GPIO_Port, SDCARD_DETECT_Pin))
f_mount(&sdFileSystem, SPISD_Path, 1);
+#elif defined(STM32F103xE) && defined(CZMINI)
+ f_mount(&sdFileSystem, SD_Path, 1);
+#endif
while (1) {
+#if defined(STM32F107xC) && defined(MKS_TFT)
BuzzerCheckStop();
if (xSemaphoreTake(xSDSemaphore, 1) == pdTRUE) {
@@ -505,7 +592,9 @@ void StartServiceTask(void const * argument) {
break;
}
}
+#endif
+#if defined(STM32F107xC) && defined(MKS_TFT)
if (xSemaphoreTake(xUSBSemaphore, 1) == pdTRUE) {
switch (usbEvent) {
case HOST_USER_DISCONNECTION:
@@ -517,6 +606,11 @@ void StartServiceTask(void const * argument) {
break;
}
}
+#endif
+
+#if defined(STM32F103xE) && defined(CZMINI)
+ osDelay(1);
+#endif
}
}
diff --git a/Src/sd_diskio.c b/Src/sd_diskio.c
new file mode 100644
index 0000000..651457b
--- /dev/null
+++ b/Src/sd_diskio.c
@@ -0,0 +1,200 @@
+/**
+ ******************************************************************************
+ * @file sd_diskio.c
+ * @author MCD Application Team
+ * @version V1.3.0
+ * @date 08-May-2015
+ * @brief SD Disk I/O driver
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2015 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include
+#include "ff_gen_drv.h"
+#include "bsp_driver_sd.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Block Size in Bytes */
+#define BLOCK_SIZE 512
+
+/* Private variables ---------------------------------------------------------*/
+/* Disk status */
+static volatile DSTATUS Stat = STA_NOINIT;
+
+/* Private function prototypes -----------------------------------------------*/
+DSTATUS SD_initialize (BYTE);
+DSTATUS SD_status (BYTE);
+DRESULT SD_read (BYTE, BYTE*, DWORD, UINT);
+#if _USE_WRITE == 1
+ DRESULT SD_write (BYTE, const BYTE*, DWORD, UINT);
+#endif /* _USE_WRITE == 1 */
+#if _USE_IOCTL == 1
+ DRESULT SD_ioctl (BYTE, BYTE, void*);
+#endif /* _USE_IOCTL == 1 */
+
+const Diskio_drvTypeDef SD_Driver =
+{
+ SD_initialize,
+ SD_status,
+ SD_read,
+#if _USE_WRITE == 1
+ SD_write,
+#endif /* _USE_WRITE == 1 */
+
+#if _USE_IOCTL == 1
+ SD_ioctl,
+#endif /* _USE_IOCTL == 1 */
+};
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief Initializes a Drive
+ * @param lun : not used
+ * @retval DSTATUS: Operation status
+ */
+DSTATUS SD_initialize(BYTE lun)
+{
+ Stat = STA_NOINIT;
+
+ /* Configure the uSD device */
+ if(BSP_SD_Init() == MSD_OK)
+ {
+ Stat &= ~STA_NOINIT;
+ }
+
+ return Stat;
+}
+
+/**
+ * @brief Gets Disk Status
+ * @param lun : not used
+ * @retval DSTATUS: Operation status
+ */
+DSTATUS SD_status(BYTE lun)
+{
+ Stat = STA_NOINIT;
+
+ if(BSP_SD_GetStatus() == MSD_OK)
+ {
+ Stat &= ~STA_NOINIT;
+ }
+
+ return Stat;
+}
+
+/**
+ * @brief Reads Sector(s)
+ * @param lun : not used
+ * @param *buff: Data buffer to store read data
+ * @param sector: Sector address (LBA)
+ * @param count: Number of sectors to read (1..128)
+ * @retval DRESULT: Operation result
+ */
+DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
+{
+ DRESULT res = RES_OK;
+
+ if(BSP_SD_ReadBlocks((uint32_t*)buff,
+ (uint64_t) (sector * BLOCK_SIZE),
+ BLOCK_SIZE,
+ count) != MSD_OK)
+ {
+ res = RES_ERROR;
+ }
+
+ return res;
+}
+
+/**
+ * @brief Writes Sector(s)
+ * @param lun : not used
+ * @param *buff: Data to be written
+ * @param sector: Sector address (LBA)
+ * @param count: Number of sectors to write (1..128)
+ * @retval DRESULT: Operation result
+ */
+#if _USE_WRITE == 1
+DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
+{
+ DRESULT res = RES_OK;
+
+ if(BSP_SD_WriteBlocks((uint32_t*)buff,
+ (uint64_t)(sector * BLOCK_SIZE),
+ BLOCK_SIZE, count) != MSD_OK)
+ {
+ res = RES_ERROR;
+ }
+
+ return res;
+}
+#endif /* _USE_WRITE == 1 */
+
+/**
+ * @brief I/O control operation
+ * @param lun : not used
+ * @param cmd: Control code
+ * @param *buff: Buffer to send/receive control data
+ * @retval DRESULT: Operation result
+ */
+#if _USE_IOCTL == 1
+DRESULT SD_ioctl(BYTE lun, BYTE cmd, void *buff)
+{
+ DRESULT res = RES_ERROR;
+ SD_CardInfo CardInfo;
+
+ if (Stat & STA_NOINIT) return RES_NOTRDY;
+
+ switch (cmd)
+ {
+ /* Make sure that no pending write process */
+ case CTRL_SYNC :
+ res = RES_OK;
+ break;
+
+ /* Get number of sectors on the disk (DWORD) */
+ case GET_SECTOR_COUNT :
+ BSP_SD_GetCardInfo(&CardInfo);
+ *(DWORD*)buff = CardInfo.CardCapacity / BLOCK_SIZE;
+ res = RES_OK;
+ break;
+
+ /* Get R/W sector size (WORD) */
+ case GET_SECTOR_SIZE :
+ *(WORD*)buff = BLOCK_SIZE;
+ res = RES_OK;
+ break;
+
+ /* Get erase block size in unit of sector (DWORD) */
+ case GET_BLOCK_SIZE :
+ *(DWORD*)buff = BLOCK_SIZE;
+ break;
+
+ default:
+ res = RES_PARERR;
+ }
+
+ return res;
+}
+#endif /* _USE_IOCTL == 1 */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/Src/stm32f1xx_hal_msp.c b/Src/stm32f1xx_hal_msp.c
index 12a570d..cab07c8 100644
--- a/Src/stm32f1xx_hal_msp.c
+++ b/Src/stm32f1xx_hal_msp.c
@@ -79,6 +79,7 @@ void HAL_MspInit(void)
/* USER CODE END MspInit 1 */
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
@@ -129,11 +130,89 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
/* USER CODE END I2C1_MspDeInit 1 */
}
+#endif
-void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
+#if defined(STM32F103xE) && defined(CZMINI)
+void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
+{
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+ if(hsd->Instance==SDIO)
+ {
+ /* USER CODE BEGIN SDIO_MspInit 0 */
+
+ /* USER CODE END SDIO_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SDIO_CLK_ENABLE();
+
+ /**SDIO GPIO Configuration
+ PC8 ------> SDIO_D0
+ PC9 ------> SDIO_D1
+ PC10 ------> SDIO_D2
+ PC11 ------> SDIO_D3
+ PC12 ------> SDIO_CK
+ PD2 ------> SDIO_CMD
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_12;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_2;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ /* Peripheral interrupt init */
+ HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0);
+ HAL_NVIC_EnableIRQ(SDIO_IRQn);
+ /* USER CODE BEGIN SDIO_MspInit 1 */
+
+ /* USER CODE END SDIO_MspInit 1 */
+ }
+
+}
+
+void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
{
+ if(hsd->Instance==SDIO)
+ {
+ /* USER CODE BEGIN SDIO_MspDeInit 0 */
+
+ /* USER CODE END SDIO_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SDIO_CLK_DISABLE();
+
+ /**SDIO GPIO Configuration
+ PC8 ------> SDIO_D0
+ PC9 ------> SDIO_D1
+ PC10 ------> SDIO_D2
+ PC11 ------> SDIO_D3
+ PC12 ------> SDIO_CK
+ PD2 ------> SDIO_CMD
+ */
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_12);
+
+ HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
+
+ /* Peripheral interrupt DeInit*/
+ HAL_NVIC_DisableIRQ(SDIO_IRQn);
+
+ }
+ /* USER CODE BEGIN SDIO_MspDeInit 1 */
+
+ /* USER CODE END SDIO_MspDeInit 1 */
+
+}
+#endif
+
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
+{
GPIO_InitTypeDef GPIO_InitStruct;
+#if defined(STM32F107xC) && defined(MKS_TFT)
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
@@ -190,12 +269,40 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
/* USER CODE END SPI3_MspInit 1 */
}
+#elif defined(STM32F103xE) && defined(CZMINI)
+ if(hspi->Instance==SPI2)
+ {
+ /* USER CODE BEGIN SPI2_MspInit 0 */
+
+ /* USER CODE END SPI2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SPI2_CLK_ENABLE();
+
+ /**SPI2 GPIO Configuration
+ PB13 ------> SPI2_SCK
+ PB14 ------> SPI2_MISO
+ PB15 ------> SPI2_MOSI
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+ GPIO_InitStruct.Pin = GPIO_PIN_14;
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN SPI2_MspInit 1 */
+
+ /* USER CODE END SPI2_MspInit 1 */
+ }
+#endif
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspDeInit 0 */
@@ -234,7 +341,27 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
/* USER CODE END SPI3_MspDeInit 1 */
}
+#elif defined(STM32F103xE) && defined(CZMINI)
+ if(hspi->Instance==SPI2)
+ {
+ /* USER CODE BEGIN SPI2_MspDeInit 0 */
+
+ /* USER CODE END SPI2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SPI2_CLK_DISABLE();
+
+ /**SPI2 GPIO Configuration
+ PB13 ------> SPI2_SCK
+ PB14 ------> SPI2_MISO
+ PB15 ------> SPI2_MOSI
+ */
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
+ }
+ /* USER CODE BEGIN SPI2_MspDeInit 1 */
+
+ /* USER CODE END SPI2_MspDeInit 1 */
+#endif
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
@@ -290,6 +417,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
/* USER CODE END USART2_MspInit 1 */
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
else if(huart->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspInit 0 */
@@ -322,7 +450,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
/* USER CODE END USART3_MspInit 1 */
}
-
+#endif
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
@@ -352,6 +480,7 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
/* USER CODE END USART2_MspDeInit 1 */
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
else if(huart->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspDeInit 0 */
@@ -373,9 +502,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
/* USER CODE END USART3_MspDeInit 1 */
}
-
+#endif
}
+#if defined(STM32F107xC) && defined(MKS_TFT)
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
@@ -441,10 +571,132 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
}
}
+#endif
+
+#if defined(STM32F103xE) && defined(CZMINI)
+static uint32_t FSMC_Initialized = 0;
+
+static void HAL_FSMC_MspInit(void){
+ /* USER CODE BEGIN FSMC_MspInit 0 */
+
+ /* USER CODE END FSMC_MspInit 0 */
+ GPIO_InitTypeDef GPIO_InitStruct;
+ if (FSMC_Initialized) {
+ return;
+ }
+ FSMC_Initialized = 1;
+ /* Peripheral clock enable */
+ __HAL_RCC_FSMC_CLK_ENABLE();
+
+ /** FSMC GPIO Configuration
+ PE7 ------> FSMC_D4
+ PE8 ------> FSMC_D5
+ PE9 ------> FSMC_D6
+ PE10 ------> FSMC_D7
+ PE11 ------> FSMC_D8
+ PE12 ------> FSMC_D9
+ PE13 ------> FSMC_D10
+ PE14 ------> FSMC_D11
+ PE15 ------> FSMC_D12
+ PD8 ------> FSMC_D13
+ PD9 ------> FSMC_D14
+ PD10 ------> FSMC_D15
+ PD13 ------> FSMC_A18
+ PD14 ------> FSMC_D0
+ PD15 ------> FSMC_D1
+ PD0 ------> FSMC_D2
+ PD1 ------> FSMC_D3
+ PD4 ------> FSMC_NOE
+ PD5 ------> FSMC_NWE
+ PD7 ------> FSMC_NE1
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
+ |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
+ |GPIO_PIN_15;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_13
+ |GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
+ |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN FSMC_MspInit 1 */
+
+ /* USER CODE END FSMC_MspInit 1 */
+}
+
+void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram){
+ /* USER CODE BEGIN SRAM_MspInit 0 */
+
+ /* USER CODE END SRAM_MspInit 0 */
+ HAL_FSMC_MspInit();
+ /* USER CODE BEGIN SRAM_MspInit 1 */
+
+ /* USER CODE END SRAM_MspInit 1 */
+}
+
+static uint32_t FSMC_DeInitialized = 0;
-/* USER CODE BEGIN 1 */
+static void HAL_FSMC_MspDeInit(void){
+ /* USER CODE BEGIN FSMC_MspDeInit 0 */
-/* USER CODE END 1 */
+ /* USER CODE END FSMC_MspDeInit 0 */
+ if (FSMC_DeInitialized) {
+ return;
+ }
+ FSMC_DeInitialized = 1;
+ /* Peripheral clock enable */
+ __HAL_RCC_FSMC_CLK_DISABLE();
+
+ /** FSMC GPIO Configuration
+ PE7 ------> FSMC_D4
+ PE8 ------> FSMC_D5
+ PE9 ------> FSMC_D6
+ PE10 ------> FSMC_D7
+ PE11 ------> FSMC_D8
+ PE12 ------> FSMC_D9
+ PE13 ------> FSMC_D10
+ PE14 ------> FSMC_D11
+ PE15 ------> FSMC_D12
+ PD8 ------> FSMC_D13
+ PD9 ------> FSMC_D14
+ PD10 ------> FSMC_D15
+ PD13 ------> FSMC_A18
+ PD14 ------> FSMC_D0
+ PD15 ------> FSMC_D1
+ PD0 ------> FSMC_D2
+ PD1 ------> FSMC_D3
+ PD4 ------> FSMC_NOE
+ PD5 ------> FSMC_NWE
+ PD7 ------> FSMC_NE1
+ */
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
+ |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
+ |GPIO_PIN_15);
+
+ HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_13
+ |GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
+ |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7);
+
+ /* USER CODE BEGIN FSMC_MspDeInit 1 */
+
+ /* USER CODE END FSMC_MspDeInit 1 */
+}
+
+void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram){
+ /* USER CODE BEGIN SRAM_MspDeInit 0 */
+
+ /* USER CODE END SRAM_MspDeInit 0 */
+ HAL_FSMC_MspDeInit();
+ /* USER CODE BEGIN SRAM_MspDeInit 1 */
+
+ /* USER CODE END SRAM_MspDeInit 1 */
+}
+#endif
/**
* @}
diff --git a/Src/stm32f1xx_it.c b/Src/stm32f1xx_it.c
index f911eda..3ac5bd9 100644
--- a/Src/stm32f1xx_it.c
+++ b/Src/stm32f1xx_it.c
@@ -41,12 +41,18 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
+#if defined(STM32F107xC) && defined(MKS_TFT)
extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
+extern TIM_HandleTypeDef htim2;
+extern UART_HandleTypeDef huart3;
+#elif defined(STM32F103xE) && defined(CZMINI)
+extern SD_HandleTypeDef hsd;
+#endif
+
extern DMA_HandleTypeDef hdma_usart2_rx;
extern TIM_HandleTypeDef htim7;
-extern TIM_HandleTypeDef htim2;
extern UART_HandleTypeDef huart2;
-extern UART_HandleTypeDef huart3;
+
/******************************************************************************/
/* Cortex-M3 Processor Interruption and Exception Handlers */
@@ -162,7 +168,7 @@ void SysTick_Handler(void)
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
/**
* @brief This function handles EXTI line0 interrupt.
*/
@@ -190,7 +196,7 @@ void EXTI1_IRQHandler(void)
/* USER CODE END EXTI1_IRQn 1 */
}
-
+#endif
/**
* @brief This function handles DMA1 channel6 global interrupt.
*/
@@ -213,7 +219,6 @@ void EXTI9_5_IRQHandler(void)
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
/* USER CODE END EXTI9_5_IRQn 0 */
- HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
@@ -247,7 +252,7 @@ void USART2_IRQHandler(void)
/* USER CODE END USART2_IRQn 1 */
}
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
/**
* @brief This function handles USART3 global interrupt.
*/
@@ -261,7 +266,7 @@ void USART3_IRQHandler(void)
/* USER CODE END USART3_IRQn 1 */
}
-
+#endif
/**
* @brief This function handles TIM7 global interrupt.
*/
@@ -279,7 +284,7 @@ void TIM7_IRQHandler(void)
/**
* @brief This function handles TIM2 global interrupt.
*/
-
+#if defined(STM32F107xC) && defined(MKS_TFT)
void TIM2_IRQHandler(void)
{
/* USER CODE BEGIN TIM2_IRQn 0 */
@@ -304,7 +309,22 @@ void OTG_FS_IRQHandler(void)
/* USER CODE END OTG_FS_IRQn 1 */
}
+#elif defined(STM32F103xE) && defined(CZMINI)
+/**
+* @brief This function handles SDIO global interrupt.
+*/
+void SDIO_IRQHandler(void)
+{
+ /* USER CODE BEGIN SDIO_IRQn 0 */
+
+ /* USER CODE END SDIO_IRQn 0 */
+ HAL_SD_IRQHandler(&hsd);
+ /* USER CODE BEGIN SDIO_IRQn 1 */
+
+ /* USER CODE END SDIO_IRQn 1 */
+}
+#endif
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */