2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
22 * Original author: Alain (https://github.com/aroyer-qc)
23 * Modified for BF source: Chris Hockuba (https://github.com/conkerkh)
26 /* Include(s) -------------------------------------------------------------------------------------------------------*/
33 #ifdef USE_SDCARD_SDIO
35 #include "sdmmc_sdio.h"
36 #include "stm32h7xx.h"
38 #include "drivers/sdio.h"
39 #include "drivers/io.h"
40 #include "drivers/io_impl.h"
41 #include "drivers/nvic.h"
42 #include "drivers/time.h"
43 #include "drivers/rcc.h"
44 #include "drivers/dma.h"
46 #include "build/debug.h"
48 typedef struct SD_Handle_s
50 uint32_t CSD
[4]; // SD card specific data table
51 uint32_t CID
[4]; // SD card identification number table
52 volatile uint32_t RXCplt
; // SD RX Complete is equal 0 when no transfer
53 volatile uint32_t TXCplt
; // SD TX Complete is equal 0 when no transfer
56 SD_HandleTypeDef hsd1
;
58 SD_CardInfo_t SD_CardInfo
;
59 SD_CardType_t SD_CardType
;
61 static SD_Handle_t SD_Handle
;
63 typedef struct sdioPin_s
{
73 #define SDIO_PIN_CMD 5
74 #define SDIO_PIN_COUNT 6
76 #define SDIO_MAX_PINDEFS 2
78 typedef struct sdioHardware_s
{
79 SDMMC_TypeDef
*instance
;
81 sdioPin_t sdioPinCK
[SDIO_MAX_PINDEFS
];
82 sdioPin_t sdioPinCMD
[SDIO_MAX_PINDEFS
];
83 sdioPin_t sdioPinD0
[SDIO_MAX_PINDEFS
];
84 sdioPin_t sdioPinD1
[SDIO_MAX_PINDEFS
];
85 sdioPin_t sdioPinD2
[SDIO_MAX_PINDEFS
];
86 sdioPin_t sdioPinD3
[SDIO_MAX_PINDEFS
];
89 // Possible pin assignments
91 #define PINDEF(device, pin, afnum) { DEFIO_TAG_E(pin), GPIO_AF ## afnum ## _SDMMC ## device }
93 static const sdioHardware_t sdioPinHardware
[SDIODEV_COUNT
] = {
97 .sdioPinCK
= { PINDEF(1, PC12
, 12) },
98 .sdioPinCMD
= { PINDEF(1, PD2
, 12) },
99 .sdioPinD0
= { PINDEF(1, PC8
, 12) },
100 .sdioPinD1
= { PINDEF(1, PC9
, 12) },
101 .sdioPinD2
= { PINDEF(1, PC10
, 12) },
102 .sdioPinD3
= { PINDEF(1, PC11
, 12) },
107 .sdioPinCK
= { PINDEF(2, PC1
, 9), PINDEF(2, PD6
, 11) },
108 .sdioPinCMD
= { PINDEF(2, PD7
, 11), PINDEF(2, PA0
, 9) },
109 .sdioPinD0
= { PINDEF(2, PB14
, 9) },
110 .sdioPinD1
= { PINDEF(2, PB15
, 9) },
111 .sdioPinD2
= { PINDEF(2, PB3
, 9) },
112 .sdioPinD3
= { PINDEF(2, PB4
, 9) },
118 // Active configuration
119 static const sdioHardware_t
*sdioHardware
;
120 static sdioPin_t sdioPin
[SDIO_PIN_COUNT
];
122 void sdioPinConfigure(void)
124 if (SDCARD_SDIO_DEVICE
== SDIOINVALID
) {
128 sdioHardware
= &sdioPinHardware
[SDCARD_SDIO_DEVICE
];
130 sdioPin
[SDIO_PIN_CK
] = sdioHardware
[SDCARD_SDIO_DEVICE
].sdioPinCK
[0];
131 sdioPin
[SDIO_PIN_CMD
] = sdioHardware
[SDCARD_SDIO_DEVICE
].sdioPinCMD
[0];
132 sdioPin
[SDIO_PIN_D0
] = sdioHardware
[SDCARD_SDIO_DEVICE
].sdioPinD0
[0];
134 #ifdef SDCARD_SDIO_4BIT
135 sdioPin
[SDIO_PIN_D1
] = sdioHardware
[SDCARD_SDIO_DEVICE
].sdioPinD1
[0];
136 sdioPin
[SDIO_PIN_D2
] = sdioHardware
[SDCARD_SDIO_DEVICE
].sdioPinD2
[0];
137 sdioPin
[SDIO_PIN_D3
] = sdioHardware
[SDCARD_SDIO_DEVICE
].sdioPinD3
[0];
141 #define IOCFG_SDMMC IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_NOPULL)
143 void HAL_SD_MspInit(SD_HandleTypeDef
* hsd
)
151 if (sdioHardware
->instance
== SDMMC1
) {
152 __HAL_RCC_SDMMC1_CLK_DISABLE();
153 __HAL_RCC_SDMMC1_FORCE_RESET();
154 __HAL_RCC_SDMMC1_RELEASE_RESET();
155 __HAL_RCC_SDMMC1_CLK_ENABLE();
156 } else if (sdioHardware
->instance
== SDMMC2
) {
157 __HAL_RCC_SDMMC2_CLK_DISABLE();
158 __HAL_RCC_SDMMC2_FORCE_RESET();
159 __HAL_RCC_SDMMC2_RELEASE_RESET();
160 __HAL_RCC_SDMMC2_CLK_ENABLE();
163 const IO_t clk
= IOGetByTag(sdioPin
[SDIO_PIN_CK
].pin
);
164 const IO_t cmd
= IOGetByTag(sdioPin
[SDIO_PIN_CMD
].pin
);
165 const IO_t d0
= IOGetByTag(sdioPin
[SDIO_PIN_D0
].pin
);
166 const IO_t d1
= IOGetByTag(sdioPin
[SDIO_PIN_D1
].pin
);
167 const IO_t d2
= IOGetByTag(sdioPin
[SDIO_PIN_D2
].pin
);
168 const IO_t d3
= IOGetByTag(sdioPin
[SDIO_PIN_D3
].pin
);
170 IOConfigGPIOAF(clk
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_CK
].af
);
171 IOConfigGPIOAF(cmd
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_CMD
].af
);
172 IOConfigGPIOAF(d0
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_D0
].af
);
174 #ifdef SDCARD_SDIO_4BIT
175 IOConfigGPIOAF(d1
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_D1
].af
);
176 IOConfigGPIOAF(d2
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_D2
].af
);
177 IOConfigGPIOAF(d3
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_D3
].af
);
180 HAL_NVIC_SetPriority(sdioHardware
->irqn
, 0, 0);
181 HAL_NVIC_EnableIRQ(sdioHardware
->irqn
);
184 void SDIO_GPIO_Init(void)
190 const IO_t clk
= IOGetByTag(sdioPin
[SDIO_PIN_CK
].pin
);
191 const IO_t cmd
= IOGetByTag(sdioPin
[SDIO_PIN_CMD
].pin
);
192 const IO_t d0
= IOGetByTag(sdioPin
[SDIO_PIN_D0
].pin
);
193 const IO_t d1
= IOGetByTag(sdioPin
[SDIO_PIN_D1
].pin
);
194 const IO_t d2
= IOGetByTag(sdioPin
[SDIO_PIN_D2
].pin
);
195 const IO_t d3
= IOGetByTag(sdioPin
[SDIO_PIN_D3
].pin
);
197 IOInit(clk
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
198 IOInit(cmd
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
199 IOInit(d0
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
201 #ifdef SDCARD_SDIO_4BIT
202 IOInit(d1
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
203 IOInit(d2
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
204 IOInit(d3
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
208 // Setting all the SDIO pins to high for a short time results in more robust initialisation.
211 IOConfigGPIO(d0
, IOCFG_OUT_PP
);
213 #ifdef SDCARD_SDIO_4BIT
217 IOConfigGPIO(d1
, IOCFG_OUT_PP
);
218 IOConfigGPIO(d2
, IOCFG_OUT_PP
);
219 IOConfigGPIO(d3
, IOCFG_OUT_PP
);
224 IOConfigGPIO(clk
, IOCFG_OUT_PP
);
225 IOConfigGPIO(cmd
, IOCFG_OUT_PP
);
228 bool SD_Initialize_LL(DMA_Stream_TypeDef
*dma
)
234 bool SD_GetState(void)
236 HAL_SD_CardStateTypedef cardState
= HAL_SD_GetCardState(&hsd1
);
238 return (cardState
== HAL_SD_CARD_TRANSFER
);
243 HAL_StatusTypeDef status
;
245 memset(&hsd1
, 0, sizeof(hsd1
));
247 hsd1
.Instance
= sdioHardware
->instance
;
249 hsd1
.Init
.ClockEdge
= SDMMC_CLOCK_EDGE_RISING
;
250 hsd1
.Init
.ClockPowerSave
= SDMMC_CLOCK_POWER_SAVE_ENABLE
;
251 #ifdef SDCARD_SDIO_4BIT
252 hsd1
.Init
.BusWide
= SDMMC_BUS_WIDE_4B
;
254 hsd1
.Init
.BusWide
= SDMMC_BUS_WIDE_1B
; // FIXME untested
256 hsd1
.Init
.HardwareFlowControl
= SDMMC_HARDWARE_FLOW_CONTROL_ENABLE
;
257 hsd1
.Init
.ClockDiv
= 1; // 200Mhz / (2 * 1 ) = 100Mhz, used for "UltraHigh speed SD card" only, see HAL_SD_ConfigWideBusOperation, SDMMC_HSpeed_CLK_DIV, SDMMC_NSpeed_CLK_DIV
259 status
= HAL_SD_Init(&hsd1
); // Will call HAL_SD_MspInit
261 if (status
!= HAL_OK
) {
265 switch(hsd1
.SdCard
.CardType
) {
267 switch (hsd1
.SdCard
.CardVersion
) {
269 SD_CardType
= SD_STD_CAPACITY_V1_1
;
272 SD_CardType
= SD_STD_CAPACITY_V2_0
;
280 SD_CardType
= SD_HIGH_CAPACITY
;
287 // STATIC_ASSERT(sizeof(SD_Handle.CSD) == sizeof(hsd1.CSD), hal-csd-size-error);
288 memcpy(&SD_Handle
.CSD
, &hsd1
.CSD
, sizeof(SD_Handle
.CSD
));
290 // STATIC_ASSERT(sizeof(SD_Handle.CID) == sizeof(hsd1.CID), hal-cid-size-error);
291 memcpy(&SD_Handle
.CID
, &hsd1
.CID
, sizeof(SD_Handle
.CID
));
296 SD_Error_t
SD_GetCardInfo(void)
298 SD_Error_t ErrorState
= SD_OK
;
300 // fill in SD_CardInfo
305 Temp
= (SD_Handle
.CSD
[0] & 0xFF000000) >> 24;
306 SD_CardInfo
.SD_csd
.CSDStruct
= (uint8_t)((Temp
& 0xC0) >> 6);
307 SD_CardInfo
.SD_csd
.SysSpecVersion
= (uint8_t)((Temp
& 0x3C) >> 2);
308 SD_CardInfo
.SD_csd
.Reserved1
= Temp
& 0x03;
311 Temp
= (SD_Handle
.CSD
[0] & 0x00FF0000) >> 16;
312 SD_CardInfo
.SD_csd
.TAAC
= (uint8_t)Temp
;
315 Temp
= (SD_Handle
.CSD
[0] & 0x0000FF00) >> 8;
316 SD_CardInfo
.SD_csd
.NSAC
= (uint8_t)Temp
;
319 Temp
= SD_Handle
.CSD
[0] & 0x000000FF;
320 SD_CardInfo
.SD_csd
.MaxBusClkFrec
= (uint8_t)Temp
;
323 Temp
= (SD_Handle
.CSD
[1] & 0xFF000000) >> 24;
324 SD_CardInfo
.SD_csd
.CardComdClasses
= (uint16_t)(Temp
<< 4);
327 Temp
= (SD_Handle
.CSD
[1] & 0x00FF0000) >> 16;
328 SD_CardInfo
.SD_csd
.CardComdClasses
|= (uint16_t)((Temp
& 0xF0) >> 4);
329 SD_CardInfo
.SD_csd
.RdBlockLen
= (uint8_t)(Temp
& 0x0F);
332 Temp
= (SD_Handle
.CSD
[1] & 0x0000FF00) >> 8;
333 SD_CardInfo
.SD_csd
.PartBlockRead
= (uint8_t)((Temp
& 0x80) >> 7);
334 SD_CardInfo
.SD_csd
.WrBlockMisalign
= (uint8_t)((Temp
& 0x40) >> 6);
335 SD_CardInfo
.SD_csd
.RdBlockMisalign
= (uint8_t)((Temp
& 0x20) >> 5);
336 SD_CardInfo
.SD_csd
.DSRImpl
= (uint8_t)((Temp
& 0x10) >> 4);
337 SD_CardInfo
.SD_csd
.Reserved2
= 0; /*!< Reserved */
339 if((SD_CardType
== SD_STD_CAPACITY_V1_1
) || (SD_CardType
== SD_STD_CAPACITY_V2_0
)) {
340 SD_CardInfo
.SD_csd
.DeviceSize
= (Temp
& 0x03) << 10;
343 Temp
= (uint8_t)(SD_Handle
.CSD
[1] & 0x000000FF);
344 SD_CardInfo
.SD_csd
.DeviceSize
|= (Temp
) << 2;
347 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0xFF000000) >> 24);
348 SD_CardInfo
.SD_csd
.DeviceSize
|= (Temp
& 0xC0) >> 6;
350 SD_CardInfo
.SD_csd
.MaxRdCurrentVDDMin
= (Temp
& 0x38) >> 3;
351 SD_CardInfo
.SD_csd
.MaxRdCurrentVDDMax
= (Temp
& 0x07);
354 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0x00FF0000) >> 16);
355 SD_CardInfo
.SD_csd
.MaxWrCurrentVDDMin
= (Temp
& 0xE0) >> 5;
356 SD_CardInfo
.SD_csd
.MaxWrCurrentVDDMax
= (Temp
& 0x1C) >> 2;
357 SD_CardInfo
.SD_csd
.DeviceSizeMul
= (Temp
& 0x03) << 1;
360 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0x0000FF00) >> 8);
361 SD_CardInfo
.SD_csd
.DeviceSizeMul
|= (Temp
& 0x80) >> 7;
363 SD_CardInfo
.CardCapacity
= (SD_CardInfo
.SD_csd
.DeviceSize
+ 1) ;
364 SD_CardInfo
.CardCapacity
*= (1 << (SD_CardInfo
.SD_csd
.DeviceSizeMul
+ 2));
365 SD_CardInfo
.CardBlockSize
= 1 << (SD_CardInfo
.SD_csd
.RdBlockLen
);
366 SD_CardInfo
.CardCapacity
= SD_CardInfo
.CardCapacity
* SD_CardInfo
.CardBlockSize
/ 512; // In 512 byte blocks
367 } else if(SD_CardType
== SD_HIGH_CAPACITY
) {
369 Temp
= (uint8_t)(SD_Handle
.CSD
[1] & 0x000000FF);
370 SD_CardInfo
.SD_csd
.DeviceSize
= (Temp
& 0x3F) << 16;
373 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0xFF000000) >> 24);
375 SD_CardInfo
.SD_csd
.DeviceSize
|= (Temp
<< 8);
378 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0x00FF0000) >> 16);
380 SD_CardInfo
.SD_csd
.DeviceSize
|= (Temp
);
383 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0x0000FF00) >> 8);
385 SD_CardInfo
.CardCapacity
= ((uint64_t)SD_CardInfo
.SD_csd
.DeviceSize
+ 1) * 1024;
386 SD_CardInfo
.CardBlockSize
= 512;
388 // Not supported card type
389 ErrorState
= SD_ERROR
;
392 SD_CardInfo
.SD_csd
.EraseGrSize
= (Temp
& 0x40) >> 6;
393 SD_CardInfo
.SD_csd
.EraseGrMul
= (Temp
& 0x3F) << 1;
396 Temp
= (uint8_t)(SD_Handle
.CSD
[2] & 0x000000FF);
397 SD_CardInfo
.SD_csd
.EraseGrMul
|= (Temp
& 0x80) >> 7;
398 SD_CardInfo
.SD_csd
.WrProtectGrSize
= (Temp
& 0x7F);
401 Temp
= (uint8_t)((SD_Handle
.CSD
[3] & 0xFF000000) >> 24);
402 SD_CardInfo
.SD_csd
.WrProtectGrEnable
= (Temp
& 0x80) >> 7;
403 SD_CardInfo
.SD_csd
.ManDeflECC
= (Temp
& 0x60) >> 5;
404 SD_CardInfo
.SD_csd
.WrSpeedFact
= (Temp
& 0x1C) >> 2;
405 SD_CardInfo
.SD_csd
.MaxWrBlockLen
= (Temp
& 0x03) << 2;
408 Temp
= (uint8_t)((SD_Handle
.CSD
[3] & 0x00FF0000) >> 16);
409 SD_CardInfo
.SD_csd
.MaxWrBlockLen
|= (Temp
& 0xC0) >> 6;
410 SD_CardInfo
.SD_csd
.WriteBlockPaPartial
= (Temp
& 0x20) >> 5;
411 SD_CardInfo
.SD_csd
.Reserved3
= 0;
412 SD_CardInfo
.SD_csd
.ContentProtectAppli
= (Temp
& 0x01);
415 Temp
= (uint8_t)((SD_Handle
.CSD
[3] & 0x0000FF00) >> 8);
416 SD_CardInfo
.SD_csd
.FileFormatGrouop
= (Temp
& 0x80) >> 7;
417 SD_CardInfo
.SD_csd
.CopyFlag
= (Temp
& 0x40) >> 6;
418 SD_CardInfo
.SD_csd
.PermWrProtect
= (Temp
& 0x20) >> 5;
419 SD_CardInfo
.SD_csd
.TempWrProtect
= (Temp
& 0x10) >> 4;
420 SD_CardInfo
.SD_csd
.FileFormat
= (Temp
& 0x0C) >> 2;
421 SD_CardInfo
.SD_csd
.ECC
= (Temp
& 0x03);
424 Temp
= (uint8_t)(SD_Handle
.CSD
[3] & 0x000000FF);
425 SD_CardInfo
.SD_csd
.CSD_CRC
= (Temp
& 0xFE) >> 1;
426 SD_CardInfo
.SD_csd
.Reserved4
= 1;
429 Temp
= (uint8_t)((SD_Handle
.CID
[0] & 0xFF000000) >> 24);
430 SD_CardInfo
.SD_cid
.ManufacturerID
= Temp
;
433 Temp
= (uint8_t)((SD_Handle
.CID
[0] & 0x00FF0000) >> 16);
434 SD_CardInfo
.SD_cid
.OEM_AppliID
= Temp
<< 8;
437 Temp
= (uint8_t)((SD_Handle
.CID
[0] & 0x000000FF00) >> 8);
438 SD_CardInfo
.SD_cid
.OEM_AppliID
|= Temp
;
441 Temp
= (uint8_t)(SD_Handle
.CID
[0] & 0x000000FF);
442 SD_CardInfo
.SD_cid
.ProdName1
= Temp
<< 24;
445 Temp
= (uint8_t)((SD_Handle
.CID
[1] & 0xFF000000) >> 24);
446 SD_CardInfo
.SD_cid
.ProdName1
|= Temp
<< 16;
449 Temp
= (uint8_t)((SD_Handle
.CID
[1] & 0x00FF0000) >> 16);
450 SD_CardInfo
.SD_cid
.ProdName1
|= Temp
<< 8;
453 Temp
= (uint8_t)((SD_Handle
.CID
[1] & 0x0000FF00) >> 8);
454 SD_CardInfo
.SD_cid
.ProdName1
|= Temp
;
457 Temp
= (uint8_t)(SD_Handle
.CID
[1] & 0x000000FF);
458 SD_CardInfo
.SD_cid
.ProdName2
= Temp
;
461 Temp
= (uint8_t)((SD_Handle
.CID
[2] & 0xFF000000) >> 24);
462 SD_CardInfo
.SD_cid
.ProdRev
= Temp
;
465 Temp
= (uint8_t)((SD_Handle
.CID
[2] & 0x00FF0000) >> 16);
466 SD_CardInfo
.SD_cid
.ProdSN
= Temp
<< 24;
469 Temp
= (uint8_t)((SD_Handle
.CID
[2] & 0x0000FF00) >> 8);
470 SD_CardInfo
.SD_cid
.ProdSN
|= Temp
<< 16;
473 Temp
= (uint8_t)(SD_Handle
.CID
[2] & 0x000000FF);
474 SD_CardInfo
.SD_cid
.ProdSN
|= Temp
<< 8;
477 Temp
= (uint8_t)((SD_Handle
.CID
[3] & 0xFF000000) >> 24);
478 SD_CardInfo
.SD_cid
.ProdSN
|= Temp
;
481 Temp
= (uint8_t)((SD_Handle
.CID
[3] & 0x00FF0000) >> 16);
482 SD_CardInfo
.SD_cid
.Reserved1
|= (Temp
& 0xF0) >> 4;
483 SD_CardInfo
.SD_cid
.ManufactDate
= (Temp
& 0x0F) << 8;
486 Temp
= (uint8_t)((SD_Handle
.CID
[3] & 0x0000FF00) >> 8);
487 SD_CardInfo
.SD_cid
.ManufactDate
|= Temp
;
490 Temp
= (uint8_t)(SD_Handle
.CID
[3] & 0x000000FF);
491 SD_CardInfo
.SD_cid
.CID_CRC
= (Temp
& 0xFE) >> 1;
492 SD_CardInfo
.SD_cid
.Reserved2
= 1;
497 SD_Error_t
SD_CheckWrite(void) {
498 if (SD_Handle
.TXCplt
!= 0) return SD_BUSY
;
502 SD_Error_t
SD_CheckRead(void) {
503 if (SD_Handle
.RXCplt
!= 0) return SD_BUSY
;
507 SD_Error_t
SD_WriteBlocks_DMA(uint64_t WriteAddress
, uint32_t *buffer
, uint32_t BlockSize
, uint32_t NumberOfBlocks
)
509 SD_Error_t ErrorState
= SD_OK
;
510 SD_Handle
.TXCplt
= 1;
512 if (BlockSize
!= 512) {
513 return SD_ERROR
; // unsupported.
516 if ((uint32_t)buffer
& 0x1f) {
517 return SD_ADDR_MISALIGNED
;
520 // Ensure the data is flushed to main memory
521 SCB_CleanDCache_by_Addr(buffer
, NumberOfBlocks
* BlockSize
);
523 HAL_StatusTypeDef status
;
524 if ((status
= HAL_SD_WriteBlocks_DMA(&hsd1
, (uint8_t *)buffer
, WriteAddress
, NumberOfBlocks
)) != HAL_OK
) {
534 uint32_t NumberOfBlocks
;
535 } sdReadParameters_t
;
537 sdReadParameters_t sdReadParameters
;
539 SD_Error_t
SD_ReadBlocks_DMA(uint64_t ReadAddress
, uint32_t *buffer
, uint32_t BlockSize
, uint32_t NumberOfBlocks
)
541 SD_Error_t ErrorState
= SD_OK
;
543 if (BlockSize
!= 512) {
544 return SD_ERROR
; // unsupported.
547 if ((uint32_t)buffer
& 0x1f) {
548 return SD_ADDR_MISALIGNED
;
551 SD_Handle
.RXCplt
= 1;
553 sdReadParameters
.buffer
= buffer
;
554 sdReadParameters
.BlockSize
= BlockSize
;
555 sdReadParameters
.NumberOfBlocks
= NumberOfBlocks
;
557 HAL_StatusTypeDef status
;
558 if ((status
= HAL_SD_ReadBlocks_DMA(&hsd1
, (uint8_t *)buffer
, ReadAddress
, NumberOfBlocks
)) != HAL_OK
) {
566 * @brief Tx Transfer completed callback
567 * @param hsd: SD handle
570 void HAL_SD_TxCpltCallback(SD_HandleTypeDef
*hsd
)
574 SD_Handle
.TXCplt
= 0;
578 * @brief Rx Transfer completed callback
579 * @param hsd: SD handle
582 void HAL_SD_RxCpltCallback(SD_HandleTypeDef
*hsd
)
586 SD_Handle
.RXCplt
= 0;
589 the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address,
590 adjust the address and the D-Cache size to invalidate accordingly.
592 uint32_t alignedAddr
= (uint32_t)sdReadParameters
.buffer
& ~0x1F;
593 SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr
, sdReadParameters
.NumberOfBlocks
* sdReadParameters
.BlockSize
+ ((uint32_t)sdReadParameters
.buffer
- alignedAddr
));
596 void HAL_SD_AbortCallback(SD_HandleTypeDef
*hsd
)
600 SD_Handle
.TXCplt
= 0;
601 SD_Handle
.RXCplt
= 0;
604 void SDMMC1_IRQHandler(void)
606 HAL_SD_IRQHandler(&hsd1
);
609 void SDMMC2_IRQHandler(void)
611 HAL_SD_IRQHandler(&hsd1
);