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, PA0
, 9), PINDEF(2, PD7
, 11) },
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 #ifdef SDCARD_SDIO2_CK_ALT
131 sdioPin
[SDIO_PIN_CK
] = sdioHardware
->sdioPinCK
[1];
133 sdioPin
[SDIO_PIN_CK
] = sdioHardware
->sdioPinCK
[0];
135 #ifdef SDCARD_SDIO2_CMD_ALT
136 sdioPin
[SDIO_PIN_CMD
] = sdioHardware
->sdioPinCMD
[1];
138 sdioPin
[SDIO_PIN_CMD
] = sdioHardware
->sdioPinCMD
[0];
140 sdioPin
[SDIO_PIN_D0
] = sdioHardware
->sdioPinD0
[0];
142 #ifdef SDCARD_SDIO_4BIT
143 sdioPin
[SDIO_PIN_D1
] = sdioHardware
->sdioPinD1
[0];
144 sdioPin
[SDIO_PIN_D2
] = sdioHardware
->sdioPinD2
[0];
145 sdioPin
[SDIO_PIN_D3
] = sdioHardware
->sdioPinD3
[0];
149 #define IOCFG_SDMMC IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_NOPULL)
151 void HAL_SD_MspInit(SD_HandleTypeDef
* hsd
)
159 if (sdioHardware
->instance
== SDMMC1
) {
160 __HAL_RCC_SDMMC1_CLK_DISABLE();
161 __HAL_RCC_SDMMC1_FORCE_RESET();
162 __HAL_RCC_SDMMC1_RELEASE_RESET();
163 __HAL_RCC_SDMMC1_CLK_ENABLE();
164 } else if (sdioHardware
->instance
== SDMMC2
) {
165 __HAL_RCC_SDMMC2_CLK_DISABLE();
166 __HAL_RCC_SDMMC2_FORCE_RESET();
167 __HAL_RCC_SDMMC2_RELEASE_RESET();
168 __HAL_RCC_SDMMC2_CLK_ENABLE();
171 const IO_t clk
= IOGetByTag(sdioPin
[SDIO_PIN_CK
].pin
);
172 const IO_t cmd
= IOGetByTag(sdioPin
[SDIO_PIN_CMD
].pin
);
173 const IO_t d0
= IOGetByTag(sdioPin
[SDIO_PIN_D0
].pin
);
174 const IO_t d1
= IOGetByTag(sdioPin
[SDIO_PIN_D1
].pin
);
175 const IO_t d2
= IOGetByTag(sdioPin
[SDIO_PIN_D2
].pin
);
176 const IO_t d3
= IOGetByTag(sdioPin
[SDIO_PIN_D3
].pin
);
178 IOConfigGPIOAF(clk
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_CK
].af
);
179 IOConfigGPIOAF(cmd
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_CMD
].af
);
180 IOConfigGPIOAF(d0
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_D0
].af
);
182 #ifdef SDCARD_SDIO_4BIT
183 IOConfigGPIOAF(d1
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_D1
].af
);
184 IOConfigGPIOAF(d2
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_D2
].af
);
185 IOConfigGPIOAF(d3
, IOCFG_SDMMC
, sdioPin
[SDIO_PIN_D3
].af
);
188 HAL_NVIC_SetPriority(sdioHardware
->irqn
, 0, 0);
189 HAL_NVIC_EnableIRQ(sdioHardware
->irqn
);
192 void SDIO_GPIO_Init(void)
198 const IO_t clk
= IOGetByTag(sdioPin
[SDIO_PIN_CK
].pin
);
199 const IO_t cmd
= IOGetByTag(sdioPin
[SDIO_PIN_CMD
].pin
);
200 const IO_t d0
= IOGetByTag(sdioPin
[SDIO_PIN_D0
].pin
);
201 const IO_t d1
= IOGetByTag(sdioPin
[SDIO_PIN_D1
].pin
);
202 const IO_t d2
= IOGetByTag(sdioPin
[SDIO_PIN_D2
].pin
);
203 const IO_t d3
= IOGetByTag(sdioPin
[SDIO_PIN_D3
].pin
);
205 IOInit(clk
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
206 IOInit(cmd
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
207 IOInit(d0
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
209 #ifdef SDCARD_SDIO_4BIT
210 IOInit(d1
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
211 IOInit(d2
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
212 IOInit(d3
, OWNER_SDCARD
, RESOURCE_NONE
, 0);
216 // Setting all the SDIO pins to high for a short time results in more robust initialisation.
219 IOConfigGPIO(d0
, IOCFG_OUT_PP
);
221 #ifdef SDCARD_SDIO_4BIT
225 IOConfigGPIO(d1
, IOCFG_OUT_PP
);
226 IOConfigGPIO(d2
, IOCFG_OUT_PP
);
227 IOConfigGPIO(d3
, IOCFG_OUT_PP
);
232 IOConfigGPIO(clk
, IOCFG_OUT_PP
);
233 IOConfigGPIO(cmd
, IOCFG_OUT_PP
);
236 bool SD_Initialize_LL(DMA_Stream_TypeDef
*dma
)
242 bool SD_GetState(void)
244 HAL_SD_CardStateTypedef cardState
= HAL_SD_GetCardState(&hsd1
);
246 return (cardState
== HAL_SD_CARD_TRANSFER
);
251 HAL_StatusTypeDef status
;
253 memset(&hsd1
, 0, sizeof(hsd1
));
255 hsd1
.Instance
= sdioHardware
->instance
;
257 hsd1
.Init
.ClockEdge
= SDMMC_CLOCK_EDGE_RISING
;
258 hsd1
.Init
.ClockPowerSave
= SDMMC_CLOCK_POWER_SAVE_ENABLE
;
259 #ifdef SDCARD_SDIO_4BIT
260 hsd1
.Init
.BusWide
= SDMMC_BUS_WIDE_4B
;
262 hsd1
.Init
.BusWide
= SDMMC_BUS_WIDE_1B
; // FIXME untested
264 hsd1
.Init
.HardwareFlowControl
= SDMMC_HARDWARE_FLOW_CONTROL_ENABLE
;
265 #ifdef SDCARD_SDIO_NORMAL_SPEED
266 hsd1
.Init
.ClockDiv
= SDMMC_NSpeed_CLK_DIV
;
268 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
271 status
= HAL_SD_Init(&hsd1
); // Will call HAL_SD_MspInit
273 if (status
!= HAL_OK
) {
277 switch(hsd1
.SdCard
.CardType
) {
279 switch (hsd1
.SdCard
.CardVersion
) {
281 SD_CardType
= SD_STD_CAPACITY_V1_1
;
284 SD_CardType
= SD_STD_CAPACITY_V2_0
;
292 SD_CardType
= SD_HIGH_CAPACITY
;
299 // STATIC_ASSERT(sizeof(SD_Handle.CSD) == sizeof(hsd1.CSD), hal-csd-size-error);
300 memcpy(&SD_Handle
.CSD
, &hsd1
.CSD
, sizeof(SD_Handle
.CSD
));
302 // STATIC_ASSERT(sizeof(SD_Handle.CID) == sizeof(hsd1.CID), hal-cid-size-error);
303 memcpy(&SD_Handle
.CID
, &hsd1
.CID
, sizeof(SD_Handle
.CID
));
308 SD_Error_t
SD_GetCardInfo(void)
310 SD_Error_t ErrorState
= SD_OK
;
312 // fill in SD_CardInfo
317 Temp
= (SD_Handle
.CSD
[0] & 0xFF000000) >> 24;
318 SD_CardInfo
.SD_csd
.CSDStruct
= (uint8_t)((Temp
& 0xC0) >> 6);
319 SD_CardInfo
.SD_csd
.SysSpecVersion
= (uint8_t)((Temp
& 0x3C) >> 2);
320 SD_CardInfo
.SD_csd
.Reserved1
= Temp
& 0x03;
323 Temp
= (SD_Handle
.CSD
[0] & 0x00FF0000) >> 16;
324 SD_CardInfo
.SD_csd
.TAAC
= (uint8_t)Temp
;
327 Temp
= (SD_Handle
.CSD
[0] & 0x0000FF00) >> 8;
328 SD_CardInfo
.SD_csd
.NSAC
= (uint8_t)Temp
;
331 Temp
= SD_Handle
.CSD
[0] & 0x000000FF;
332 SD_CardInfo
.SD_csd
.MaxBusClkFrec
= (uint8_t)Temp
;
335 Temp
= (SD_Handle
.CSD
[1] & 0xFF000000) >> 24;
336 SD_CardInfo
.SD_csd
.CardComdClasses
= (uint16_t)(Temp
<< 4);
339 Temp
= (SD_Handle
.CSD
[1] & 0x00FF0000) >> 16;
340 SD_CardInfo
.SD_csd
.CardComdClasses
|= (uint16_t)((Temp
& 0xF0) >> 4);
341 SD_CardInfo
.SD_csd
.RdBlockLen
= (uint8_t)(Temp
& 0x0F);
344 Temp
= (SD_Handle
.CSD
[1] & 0x0000FF00) >> 8;
345 SD_CardInfo
.SD_csd
.PartBlockRead
= (uint8_t)((Temp
& 0x80) >> 7);
346 SD_CardInfo
.SD_csd
.WrBlockMisalign
= (uint8_t)((Temp
& 0x40) >> 6);
347 SD_CardInfo
.SD_csd
.RdBlockMisalign
= (uint8_t)((Temp
& 0x20) >> 5);
348 SD_CardInfo
.SD_csd
.DSRImpl
= (uint8_t)((Temp
& 0x10) >> 4);
349 SD_CardInfo
.SD_csd
.Reserved2
= 0; /*!< Reserved */
351 if((SD_CardType
== SD_STD_CAPACITY_V1_1
) || (SD_CardType
== SD_STD_CAPACITY_V2_0
)) {
352 SD_CardInfo
.SD_csd
.DeviceSize
= (Temp
& 0x03) << 10;
355 Temp
= (uint8_t)(SD_Handle
.CSD
[1] & 0x000000FF);
356 SD_CardInfo
.SD_csd
.DeviceSize
|= (Temp
) << 2;
359 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0xFF000000) >> 24);
360 SD_CardInfo
.SD_csd
.DeviceSize
|= (Temp
& 0xC0) >> 6;
362 SD_CardInfo
.SD_csd
.MaxRdCurrentVDDMin
= (Temp
& 0x38) >> 3;
363 SD_CardInfo
.SD_csd
.MaxRdCurrentVDDMax
= (Temp
& 0x07);
366 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0x00FF0000) >> 16);
367 SD_CardInfo
.SD_csd
.MaxWrCurrentVDDMin
= (Temp
& 0xE0) >> 5;
368 SD_CardInfo
.SD_csd
.MaxWrCurrentVDDMax
= (Temp
& 0x1C) >> 2;
369 SD_CardInfo
.SD_csd
.DeviceSizeMul
= (Temp
& 0x03) << 1;
372 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0x0000FF00) >> 8);
373 SD_CardInfo
.SD_csd
.DeviceSizeMul
|= (Temp
& 0x80) >> 7;
375 SD_CardInfo
.CardCapacity
= (SD_CardInfo
.SD_csd
.DeviceSize
+ 1) ;
376 SD_CardInfo
.CardCapacity
*= (1 << (SD_CardInfo
.SD_csd
.DeviceSizeMul
+ 2));
377 SD_CardInfo
.CardBlockSize
= 1 << (SD_CardInfo
.SD_csd
.RdBlockLen
);
378 SD_CardInfo
.CardCapacity
= SD_CardInfo
.CardCapacity
* SD_CardInfo
.CardBlockSize
/ 512; // In 512 byte blocks
379 } else if(SD_CardType
== SD_HIGH_CAPACITY
) {
381 Temp
= (uint8_t)(SD_Handle
.CSD
[1] & 0x000000FF);
382 SD_CardInfo
.SD_csd
.DeviceSize
= (Temp
& 0x3F) << 16;
385 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0xFF000000) >> 24);
387 SD_CardInfo
.SD_csd
.DeviceSize
|= (Temp
<< 8);
390 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0x00FF0000) >> 16);
392 SD_CardInfo
.SD_csd
.DeviceSize
|= (Temp
);
395 Temp
= (uint8_t)((SD_Handle
.CSD
[2] & 0x0000FF00) >> 8);
397 SD_CardInfo
.CardCapacity
= ((uint64_t)SD_CardInfo
.SD_csd
.DeviceSize
+ 1) * 1024;
398 SD_CardInfo
.CardBlockSize
= 512;
400 // Not supported card type
401 ErrorState
= SD_ERROR
;
404 SD_CardInfo
.SD_csd
.EraseGrSize
= (Temp
& 0x40) >> 6;
405 SD_CardInfo
.SD_csd
.EraseGrMul
= (Temp
& 0x3F) << 1;
408 Temp
= (uint8_t)(SD_Handle
.CSD
[2] & 0x000000FF);
409 SD_CardInfo
.SD_csd
.EraseGrMul
|= (Temp
& 0x80) >> 7;
410 SD_CardInfo
.SD_csd
.WrProtectGrSize
= (Temp
& 0x7F);
413 Temp
= (uint8_t)((SD_Handle
.CSD
[3] & 0xFF000000) >> 24);
414 SD_CardInfo
.SD_csd
.WrProtectGrEnable
= (Temp
& 0x80) >> 7;
415 SD_CardInfo
.SD_csd
.ManDeflECC
= (Temp
& 0x60) >> 5;
416 SD_CardInfo
.SD_csd
.WrSpeedFact
= (Temp
& 0x1C) >> 2;
417 SD_CardInfo
.SD_csd
.MaxWrBlockLen
= (Temp
& 0x03) << 2;
420 Temp
= (uint8_t)((SD_Handle
.CSD
[3] & 0x00FF0000) >> 16);
421 SD_CardInfo
.SD_csd
.MaxWrBlockLen
|= (Temp
& 0xC0) >> 6;
422 SD_CardInfo
.SD_csd
.WriteBlockPaPartial
= (Temp
& 0x20) >> 5;
423 SD_CardInfo
.SD_csd
.Reserved3
= 0;
424 SD_CardInfo
.SD_csd
.ContentProtectAppli
= (Temp
& 0x01);
427 Temp
= (uint8_t)((SD_Handle
.CSD
[3] & 0x0000FF00) >> 8);
428 SD_CardInfo
.SD_csd
.FileFormatGrouop
= (Temp
& 0x80) >> 7;
429 SD_CardInfo
.SD_csd
.CopyFlag
= (Temp
& 0x40) >> 6;
430 SD_CardInfo
.SD_csd
.PermWrProtect
= (Temp
& 0x20) >> 5;
431 SD_CardInfo
.SD_csd
.TempWrProtect
= (Temp
& 0x10) >> 4;
432 SD_CardInfo
.SD_csd
.FileFormat
= (Temp
& 0x0C) >> 2;
433 SD_CardInfo
.SD_csd
.ECC
= (Temp
& 0x03);
436 Temp
= (uint8_t)(SD_Handle
.CSD
[3] & 0x000000FF);
437 SD_CardInfo
.SD_csd
.CSD_CRC
= (Temp
& 0xFE) >> 1;
438 SD_CardInfo
.SD_csd
.Reserved4
= 1;
441 Temp
= (uint8_t)((SD_Handle
.CID
[0] & 0xFF000000) >> 24);
442 SD_CardInfo
.SD_cid
.ManufacturerID
= Temp
;
445 Temp
= (uint8_t)((SD_Handle
.CID
[0] & 0x00FF0000) >> 16);
446 SD_CardInfo
.SD_cid
.OEM_AppliID
= Temp
<< 8;
449 Temp
= (uint8_t)((SD_Handle
.CID
[0] & 0x000000FF00) >> 8);
450 SD_CardInfo
.SD_cid
.OEM_AppliID
|= Temp
;
453 Temp
= (uint8_t)(SD_Handle
.CID
[0] & 0x000000FF);
454 SD_CardInfo
.SD_cid
.ProdName1
= Temp
<< 24;
457 Temp
= (uint8_t)((SD_Handle
.CID
[1] & 0xFF000000) >> 24);
458 SD_CardInfo
.SD_cid
.ProdName1
|= Temp
<< 16;
461 Temp
= (uint8_t)((SD_Handle
.CID
[1] & 0x00FF0000) >> 16);
462 SD_CardInfo
.SD_cid
.ProdName1
|= Temp
<< 8;
465 Temp
= (uint8_t)((SD_Handle
.CID
[1] & 0x0000FF00) >> 8);
466 SD_CardInfo
.SD_cid
.ProdName1
|= Temp
;
469 Temp
= (uint8_t)(SD_Handle
.CID
[1] & 0x000000FF);
470 SD_CardInfo
.SD_cid
.ProdName2
= Temp
;
473 Temp
= (uint8_t)((SD_Handle
.CID
[2] & 0xFF000000) >> 24);
474 SD_CardInfo
.SD_cid
.ProdRev
= Temp
;
477 Temp
= (uint8_t)((SD_Handle
.CID
[2] & 0x00FF0000) >> 16);
478 SD_CardInfo
.SD_cid
.ProdSN
= Temp
<< 24;
481 Temp
= (uint8_t)((SD_Handle
.CID
[2] & 0x0000FF00) >> 8);
482 SD_CardInfo
.SD_cid
.ProdSN
|= Temp
<< 16;
485 Temp
= (uint8_t)(SD_Handle
.CID
[2] & 0x000000FF);
486 SD_CardInfo
.SD_cid
.ProdSN
|= Temp
<< 8;
489 Temp
= (uint8_t)((SD_Handle
.CID
[3] & 0xFF000000) >> 24);
490 SD_CardInfo
.SD_cid
.ProdSN
|= Temp
;
493 Temp
= (uint8_t)((SD_Handle
.CID
[3] & 0x00FF0000) >> 16);
494 SD_CardInfo
.SD_cid
.Reserved1
|= (Temp
& 0xF0) >> 4;
495 SD_CardInfo
.SD_cid
.ManufactDate
= (Temp
& 0x0F) << 8;
498 Temp
= (uint8_t)((SD_Handle
.CID
[3] & 0x0000FF00) >> 8);
499 SD_CardInfo
.SD_cid
.ManufactDate
|= Temp
;
502 Temp
= (uint8_t)(SD_Handle
.CID
[3] & 0x000000FF);
503 SD_CardInfo
.SD_cid
.CID_CRC
= (Temp
& 0xFE) >> 1;
504 SD_CardInfo
.SD_cid
.Reserved2
= 1;
509 SD_Error_t
SD_CheckWrite(void) {
510 if (SD_Handle
.TXCplt
!= 0) return SD_BUSY
;
514 SD_Error_t
SD_CheckRead(void) {
515 if (SD_Handle
.RXCplt
!= 0) return SD_BUSY
;
519 SD_Error_t
SD_WriteBlocks_DMA(uint64_t WriteAddress
, uint32_t *buffer
, uint32_t BlockSize
, uint32_t NumberOfBlocks
)
521 SD_Error_t ErrorState
= SD_OK
;
522 SD_Handle
.TXCplt
= 1;
524 if (BlockSize
!= 512) {
525 return SD_ERROR
; // unsupported.
528 if ((uint32_t)buffer
& 0x1f) {
529 return SD_ADDR_MISALIGNED
;
532 // Ensure the data is flushed to main memory
533 SCB_CleanDCache_by_Addr(buffer
, NumberOfBlocks
* BlockSize
);
535 HAL_StatusTypeDef status
;
536 if ((status
= HAL_SD_WriteBlocks_DMA(&hsd1
, (uint8_t *)buffer
, WriteAddress
, NumberOfBlocks
)) != HAL_OK
) {
546 uint32_t NumberOfBlocks
;
547 } sdReadParameters_t
;
549 sdReadParameters_t sdReadParameters
;
551 SD_Error_t
SD_ReadBlocks_DMA(uint64_t ReadAddress
, uint32_t *buffer
, uint32_t BlockSize
, uint32_t NumberOfBlocks
)
553 SD_Error_t ErrorState
= SD_OK
;
555 if (BlockSize
!= 512) {
556 return SD_ERROR
; // unsupported.
559 if ((uint32_t)buffer
& 0x1f) {
560 return SD_ADDR_MISALIGNED
;
563 SD_Handle
.RXCplt
= 1;
565 sdReadParameters
.buffer
= buffer
;
566 sdReadParameters
.BlockSize
= BlockSize
;
567 sdReadParameters
.NumberOfBlocks
= NumberOfBlocks
;
569 HAL_StatusTypeDef status
;
570 if ((status
= HAL_SD_ReadBlocks_DMA(&hsd1
, (uint8_t *)buffer
, ReadAddress
, NumberOfBlocks
)) != HAL_OK
) {
578 * @brief Tx Transfer completed callback
579 * @param hsd: SD handle
582 void HAL_SD_TxCpltCallback(SD_HandleTypeDef
*hsd
)
586 SD_Handle
.TXCplt
= 0;
590 * @brief Rx Transfer completed callback
591 * @param hsd: SD handle
594 void HAL_SD_RxCpltCallback(SD_HandleTypeDef
*hsd
)
598 SD_Handle
.RXCplt
= 0;
601 the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address,
602 adjust the address and the D-Cache size to invalidate accordingly.
604 uint32_t alignedAddr
= (uint32_t)sdReadParameters
.buffer
& ~0x1F;
605 SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr
, sdReadParameters
.NumberOfBlocks
* sdReadParameters
.BlockSize
+ ((uint32_t)sdReadParameters
.buffer
- alignedAddr
));
608 void HAL_SD_AbortCallback(SD_HandleTypeDef
*hsd
)
612 SD_Handle
.TXCplt
= 0;
613 SD_Handle
.RXCplt
= 0;
616 void SDMMC1_IRQHandler(void)
618 HAL_SD_IRQHandler(&hsd1
);
621 void SDMMC2_IRQHandler(void)
623 HAL_SD_IRQHandler(&hsd1
);