fusee: fix sdmmc speed modes

This commit is contained in:
hexkyz 2020-11-11 18:05:30 +00:00 committed by SciresM
parent d233b482fb
commit 5e342d8c52
5 changed files with 80 additions and 80 deletions

View file

@ -734,11 +734,11 @@ static int sdmmc_sd_switch_hs_low(sdmmc_device_t *device, uint8_t *status)
return 0; return 0;
/* Reconfigure the internal clock. */ /* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_UHS_SDR104)) if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR104))
return 0; return 0;
/* Run tuning. */ /* Run tuning. */
if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_UHS_SDR104, MMC_SEND_TUNING_BLOCK)) if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR104, MMC_SEND_TUNING_BLOCK))
return 0; return 0;
} }
else if (status[13] & SD_MODE_UHS_SDR50) /* High-speed SDR50 is supported. */ else if (status[13] & SD_MODE_UHS_SDR50) /* High-speed SDR50 is supported. */
@ -748,11 +748,11 @@ static int sdmmc_sd_switch_hs_low(sdmmc_device_t *device, uint8_t *status)
return 0; return 0;
/* Reconfigure the internal clock. */ /* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_UHS_SDR50)) if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR50))
return 0; return 0;
/* Run tuning. */ /* Run tuning. */
if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_UHS_SDR50, MMC_SEND_TUNING_BLOCK)) if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR50, MMC_SEND_TUNING_BLOCK))
return 0; return 0;
} }
else if (status[13] & SD_MODE_UHS_SDR12) /* High-speed SDR12 is supported. */ else if (status[13] & SD_MODE_UHS_SDR12) /* High-speed SDR12 is supported. */
@ -762,11 +762,11 @@ static int sdmmc_sd_switch_hs_low(sdmmc_device_t *device, uint8_t *status)
return 0; return 0;
/* Reconfigure the internal clock. */ /* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_UHS_SDR12)) if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR12))
return 0; return 0;
/* Run tuning. */ /* Run tuning. */
if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_UHS_SDR12, MMC_SEND_TUNING_BLOCK)) if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR12, MMC_SEND_TUNING_BLOCK))
return 0; return 0;
} }
else else
@ -791,7 +791,7 @@ static int sdmmc_sd_switch_hs_high(sdmmc_device_t *device, uint8_t *status)
return 0; return 0;
/* Reconfigure the internal clock. */ /* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_UHS_SDR25)) if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR25))
return 0; return 0;
/* Peek the SD card's status. */ /* Peek the SD card's status. */
@ -848,7 +848,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
memset(device, 0, sizeof(sdmmc_device_t)); memset(device, 0, sizeof(sdmmc_device_t));
/* Try to initialize the driver. */ /* Try to initialize the driver. */
if (!sdmmc_init(sdmmc, SDMMC_1, SDMMC_VOLTAGE_3V3, SDMMC_BUS_WIDTH_1BIT, SDMMC_SPEED_SD_INIT)) if (!sdmmc_init(sdmmc, SDMMC_1, SDMMC_VOLTAGE_3V3, SDMMC_BUS_WIDTH_1BIT, SDMMC_SPEED_SD_IDENT))
{ {
sdmmc_error(sdmmc, "Failed to initialize the SDMMC driver!"); sdmmc_error(sdmmc, "Failed to initialize the SDMMC driver!");
return 0; return 0;
@ -881,7 +881,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_info(sdmmc, "Sent if cond to SD card!"); sdmmc_info(sdmmc, "Sent if cond to SD card!");
/* Get the SD card's operating conditions. */ /* Get the SD card's operating conditions. */
if (!sdmmc_sd_send_op_cond(device, is_sd_ver2, (bus_width == SDMMC_BUS_WIDTH_4BIT) && (bus_speed == SDMMC_SPEED_UHS_SDR104))) if (!sdmmc_sd_send_op_cond(device, is_sd_ver2, (bus_width == SDMMC_BUS_WIDTH_4BIT) && (bus_speed == SDMMC_SPEED_SD_SDR104)))
{ {
sdmmc_error(sdmmc, "Failed to send op cond!"); sdmmc_error(sdmmc, "Failed to send op cond!");
return 0; return 0;
@ -927,7 +927,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
if (!device->is_180v) if (!device->is_180v)
{ {
/* Reconfigure the internal clock. */ /* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_LEGACY)) if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_DS))
{ {
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!"); sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
return 0; return 0;
@ -1005,7 +1005,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_info(sdmmc, "Switched to high-speed from low voltage!"); sdmmc_info(sdmmc, "Switched to high-speed from low voltage!");
} }
else if ((device->scr.sda_vsn & (SD_SCR_SPEC_VER_1 | SD_SCR_SPEC_VER_2)) && ((bus_speed != SDMMC_SPEED_SD_LEGACY))) else if ((device->scr.sda_vsn & (SD_SCR_SPEC_VER_1 | SD_SCR_SPEC_VER_2)) && ((bus_speed != SDMMC_SPEED_SD_DS)))
{ {
/* Switch to high-speed from high voltage (if possible). */ /* Switch to high-speed from high voltage (if possible). */
if (!sdmmc_sd_switch_hs_high(device, switch_status)) if (!sdmmc_sd_switch_hs_high(device, switch_status))
@ -1404,7 +1404,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
memset(device, 0, sizeof(sdmmc_device_t)); memset(device, 0, sizeof(sdmmc_device_t));
/* Try to initialize the driver. */ /* Try to initialize the driver. */
if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_VOLTAGE_1V8, SDMMC_BUS_WIDTH_1BIT, SDMMC_SPEED_MMC_INIT)) if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_VOLTAGE_1V8, SDMMC_BUS_WIDTH_1BIT, SDMMC_SPEED_MMC_IDENT))
{ {
sdmmc_error(sdmmc, "Failed to initialize the SDMMC driver!"); sdmmc_error(sdmmc, "Failed to initialize the SDMMC driver!");
return 0; return 0;

View file

@ -307,28 +307,28 @@ static int sdmmc_get_sdclk_freq(SdmmcBusSpeed bus_speed)
{ {
switch (bus_speed) switch (bus_speed)
{ {
case SDMMC_SPEED_MMC_INIT: case SDMMC_SPEED_MMC_IDENT:
case SDMMC_SPEED_MMC_LEGACY: case SDMMC_SPEED_MMC_LEGACY:
return 26000; return 26000;
case SDMMC_SPEED_MMC_HS: case SDMMC_SPEED_MMC_HS:
return 52000; return 52000;
case SDMMC_SPEED_MMC_HS200: case SDMMC_SPEED_MMC_HS200:
case SDMMC_SPEED_MMC_HS400: case SDMMC_SPEED_MMC_HS400:
case SDMMC_SPEED_UHS_SDR104: case SDMMC_SPEED_SD_SDR104:
case SDMMC_SPEED_EMU_SDR104: case SDMMC_SPEED_EMU_SDR104:
return 200000; return 200000;
case SDMMC_SPEED_SD_INIT: case SDMMC_SPEED_SD_IDENT:
case SDMMC_SPEED_SD_LEGACY: case SDMMC_SPEED_SD_DS:
case SDMMC_SPEED_UHS_SDR12: case SDMMC_SPEED_SD_SDR12:
return 25000; return 25000;
case SDMMC_SPEED_SD_HS: case SDMMC_SPEED_SD_HS:
case SDMMC_SPEED_UHS_SDR25: case SDMMC_SPEED_SD_SDR25:
return 50000; return 50000;
case SDMMC_SPEED_UHS_SDR50: case SDMMC_SPEED_SD_SDR50:
return 100000; return 100000;
case SDMMC_SPEED_UHS_DDR50: case SDMMC_SPEED_GC_ASIC_FPGA:
return 40800; return 40800;
case SDMMC_SPEED_MMC_DDR52: case SDMMC_SPEED_GC_ASIC:
return 200000; return 200000;
default: default:
return 0; return 0;
@ -340,23 +340,23 @@ static int sdmmc_get_sdclk_div(SdmmcBusSpeed bus_speed)
{ {
switch (bus_speed) switch (bus_speed)
{ {
case SDMMC_SPEED_MMC_INIT: case SDMMC_SPEED_MMC_IDENT:
return 66; return 66;
case SDMMC_SPEED_SD_INIT: case SDMMC_SPEED_SD_IDENT:
case SDMMC_SPEED_MMC_LEGACY: case SDMMC_SPEED_MMC_LEGACY:
case SDMMC_SPEED_MMC_HS: case SDMMC_SPEED_MMC_HS:
case SDMMC_SPEED_MMC_HS200: case SDMMC_SPEED_MMC_HS200:
case SDMMC_SPEED_MMC_HS400: case SDMMC_SPEED_MMC_HS400:
case SDMMC_SPEED_SD_LEGACY: case SDMMC_SPEED_SD_DS:
case SDMMC_SPEED_SD_HS: case SDMMC_SPEED_SD_HS:
case SDMMC_SPEED_UHS_SDR12: case SDMMC_SPEED_SD_SDR12:
case SDMMC_SPEED_UHS_SDR25: case SDMMC_SPEED_SD_SDR25:
case SDMMC_SPEED_UHS_SDR50: case SDMMC_SPEED_SD_SDR50:
case SDMMC_SPEED_UHS_SDR104: case SDMMC_SPEED_SD_SDR104:
case SDMMC_SPEED_UHS_DDR50: case SDMMC_SPEED_GC_ASIC_FPGA:
case SDMMC_SPEED_EMU_SDR104: case SDMMC_SPEED_EMU_SDR104:
return 1; return 1;
case SDMMC_SPEED_MMC_DDR52: case SDMMC_SPEED_GC_ASIC:
return 2; return 2;
default: default:
return 0; return 0;
@ -375,7 +375,7 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq
{ {
case 25000: case 25000:
out_freq = 24728; out_freq = 24728;
car_div = SDMMC_CAR_DIVIDER_UHS_SDR12; car_div = SDMMC_CAR_DIVIDER_SD_SDR12;
break; break;
case 26000: case 26000:
out_freq = 25500; out_freq = 25500;
@ -383,11 +383,11 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq
break; break;
case 40800: case 40800:
out_freq = 40800; out_freq = 40800;
car_div = SDMMC_CAR_DIVIDER_UHS_DDR50; car_div = SDMMC_CAR_DIVIDER_GC_ASIC_FPGA;
break; break;
case 50000: case 50000:
out_freq = 48000; out_freq = 48000;
car_div = SDMMC_CAR_DIVIDER_UHS_SDR25; car_div = SDMMC_CAR_DIVIDER_SD_SDR25;
break; break;
case 52000: case 52000:
out_freq = 51000; out_freq = 51000;
@ -395,7 +395,7 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq
break; break;
case 100000: case 100000:
out_freq = 90667; out_freq = 90667;
car_div = SDMMC_CAR_DIVIDER_UHS_SDR50; car_div = SDMMC_CAR_DIVIDER_SD_SDR50;
break; break;
case 200000: case 200000:
out_freq = 163200; out_freq = 163200;
@ -403,7 +403,7 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq
break; break;
case 208000: case 208000:
out_freq = 204000; out_freq = 204000;
car_div = SDMMC_CAR_DIVIDER_UHS_SDR104; car_div = SDMMC_CAR_DIVIDER_SD_SDR104;
break; break;
default: default:
return 0; return 0;
@ -884,10 +884,10 @@ int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
/* Set the appropriate host speed. */ /* Set the appropriate host speed. */
switch (bus_speed) { switch (bus_speed) {
/* 400kHz initialization mode and a few others. */ /* 400kHz initialization mode and a few others. */
case SDMMC_SPEED_MMC_INIT: case SDMMC_SPEED_MMC_IDENT:
case SDMMC_SPEED_MMC_LEGACY: case SDMMC_SPEED_MMC_LEGACY:
case SDMMC_SPEED_SD_INIT: case SDMMC_SPEED_SD_IDENT:
case SDMMC_SPEED_SD_LEGACY: case SDMMC_SPEED_SD_DS:
sdmmc->regs->host_control &= ~(SDHCI_CTRL_HISPD); sdmmc->regs->host_control &= ~(SDHCI_CTRL_HISPD);
sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_VDD_180); sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_VDD_180);
break; break;
@ -895,17 +895,17 @@ int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
/* 50MHz high speed (SD) and 52MHz high speed (MMC). */ /* 50MHz high speed (SD) and 52MHz high speed (MMC). */
case SDMMC_SPEED_SD_HS: case SDMMC_SPEED_SD_HS:
case SDMMC_SPEED_MMC_HS: case SDMMC_SPEED_MMC_HS:
case SDMMC_SPEED_UHS_SDR25: case SDMMC_SPEED_SD_SDR25:
sdmmc->regs->host_control |= SDHCI_CTRL_HISPD; sdmmc->regs->host_control |= SDHCI_CTRL_HISPD;
sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_VDD_180); sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_VDD_180);
break; break;
/* 200MHz UHS-I (SD) and other modes due to errata. */ /* 200MHz UHS-I (SD) and other modes due to errata. */
case SDMMC_SPEED_MMC_HS200: case SDMMC_SPEED_MMC_HS200:
case SDMMC_SPEED_UHS_SDR104: case SDMMC_SPEED_SD_SDR104:
case SDMMC_SPEED_UHS_DDR50: case SDMMC_SPEED_GC_ASIC_FPGA:
case SDMMC_SPEED_UHS_SDR50: case SDMMC_SPEED_SD_SDR50:
case SDMMC_SPEED_MMC_DDR52: case SDMMC_SPEED_GC_ASIC:
case SDMMC_SPEED_EMU_SDR104: case SDMMC_SPEED_EMU_SDR104:
sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK); sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK);
sdmmc->regs->host_control2 |= SDHCI_CTRL_UHS_SDR104; sdmmc->regs->host_control2 |= SDHCI_CTRL_UHS_SDR104;
@ -920,7 +920,7 @@ int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
break; break;
/* 25MHz default speed (SD). */ /* 25MHz default speed (SD). */
case SDMMC_SPEED_UHS_SDR12: case SDMMC_SPEED_SD_SDR12:
sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK); sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK);
sdmmc->regs->host_control2 |= SDHCI_CTRL_UHS_SDR12; sdmmc->regs->host_control2 |= SDHCI_CTRL_UHS_SDR12;
sdmmc->regs->host_control2 |= SDHCI_CTRL_VDD_180; sdmmc->regs->host_control2 |= SDHCI_CTRL_VDD_180;
@ -1754,7 +1754,7 @@ int sdmmc_switch_voltage(sdmmc_t *sdmmc)
sdmmc_disable_sd_clock(sdmmc); sdmmc_disable_sd_clock(sdmmc);
/* Reconfigure the internal clock. */ /* Reconfigure the internal clock. */
if (!sdmmc_select_speed(sdmmc, SDMMC_SPEED_UHS_SDR12)) if (!sdmmc_select_speed(sdmmc, SDMMC_SPEED_SD_SDR12))
{ {
sdmmc_error(sdmmc, "Failed to apply the correct bus speed for low voltage support!"); sdmmc_error(sdmmc, "Failed to apply the correct bus speed for low voltage support!");
return 0; return 0;
@ -1919,14 +1919,14 @@ int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcod
{ {
case SDMMC_SPEED_MMC_HS200: case SDMMC_SPEED_MMC_HS200:
case SDMMC_SPEED_MMC_HS400: case SDMMC_SPEED_MMC_HS400:
case SDMMC_SPEED_UHS_SDR104: case SDMMC_SPEED_SD_SDR104:
case SDMMC_SPEED_EMU_SDR104: case SDMMC_SPEED_EMU_SDR104:
max_tuning_loop = 0x80; max_tuning_loop = 0x80;
tuning_cntrl_flag = 0x4000; tuning_cntrl_flag = 0x4000;
break; break;
case SDMMC_SPEED_UHS_SDR50: case SDMMC_SPEED_SD_SDR50:
case SDMMC_SPEED_UHS_DDR50: case SDMMC_SPEED_GC_ASIC_FPGA:
case SDMMC_SPEED_MMC_DDR52: case SDMMC_SPEED_GC_ASIC:
max_tuning_loop = 0x100; max_tuning_loop = 0x100;
tuning_cntrl_flag = 0x8000; tuning_cntrl_flag = 0x8000;
break; break;

View file

@ -210,33 +210,33 @@ typedef enum {
} SdmmcBusWidth; } SdmmcBusWidth;
typedef enum { typedef enum {
SDMMC_SPEED_MMC_INIT = 0, SDMMC_SPEED_MMC_IDENT = 0,
SDMMC_SPEED_MMC_LEGACY = 1, SDMMC_SPEED_MMC_LEGACY = 1,
SDMMC_SPEED_MMC_HS = 2, SDMMC_SPEED_MMC_HS = 2,
SDMMC_SPEED_MMC_HS200 = 3, SDMMC_SPEED_MMC_HS200 = 3,
SDMMC_SPEED_MMC_HS400 = 4, SDMMC_SPEED_MMC_HS400 = 4,
SDMMC_SPEED_SD_INIT = 5, SDMMC_SPEED_SD_IDENT = 5,
SDMMC_SPEED_SD_LEGACY = 6, SDMMC_SPEED_SD_DS = 6,
SDMMC_SPEED_SD_HS = 7, SDMMC_SPEED_SD_HS = 7,
SDMMC_SPEED_UHS_SDR12 = 8, SDMMC_SPEED_SD_SDR12 = 8,
SDMMC_SPEED_UHS_SDR25 = 9, SDMMC_SPEED_SD_SDR25 = 9,
SDMMC_SPEED_UHS_SDR50 = 10, SDMMC_SPEED_SD_SDR50 = 10,
SDMMC_SPEED_UHS_SDR104 = 11, SDMMC_SPEED_SD_SDR104 = 11,
SDMMC_SPEED_UHS_RESERVED = 12, SDMMC_SPEED_SD_DDR50 = 12,
SDMMC_SPEED_UHS_DDR50 = 13, SDMMC_SPEED_GC_ASIC_FPGA = 13,
SDMMC_SPEED_MMC_DDR52 = 14, SDMMC_SPEED_GC_ASIC = 14,
SDMMC_SPEED_EMU_SDR104 = 255, /* Custom speed mode. Prevents low voltage switch in MMC emulation. */ SDMMC_SPEED_EMU_SDR104 = 255, /* Custom speed mode. Prevents low voltage switch in MMC emulation. */
} SdmmcBusSpeed; } SdmmcBusSpeed;
typedef enum { typedef enum {
SDMMC_CAR_DIVIDER_UHS_SDR12 = 31, /* (16.5 * 2) - 2 */
SDMMC_CAR_DIVIDER_UHS_SDR25 = 15, /* (8.5 * 2) - 2 */
SDMMC_CAR_DIVIDER_UHS_SDR50 = 7, /* (4.5 * 2) - 2 */
SDMMC_CAR_DIVIDER_UHS_SDR104 = 2, /* (2 * 2) - 2 */
SDMMC_CAR_DIVIDER_UHS_DDR50 = 18, /* (5 * 2 * 2) - 2 */
SDMMC_CAR_DIVIDER_MMC_LEGACY = 30, /* (16 * 2) - 2 */ SDMMC_CAR_DIVIDER_MMC_LEGACY = 30, /* (16 * 2) - 2 */
SDMMC_CAR_DIVIDER_MMC_HS = 14, /* (8 * 2) - 2 */ SDMMC_CAR_DIVIDER_MMC_HS = 14, /* (8 * 2) - 2 */
SDMMC_CAR_DIVIDER_MMC_HS200 = 3, /* (2.5 * 2) - 2 (for PLLP_OUT0, same as HS400) */ SDMMC_CAR_DIVIDER_MMC_HS200 = 3, /* (2.5 * 2) - 2 (for PLLP_OUT0, same as HS400) */
SDMMC_CAR_DIVIDER_SD_SDR12 = 31, /* (16.5 * 2) - 2 */
SDMMC_CAR_DIVIDER_SD_SDR25 = 15, /* (8.5 * 2) - 2 */
SDMMC_CAR_DIVIDER_SD_SDR50 = 7, /* (4.5 * 2) - 2 */
SDMMC_CAR_DIVIDER_SD_SDR104 = 2, /* (2 * 2) - 2 */
SDMMC_CAR_DIVIDER_GC_ASIC_FPGA = 18, /* (5 * 2 * 2) - 2 */
} SdmmcCarDivider; } SdmmcCarDivider;
/* Structure for describing a SDMMC device. */ /* Structure for describing a SDMMC device. */

View file

@ -41,7 +41,7 @@ bool mount_sd(void)
if (!g_sd_initialized) { if (!g_sd_initialized) {
/* Initialize SD. */ /* Initialize SD. */
if (sdmmc_device_sd_init(&g_sd_device, &g_sd_sdmmc, SDMMC_BUS_WIDTH_4BIT, SDMMC_SPEED_UHS_SDR104)) if (sdmmc_device_sd_init(&g_sd_device, &g_sd_sdmmc, SDMMC_BUS_WIDTH_4BIT, SDMMC_SPEED_SD_SDR104))
{ {
g_sd_initialized = true; g_sd_initialized = true;

View file

@ -40,7 +40,7 @@ bool mount_sd(void)
if (!g_sd_initialized) { if (!g_sd_initialized) {
/* Initialize SD. */ /* Initialize SD. */
if (sdmmc_device_sd_init(&g_sd_device, &g_sd_sdmmc, SDMMC_BUS_WIDTH_4BIT, SDMMC_SPEED_UHS_SDR104)) if (sdmmc_device_sd_init(&g_sd_device, &g_sd_sdmmc, SDMMC_BUS_WIDTH_4BIT, SDMMC_SPEED_SD_SDR104))
{ {
g_sd_initialized = true; g_sd_initialized = true;