1 /*! 2 * @file apm32f4xx_sdio.h 3 * 4 * @brief This file contains all the functions prototypes for the SDIO firmware 5 * library. 6 * 7 * @version V1.0.2 8 * 9 * @date 2022-06-23 10 * 11 * @attention 12 * 13 * Copyright (C) 2021-2022 Geehy Semiconductor 14 * 15 * You may not use this file except in compliance with the 16 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE). 17 * 18 * The program is only for reference, which is distributed in the hope 19 * that it will be usefull and instructional for customers to develop 20 * their software. Unless required by applicable law or agreed to in 21 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT 22 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied. 23 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions 24 * and limitations under the License. 25 */ 26 27 /* Define to prevent recursive inclusion */ 28 #ifndef __APM32F4XX_SDIO_H 29 #define __APM32F4XX_SDIO_H 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 /* Includes */ 36 #include "apm32f4xx.h" 37 38 /** @addtogroup APM32F4xx_StdPeriphDriver 39 @{ 40 */ 41 42 /** @addtogroup SDIO_Driver 43 @{ 44 */ 45 46 /** @defgroup SDIO_Enumerations 47 @{ 48 */ 49 50 /** 51 * @brief SDIO clock edge 52 */ 53 typedef enum 54 { 55 SDIO_CLOCK_EDGE_RISING, /*!< Select rising edge of SDIOCLK to generate SDIO_CLK */ 56 SDIO_CLOCK_EDGE_FALLING /*!< Select falling edge of SDIOCLK to generate SDIO_CLK */ 57 } SDIO_CLOCK_EDGE_T; 58 59 /** 60 * @brief SDIO clock bypass 61 */ 62 typedef enum 63 { 64 SDIO_CLOCK_BYPASS_DISABLE, /*!< Disable divider bypass */ 65 SDIO_CLOCK_BYPASS_ENABLE /*!< Enable divider bypass */ 66 } SDIO_CLOCK_BYPASS_T; 67 68 /** 69 * @brief SDIO clock power save 70 */ 71 typedef enum 72 { 73 SDIO_CLOCK_POWER_SAVE_DISABLE, /*!< Disable power saving mode */ 74 SDIO_CLOCK_POWER_SAVE_ENABLE /*!< Enable power saving mode */ 75 } SDIO_CLOCK_POWER_SAVE_T; 76 77 /** 78 * @brief SDIO bus wide 79 */ 80 typedef enum 81 { 82 SDIO_BUS_WIDE_1B, /*!< 1-bit wide bus mode */ 83 SDIO_BUS_WIDE_4B, /*!< 4-bit wide bus mode */ 84 SDIO_BUS_WIDE_8B /*!< 8-bit wide bus mode */ 85 } SDIO_BUS_WIDE_T; 86 87 /** 88 * @brief SDIO hardware flow control 89 */ 90 typedef enum 91 { 92 SDIO_HARDWARE_FLOW_CONTROL_DISABLE, /*!< Disable hardware flow control */ 93 SDIO_HARDWARE_FLOW_CONTROL_ENABLE /*!< Enable hardware flow control */ 94 } SDIO_HARDWARE_FLOW_CONTROL_T; 95 96 /** 97 * @brief SDIO power state 98 */ 99 typedef enum 100 { 101 SDIO_POWER_STATE_OFF = 0x00, /*!< Power off */ 102 SDIO_POWER_STATE_ON = 0x03 /*!< Power on */ 103 } SDIO_POWER_STATE_T; 104 105 /** 106 * @brief SDIO response 107 */ 108 typedef enum 109 { 110 SDIO_RESPONSE_NO = (uint8_t)0x00, /*!< No response */ 111 SDIO_RESPONSE_SHORT = (uint8_t)0x01, /*!< Short response */ 112 SDIO_RESPONSE_LONG = (uint8_t)0x03 /*!< Long response */ 113 } SDIO_RESPONSE_T; 114 115 /** 116 * @brief SDIO wait interrupt state 117 */ 118 typedef enum 119 { 120 SDIO_WAIT_NO = (uint8_t)0x00, /*!< No wait */ 121 SDIO_WAIT_INT = (uint8_t)0x01, /*!< Wait interrupt request */ 122 SDIO_WAIT_PEND = (uint8_t)0x02 /*!< Wait CmdPend */ 123 } SDIO_WAIT_T; 124 125 /** 126 * @brief SDIO CPSM state 127 */ 128 typedef enum 129 { 130 SDIO_CPSM_DISABLE, /*!< Disable CPSM */ 131 SDIO_CPSM_ENABLE /*!< Enable CPSM */ 132 } SDIO_CPSM_T; 133 134 /** 135 * @brief SDIO response registers 136 */ 137 typedef enum 138 { 139 SDIO_RES1 = ((uint8_t)0x00), /*!< Response Register 1 */ 140 SDIO_RES2 = ((uint8_t)0x04), /*!< Response Register 2 */ 141 SDIO_RES3 = ((uint8_t)0x08), /*!< Response Register 3 */ 142 SDIO_RES4 = ((uint8_t)0x0C) /*!< Response Register 4 */ 143 } SDIO_RES_T; 144 145 /** 146 * @brief SDIO data block size 147 */ 148 typedef enum 149 { 150 SDIO_DATA_BLOCKSIZE_1B, /*!< block size = 1 byte */ 151 SDIO_DATA_BLOCKSIZE_2B, /*!< block size = 2 bytes */ 152 SDIO_DATA_BLOCKSIZE_4B, /*!< block size = 4 bytes */ 153 SDIO_DATA_BLOCKSIZE_8B, /*!< block size = 8 bytes */ 154 SDIO_DATA_BLOCKSIZE_16B, /*!< block size = 16 bytes */ 155 SDIO_DATA_BLOCKSIZE_32B, /*!< block size = 32 bytes */ 156 SDIO_DATA_BLOCKSIZE_64B, /*!< block size = 64 bytes */ 157 SDIO_DATA_BLOCKSIZE_128B, /*!< block size = 128 bytes */ 158 SDIO_DATA_BLOCKSIZE_256B, /*!< block size = 256 bytes */ 159 SDIO_DATA_BLOCKSIZE_512B, /*!< block size = 512 bytes */ 160 SDIO_DATA_BLOCKSIZE_1024B, /*!< block size = 1024 bytes */ 161 SDIO_DATA_BLOCKSIZE_2048B, /*!< block size = 2048 bytes */ 162 SDIO_DATA_BLOCKSIZE_4096B, /*!< block size = 4096 bytes */ 163 SDIO_DATA_BLOCKSIZE_8192B, /*!< block size = 8192 bytes */ 164 SDIO_DATA_BLOCKSIZE_16384B /*!< block size = 16384 bytes */ 165 } SDIO_DATA_BLOCKSIZE_T; 166 167 /** 168 * @brief SDIO transfer direction 169 */ 170 typedef enum 171 { 172 SDIO_TRANSFER_DIR_TO_CARD, /*!< Controller to SD card */ 173 SDIO_TRANSFER_DIR_TO_SDIO /*!< SD card to controller */ 174 } SDIO_TRANSFER_DIR_T; 175 176 /** 177 * @brief SDIO transfer type 178 */ 179 typedef enum 180 { 181 SDIO_TRANSFER_MODE_BLOCK, /*!< Block data mode */ 182 SDIO_TRANSFER_MODE_STREAM /*!< Stream data mode */ 183 } SDIO_TRANSFER_MODE_T; 184 185 /** 186 * @brief SDIO DPSM state 187 */ 188 typedef enum 189 { 190 SDIO_DPSM_DISABLE, /*!< Disable DPSM */ 191 SDIO_DPSM_ENABLE /*!< Enable DPSM */ 192 } SDIO_DPSM_T; 193 194 /** 195 * @brief SDIO flag 196 */ 197 typedef enum 198 { 199 SDIO_FLAG_COMRESP = ((uint32_t)0x00000001), /*!< Command response received (CRC check failed) flag */ 200 SDIO_FLAG_DBDR = ((uint32_t)0x00000002), /*!< Data block sent/received (CRC check failed) flag */ 201 SDIO_FLAG_CMDRESTO = ((uint32_t)0x00000004), /*!< Command response timeout flag */ 202 SDIO_FLAG_DATATO = ((uint32_t)0x00000008), /*!< Data timeout flag */ 203 SDIO_FLAG_TXUDRER = ((uint32_t)0x00000010), /*!< Transmit FIFO underrun error flag */ 204 SDIO_FLAG_RXOVRER = ((uint32_t)0x00000020), /*!< Received FIFO overrun error flag */ 205 SDIO_FLAG_CMDRES = ((uint32_t)0x00000040), /*!< Command response received (CRC check passed) flag */ 206 SDIO_FLAG_CMDSENT = ((uint32_t)0x00000080), /*!< Command sent (no response required) flag */ 207 SDIO_FLAG_DATAEND = ((uint32_t)0x00000100), /*!< Data end (data counter is zero) flag */ 208 SDIO_FLAG_SBE = ((uint32_t)0x00000200), /*!< Start bit not detected on all data signals in wide bus mode flag */ 209 SDIO_FLAG_DBCP = ((uint32_t)0x00000400), /*!< Data block sent/received (CRC check passed) flag */ 210 SDIO_FLAG_CMDACT = ((uint32_t)0x00000800), /*!< Command transfer in progress flag */ 211 SDIO_FLAG_TXACT = ((uint32_t)0x00001000), /*!< Data transmit in progress flag */ 212 SDIO_FLAG_RXACT = ((uint32_t)0x00002000), /*!< Data receive in progress flag */ 213 SDIO_FLAG_TXFHF = ((uint32_t)0x00004000), /*!< Transmit FIFO Half Empty flag */ 214 SDIO_FLAG_RXFHF = ((uint32_t)0x00008000), /*!< Receive FIFO Half Full flag */ 215 SDIO_FLAG_TXFF = ((uint32_t)0x00010000), /*!< Transmit FIFO full flag */ 216 SDIO_FLAG_RXFF = ((uint32_t)0x00020000), /*!< Receive FIFO full flag */ 217 SDIO_FLAG_TXFE = ((uint32_t)0x00040000), /*!< Transmit FIFO empty flag */ 218 SDIO_FLAG_RXFE = ((uint32_t)0x00080000), /*!< Receive FIFO empty flag */ 219 SDIO_FLAG_TXDA = ((uint32_t)0x00100000), /*!< Data available in transmit FIFO flag */ 220 SDIO_FLAG_RXDA = ((uint32_t)0x00200000), /*!< Data available in receive FIFO flag */ 221 SDIO_FLAG_SDIOINT = ((uint32_t)0x00400000), /*!< SD I/O interrupt received flag */ 222 SDIO_FLAG_ATAEND = ((uint32_t)0x00800000) /*!< CE-ATA command completion signal received for CMD61 flag */ 223 } SDIO_FLAG_T; 224 225 /** 226 * @brief SDIO interrupt sources 227 */ 228 typedef enum 229 { 230 SDIO_INT_COMRESP = ((uint32_t)0x00000001), /*!< Command response received (CRC check failed) interrupt */ 231 SDIO_INT_DBDR = ((uint32_t)0x00000002), /*!< Data block sent/received (CRC check failed) interrupt */ 232 SDIO_INT_CMDRESTO = ((uint32_t)0x00000004), /*!< Command response timeout interrupt */ 233 SDIO_INT_DATATO = ((uint32_t)0x00000008), /*!< Data timeout interrupt */ 234 SDIO_INT_TXUDRER = ((uint32_t)0x00000010), /*!< Transmit FIFO underrun error interrupt */ 235 SDIO_INT_RXOVRER = ((uint32_t)0x00000020), /*!< Received FIFO overrun error interrupt */ 236 SDIO_INT_CMDRES = ((uint32_t)0x00000040), /*!< Command response received (CRC check passed) interrupt */ 237 SDIO_INT_CMDSENT = ((uint32_t)0x00000080), /*!< Command sent (no response required) interrupt */ 238 SDIO_INT_DATAEND = ((uint32_t)0x00000100), /*!< Data end (data counter, SDIDCOUNT, is zero) interrupt */ 239 SDIO_INT_SBE = ((uint32_t)0x00000200), /*!< Start bit not detected on all data signals in wide bus mode interrupt */ 240 SDIO_INT_DBCP = ((uint32_t)0x00000400), /*!< Data block sent/received (CRC check passed) interrupt */ 241 SDIO_INT_CMDACT = ((uint32_t)0x00000800), /*!< Command transfer in progress interrupt */ 242 SDIO_INT_TXACT = ((uint32_t)0x00001000), /*!< Data transmit in progress interrupt */ 243 SDIO_INT_RXACT = ((uint32_t)0x00002000), /*!< Data receive in progress interrupt */ 244 SDIO_INT_TXFHF = ((uint32_t)0x00004000), /*!< Transmit FIFO Half Empty interrupt */ 245 SDIO_INT_RXFHF = ((uint32_t)0x00008000), /*!< Receive FIFO Half Full interrupt */ 246 SDIO_INT_TXFF = ((uint32_t)0x00010000), /*!< Transmit FIFO full interrupt */ 247 SDIO_INT_RXFF = ((uint32_t)0x00020000), /*!< Receive FIFO full interrupt */ 248 SDIO_INT_TXFE = ((uint32_t)0x00040000), /*!< Transmit FIFO empty interrupt */ 249 SDIO_INT_RXFE = ((uint32_t)0x00080000), /*!< Receive FIFO empty interrupt */ 250 SDIO_INT_TXDA = ((uint32_t)0x00100000), /*!< Data available in transmit FIFO interrupt */ 251 SDIO_INT_RXDA = ((uint32_t)0x00200000), /*!< Data available in receive FIFO interrupt */ 252 SDIO_INT_SDIOINT = ((uint32_t)0x00400000), /*!< SD I/O interrupt received interrupt */ 253 SDIO_INT_ATAEND = ((uint32_t)0x00800000) /*!< CE-ATA command completion signal received for CMD61 interrupt */ 254 } SDIO_INT_T; 255 256 /** 257 * @brief SDIO read wait mode 258 */ 259 typedef enum 260 { 261 SDIO_READ_WAIT_MODE_DATA2, /*!< Read Wait control using SDIO_DATA2 */ 262 SDIO_READ_WAIT_MODE_CLK /*!< Read Wait control by stopping SDIOCLK */ 263 } SDIO_READ_WAIT_MODE_T; 264 265 /**@} end of group SDIO_Enumerations*/ 266 267 /** @addtogroup SDIO_Structure Data Structure 268 @{ 269 */ 270 271 /** 272 * @brief SDIO Config structure definition 273 */ 274 typedef struct 275 { 276 SDIO_CLOCK_EDGE_T clockEdge; /*!< Specifies the clock transition on which the bit capture is made */ 277 SDIO_CLOCK_BYPASS_T clockBypass; /*!< Specifies whether the SDIO Clock divider bypass is enabled or disabled */ 278 SDIO_CLOCK_POWER_SAVE_T clockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or disabled when the bus is idle */ 279 SDIO_BUS_WIDE_T busWide; /*!< Specifies the SDIO bus width */ 280 SDIO_HARDWARE_FLOW_CONTROL_T hardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled */ 281 uint8_t clockDiv; /*!< This parameter can be a value between 0x00 and 0xFF */ 282 } SDIO_Config_T; 283 284 /** 285 * @brief SDIO Command Config structure definition 286 */ 287 typedef struct 288 { 289 uint32_t argument; /*!< Specifies the SDIO command argument which is sentto a card as part of a command message. 290 If a command contains an argument, it must be loaded into this register before writing 291 the command to the command register */ 292 uint32_t cmdIndex; /*!< It must be lower than 0x40 */ 293 SDIO_RESPONSE_T response; /*!< SDIO response */ 294 SDIO_WAIT_T wait; /*!< Specifies whether SDIO wait for interrupt request */ 295 SDIO_CPSM_T CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM) */ 296 } SDIO_CmdConfig_T; 297 298 /** 299 * @brief SDIO Data Config 300 */ 301 typedef struct 302 { 303 uint32_t dataTimeOut; /*!< SDIO data timeout period */ 304 uint32_t dataLength; /*!< SDIO data length */ 305 SDIO_DATA_BLOCKSIZE_T dataBlockSize; /*!< SDIO data block size */ 306 SDIO_TRANSFER_DIR_T transferDir; /*!< SDIO transfer direction */ 307 SDIO_TRANSFER_MODE_T transferMode; /*!< SDIO transfer type */ 308 SDIO_DPSM_T DPSM; /*!< Specifies whether SDIO Data path state machine(DPSM) */ 309 } SDIO_DataConfig_T; 310 311 /**@} end of group SDIO_Structure*/ 312 313 /** @defgroup SDIO_Functions 314 @{ 315 */ 316 317 /* SDIO reset and configuration */ 318 void SDIO_Reset(void); 319 void SDIO_Config(SDIO_Config_T* sdioConfig); 320 void SDIO_ConfigStructInit(SDIO_Config_T* sdioConfig); 321 void SDIO_EnableClock(void); 322 void SDIO_DisableClock(void); 323 void SDIO_ConfigPowerState(SDIO_POWER_STATE_T powerState); 324 uint32_t SDIO_ReadPowerState(void); 325 326 /* DMA */ 327 void SDIO_EnableDMA(void); 328 void SDIO_DisableDMA(void); 329 330 /* Command */ 331 void SDIO_TxCommand(SDIO_CmdConfig_T *cmdConfig); 332 void SDIO_TxCommandStructInit(SDIO_CmdConfig_T* cmdconfig); 333 uint8_t SDIO_ReadCommandResponse(void); 334 uint32_t SDIO_ReadResponse(SDIO_RES_T res); 335 336 /* SDIO data configuration */ 337 void SDIO_ConfigData(SDIO_DataConfig_T* dataConfig); 338 void SDIO_ConfigDataStructInit(SDIO_DataConfig_T* dataConfig); 339 uint32_t SDIO_ReadDataCounter(void); 340 void SDIO_WriteData(uint32_t data); 341 uint32_t SDIO_ReadData(void); 342 uint32_t SDIO_ReadFIFOCount(void); 343 344 /* SDIO mode */ 345 void SDIO_EnableStartReadWait(void); 346 void SDIO_DisableStartReadWait(void); 347 void SDIO_EnableStopReadWait(void); 348 void SDIO_DisableStopReadWait(void); 349 void SDIO_ConfigSDIOReadWaitMode(SDIO_READ_WAIT_MODE_T readWaitMode); 350 void SDIO_EnableSDIO(void); 351 void SDIO_DisableSDIO(void); 352 void SDIO_EnableTxSDIOSuspend(void); 353 void SDIO_DisableTxSDIOSuspend(void); 354 void SDIO_EnableCommandCompletion(void); 355 void SDIO_DisableCommandCompletion(void); 356 void SDIO_EnableCEATAInterrupt(void); 357 void SDIO_DisableCEATAInterrupt(void); 358 void SDIO_EnableTxCEATA(void); 359 void SDIO_DisableTxCEATA(void); 360 361 /* Interrupt and flags */ 362 void SDIO_EnableInterrupt(uint32_t interrupt); 363 void SDIO_DisableInterrupt(uint32_t interrupt); 364 uint8_t SDIO_ReadStatusFlag(SDIO_FLAG_T flag); 365 void SDIO_ClearStatusFlag(uint32_t flag); 366 uint8_t SDIO_ReadIntFlag(SDIO_INT_T flag); 367 void SDIO_ClearIntFlag(uint32_t flag); 368 369 #ifdef __cplusplus 370 } 371 #endif 372 373 #endif /* __APM32F4XX_SDIO_H */ 374 375 /**@} end of group SDIO_Enumerations */ 376 /**@} end of group SDIO_Driver */ 377 /**@} end of group APM32F4xx_StdPeriphDriver */ 378