Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / sdcard / sdmmc_sdio_h7xx.c
blobd8cf16ba83e0076771a6385246023c64a970d5b0
1 /*
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)
8 * any later version.
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) -------------------------------------------------------------------------------------------------------*/
28 #include "stdbool.h"
29 #include <string.h>
31 #include "platform.h"
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
54 } SD_Handle_t;
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 {
64 ioTag_t pin;
65 uint8_t af;
66 } sdioPin_t;
68 #define SDIO_PIN_D0 0
69 #define SDIO_PIN_D1 1
70 #define SDIO_PIN_D2 2
71 #define SDIO_PIN_D3 3
72 #define SDIO_PIN_CK 4
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;
80 IRQn_Type irqn;
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];
87 } sdioHardware_t;
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] = {
95 .instance = SDMMC1,
96 .irqn = SDMMC1_IRQn,
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) },
105 .instance = SDMMC2,
106 .irqn = SDMMC2_IRQn,
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) },
116 #undef PINDEF
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) {
125 return;
128 sdioHardware = &sdioPinHardware[SDCARD_SDIO_DEVICE];
130 #ifdef SDCARD_SDIO2_CK_ALT
131 sdioPin[SDIO_PIN_CK] = sdioHardware->sdioPinCK[1];
132 #else
133 sdioPin[SDIO_PIN_CK] = sdioHardware->sdioPinCK[0];
134 #endif
135 #ifdef SDCARD_SDIO2_CMD_ALT
136 sdioPin[SDIO_PIN_CMD] = sdioHardware->sdioPinCMD[1];
137 #else
138 sdioPin[SDIO_PIN_CMD] = sdioHardware->sdioPinCMD[0];
139 #endif
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];
146 #endif
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)
153 UNUSED(hsd);
155 if (!sdioHardware) {
156 return;
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);
186 #endif
188 HAL_NVIC_SetPriority(sdioHardware->irqn, 0, 0);
189 HAL_NVIC_EnableIRQ(sdioHardware->irqn);
192 void SDIO_GPIO_Init(void)
194 if (!sdioHardware) {
195 return;
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);
213 #endif
216 // Setting all the SDIO pins to high for a short time results in more robust initialisation.
218 IOHi(d0);
219 IOConfigGPIO(d0, IOCFG_OUT_PP);
221 #ifdef SDCARD_SDIO_4BIT
222 IOHi(d1);
223 IOHi(d2);
224 IOHi(d3);
225 IOConfigGPIO(d1, IOCFG_OUT_PP);
226 IOConfigGPIO(d2, IOCFG_OUT_PP);
227 IOConfigGPIO(d3, IOCFG_OUT_PP);
228 #endif
230 IOHi(clk);
231 IOHi(cmd);
232 IOConfigGPIO(clk, IOCFG_OUT_PP);
233 IOConfigGPIO(cmd, IOCFG_OUT_PP);
236 bool SD_Initialize_LL(DMA_Stream_TypeDef *dma)
238 UNUSED(dma);
239 return true;
242 bool SD_GetState(void)
244 HAL_SD_CardStateTypedef cardState = HAL_SD_GetCardState(&hsd1);
246 return (cardState == HAL_SD_CARD_TRANSFER);
249 bool SD_Init(void)
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;
261 #else
262 hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B; // FIXME untested
263 #endif
264 hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
265 #ifdef SDCARD_SDIO_NORMAL_SPEED
266 hsd1.Init.ClockDiv = SDMMC_NSpeed_CLK_DIV;
267 #else
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
269 #endif
271 status = HAL_SD_Init(&hsd1); // Will call HAL_SD_MspInit
273 if (status != HAL_OK) {
274 return SD_ERROR;
277 switch(hsd1.SdCard.CardType) {
278 case CARD_SDSC:
279 switch (hsd1.SdCard.CardVersion) {
280 case CARD_V1_X:
281 SD_CardType = SD_STD_CAPACITY_V1_1;
282 break;
283 case CARD_V2_X:
284 SD_CardType = SD_STD_CAPACITY_V2_0;
285 break;
286 default:
287 return SD_ERROR;
289 break;
291 case CARD_SDHC_SDXC:
292 SD_CardType = SD_HIGH_CAPACITY;
293 break;
295 default:
296 return SD_ERROR;
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));
305 return SD_OK;
308 SD_Error_t SD_GetCardInfo(void)
310 SD_Error_t ErrorState = SD_OK;
312 // fill in SD_CardInfo
314 uint32_t Temp = 0;
316 // Byte 0
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;
322 // Byte 1
323 Temp = (SD_Handle.CSD[0] & 0x00FF0000) >> 16;
324 SD_CardInfo.SD_csd.TAAC = (uint8_t)Temp;
326 // Byte 2
327 Temp = (SD_Handle.CSD[0] & 0x0000FF00) >> 8;
328 SD_CardInfo.SD_csd.NSAC = (uint8_t)Temp;
330 // Byte 3
331 Temp = SD_Handle.CSD[0] & 0x000000FF;
332 SD_CardInfo.SD_csd.MaxBusClkFrec = (uint8_t)Temp;
334 // Byte 4
335 Temp = (SD_Handle.CSD[1] & 0xFF000000) >> 24;
336 SD_CardInfo.SD_csd.CardComdClasses = (uint16_t)(Temp << 4);
338 // Byte 5
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);
343 // Byte 6
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;
354 // Byte 7
355 Temp = (uint8_t)(SD_Handle.CSD[1] & 0x000000FF);
356 SD_CardInfo.SD_csd.DeviceSize |= (Temp) << 2;
358 // Byte 8
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);
365 // Byte 9
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;
371 // Byte 10
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) {
380 // Byte 7
381 Temp = (uint8_t)(SD_Handle.CSD[1] & 0x000000FF);
382 SD_CardInfo.SD_csd.DeviceSize = (Temp & 0x3F) << 16;
384 // Byte 8
385 Temp = (uint8_t)((SD_Handle.CSD[2] & 0xFF000000) >> 24);
387 SD_CardInfo.SD_csd.DeviceSize |= (Temp << 8);
389 // Byte 9
390 Temp = (uint8_t)((SD_Handle.CSD[2] & 0x00FF0000) >> 16);
392 SD_CardInfo.SD_csd.DeviceSize |= (Temp);
394 // Byte 10
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;
399 } else {
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;
407 // Byte 11
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);
412 // Byte 12
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;
419 // Byte 13
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);
426 // Byte 14
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);
435 // Byte 15
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;
440 // Byte 0
441 Temp = (uint8_t)((SD_Handle.CID[0] & 0xFF000000) >> 24);
442 SD_CardInfo.SD_cid.ManufacturerID = Temp;
444 // Byte 1
445 Temp = (uint8_t)((SD_Handle.CID[0] & 0x00FF0000) >> 16);
446 SD_CardInfo.SD_cid.OEM_AppliID = Temp << 8;
448 // Byte 2
449 Temp = (uint8_t)((SD_Handle.CID[0] & 0x000000FF00) >> 8);
450 SD_CardInfo.SD_cid.OEM_AppliID |= Temp;
452 // Byte 3
453 Temp = (uint8_t)(SD_Handle.CID[0] & 0x000000FF);
454 SD_CardInfo.SD_cid.ProdName1 = Temp << 24;
456 // Byte 4
457 Temp = (uint8_t)((SD_Handle.CID[1] & 0xFF000000) >> 24);
458 SD_CardInfo.SD_cid.ProdName1 |= Temp << 16;
460 // Byte 5
461 Temp = (uint8_t)((SD_Handle.CID[1] & 0x00FF0000) >> 16);
462 SD_CardInfo.SD_cid.ProdName1 |= Temp << 8;
464 // Byte 6
465 Temp = (uint8_t)((SD_Handle.CID[1] & 0x0000FF00) >> 8);
466 SD_CardInfo.SD_cid.ProdName1 |= Temp;
468 // Byte 7
469 Temp = (uint8_t)(SD_Handle.CID[1] & 0x000000FF);
470 SD_CardInfo.SD_cid.ProdName2 = Temp;
472 // Byte 8
473 Temp = (uint8_t)((SD_Handle.CID[2] & 0xFF000000) >> 24);
474 SD_CardInfo.SD_cid.ProdRev = Temp;
476 // Byte 9
477 Temp = (uint8_t)((SD_Handle.CID[2] & 0x00FF0000) >> 16);
478 SD_CardInfo.SD_cid.ProdSN = Temp << 24;
480 // Byte 10
481 Temp = (uint8_t)((SD_Handle.CID[2] & 0x0000FF00) >> 8);
482 SD_CardInfo.SD_cid.ProdSN |= Temp << 16;
484 // Byte 11
485 Temp = (uint8_t)(SD_Handle.CID[2] & 0x000000FF);
486 SD_CardInfo.SD_cid.ProdSN |= Temp << 8;
488 // Byte 12
489 Temp = (uint8_t)((SD_Handle.CID[3] & 0xFF000000) >> 24);
490 SD_CardInfo.SD_cid.ProdSN |= Temp;
492 // Byte 13
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;
497 // Byte 14
498 Temp = (uint8_t)((SD_Handle.CID[3] & 0x0000FF00) >> 8);
499 SD_CardInfo.SD_cid.ManufactDate |= Temp;
501 // Byte 15
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;
506 return ErrorState;
509 SD_Error_t SD_CheckWrite(void) {
510 if (SD_Handle.TXCplt != 0) return SD_BUSY;
511 return SD_OK;
514 SD_Error_t SD_CheckRead(void) {
515 if (SD_Handle.RXCplt != 0) return SD_BUSY;
516 return SD_OK;
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) {
537 return SD_ERROR;
540 return ErrorState;
543 typedef struct {
544 uint32_t *buffer;
545 uint32_t BlockSize;
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) {
571 return SD_ERROR;
574 return ErrorState;
578 * @brief Tx Transfer completed callback
579 * @param hsd: SD handle
580 * @retval None
582 void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
584 UNUSED(hsd);
586 SD_Handle.TXCplt = 0;
590 * @brief Rx Transfer completed callback
591 * @param hsd: SD handle
592 * @retval None
594 void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
596 UNUSED(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)
610 UNUSED(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);
626 #endif