|
| 1 | +/* |
| 2 | + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + */ |
| 6 | + |
| 7 | +#include <stdio.h> |
| 8 | +#include <stdlib.h> |
| 9 | +#include <stdint.h> |
| 10 | +#include "esp_err.h" |
| 11 | +#include "esp_log.h" |
| 12 | +#include "driver/sdspi_host.h" |
| 13 | +#include "sdmmc_cmd.h" |
| 14 | +#if SOC_SDMMC_IO_POWER_EXTERNAL |
| 15 | +#include "sd_pwr_ctrl_by_on_chip_ldo.h" |
| 16 | +#endif |
| 17 | + |
| 18 | +static const char *TAG = "esp_ext_part_tables_example_basic_utils"; |
| 19 | + |
| 20 | +#define PIN_NUM_MISO CONFIG_EXAMPLE_PIN_MISO |
| 21 | +#define PIN_NUM_MOSI CONFIG_EXAMPLE_PIN_MOSI |
| 22 | +#define PIN_NUM_CLK CONFIG_EXAMPLE_PIN_CLK |
| 23 | +#define PIN_NUM_CS CONFIG_EXAMPLE_PIN_CS |
| 24 | + |
| 25 | +esp_err_t load_first_sector_from_sd_card(void* mbr_buffer) |
| 26 | +{ |
| 27 | + // This function loads the first sector (MBR) from the SD card into the provided buffer |
| 28 | + // It uses SDSPI but can be adapted for SDMMC as well |
| 29 | + esp_err_t ret = ESP_OK; |
| 30 | + sdmmc_host_t host = SDSPI_HOST_DEFAULT(); |
| 31 | + |
| 32 | + // For SoCs where the SD power can be supplied both via an internal or external (e.g. on-board LDO) power supply. |
| 33 | + // When using specific IO pins (which can be used for ultra high-speed SDMMC) to connect to the SD card |
| 34 | + // and the internal LDO power supply, we need to initialize the power supply first. |
| 35 | +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO |
| 36 | + sd_pwr_ctrl_ldo_config_t ldo_config = { |
| 37 | + .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID, |
| 38 | + }; |
| 39 | + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; |
| 40 | + |
| 41 | + ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); |
| 42 | + if (ret != ESP_OK) { |
| 43 | + ESP_LOGE(TAG, "Failed to create a new on-chip LDO power control driver"); |
| 44 | + return; |
| 45 | + } |
| 46 | + host.pwr_ctrl_handle = pwr_ctrl_handle; |
| 47 | +#endif |
| 48 | + |
| 49 | + spi_bus_config_t bus_cfg = { |
| 50 | + .mosi_io_num = PIN_NUM_MOSI, |
| 51 | + .miso_io_num = PIN_NUM_MISO, |
| 52 | + .sclk_io_num = PIN_NUM_CLK, |
| 53 | + .quadwp_io_num = -1, |
| 54 | + .quadhd_io_num = -1, |
| 55 | + .max_transfer_sz = 4000, |
| 56 | + }; |
| 57 | + |
| 58 | + ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA); |
| 59 | + if (ret != ESP_OK) { |
| 60 | + ESP_LOGE(TAG, "Failed to initialize bus."); |
| 61 | + return ret; |
| 62 | + } |
| 63 | + |
| 64 | + sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); |
| 65 | + slot_config.gpio_cs = PIN_NUM_CS; |
| 66 | + slot_config.host_id = host.slot; |
| 67 | + |
| 68 | + ret = host.init(); |
| 69 | + if (ret != ESP_OK) { |
| 70 | + ESP_LOGE(TAG, "Failed to initialize host."); |
| 71 | + spi_bus_free(host.slot); |
| 72 | + return ret; |
| 73 | + } |
| 74 | + |
| 75 | + int slot = -1; |
| 76 | + ret = sdspi_host_init_device((const sdspi_device_config_t*)&slot_config, &slot); |
| 77 | + if (ret != ESP_OK) { |
| 78 | + ESP_LOGE(TAG, "Failed to initialize SPI device."); |
| 79 | + spi_bus_free(host.slot); |
| 80 | + return ret; |
| 81 | + } |
| 82 | + host.slot = slot; |
| 83 | + |
| 84 | + sdmmc_card_t card = {0}; |
| 85 | + ret = sdmmc_card_init(&host, &card); |
| 86 | + if (ret != ESP_OK) { |
| 87 | + ESP_LOGE(TAG, "Failed to initialize SD card."); |
| 88 | + spi_bus_free(host.slot); |
| 89 | + return ret; |
| 90 | + } |
| 91 | + |
| 92 | + ret = sdmmc_read_sectors(&card, mbr_buffer, 0, 1); |
| 93 | + if (ret != ESP_OK) { |
| 94 | + ESP_LOGE(TAG, "Failed to read first sector from SD card."); |
| 95 | + spi_bus_free(host.slot); |
| 96 | + return ret; |
| 97 | + } |
| 98 | + |
| 99 | + return ESP_OK; |
| 100 | +} |
0 commit comments