Skip to content

Commit 32537ed

Browse files
committed
esp32s3: Implement sdioio
1 parent 13d659a commit 32537ed

File tree

15 files changed

+309
-20
lines changed

15 files changed

+309
-20
lines changed

locale/circuitpython.pot

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -661,12 +661,12 @@ msgid "Buffer length %d too big. It must be less than %d"
661661
msgstr ""
662662

663663
#: ports/atmel-samd/common-hal/sdioio/SDCard.c
664-
#: ports/cxd56/common-hal/sdioio/SDCard.c shared-module/sdcardio/SDCard.c
665-
msgid "Buffer length must be a multiple of 512"
666-
msgstr ""
667-
664+
#: ports/cxd56/common-hal/sdioio/SDCard.c
665+
#: ports/espressif/common-hal/sdioio/SDCard.c
668666
#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c
669-
msgid "Buffer must be a multiple of 512 bytes"
667+
#: shared-module/sdcardio/SDCard.c
668+
#, c-format
669+
msgid "Buffer must be a multiple of %d bytes"
670670
msgstr ""
671671

672672
#: shared-bindings/_bleio/PacketBuffer.c
@@ -1183,11 +1183,13 @@ msgstr ""
11831183
msgid "Interrupted by output function"
11841184
msgstr ""
11851185

1186+
#: ports/espressif/common-hal/_bleio/Service.c
11861187
#: ports/espressif/common-hal/espulp/ULP.c
11871188
#: ports/espressif/common-hal/microcontroller/Processor.c
11881189
#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c
11891190
#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c
11901191
#: ports/raspberrypi/bindings/picodvi/Framebuffer.c
1192+
#: ports/raspberrypi/bindings/rp2pio/StateMachine.c
11911193
#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c
11921194
#: shared-bindings/digitalio/DigitalInOut.c
11931195
#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c
@@ -1307,6 +1309,7 @@ msgid "MAC address was invalid"
13071309
msgstr ""
13081310

13091311
#: ports/espressif/common-hal/_bleio/Characteristic.c
1312+
#: ports/espressif/common-hal/_bleio/Descriptor.c
13101313
msgid "MITM security not supported"
13111314
msgstr ""
13121315

@@ -1869,6 +1872,19 @@ msgstr ""
18691872
msgid "SDIO Init Error %d"
18701873
msgstr ""
18711874

1875+
#: ports/espressif/common-hal/sdioio/SDCard.c
1876+
#, c-format
1877+
msgid "SDIO Init Error %x"
1878+
msgstr ""
1879+
1880+
#: ports/espressif/common-hal/sdioio/SDCard.c
1881+
msgid "SDIO: cards have either 1 or 4 data lines"
1882+
msgstr ""
1883+
1884+
#: ports/espressif/common-hal/sdioio/SDCard.c
1885+
msgid "SDIO: requested frequency out of range"
1886+
msgstr ""
1887+
18721888
#: ports/espressif/common-hal/busio/SPI.c
18731889
msgid "SPI configuration failed"
18741890
msgstr ""
@@ -2242,14 +2258,12 @@ msgid "Update failed"
22422258
msgstr ""
22432259

22442260
#: ports/espressif/common-hal/_bleio/Characteristic.c
2245-
#: ports/espressif/common-hal/_bleio/Descriptor.c
22462261
#: ports/nordic/common-hal/_bleio/Characteristic.c
22472262
#: ports/nordic/common-hal/_bleio/Descriptor.c
22482263
msgid "Value length != required fixed length"
22492264
msgstr ""
22502265

22512266
#: ports/espressif/common-hal/_bleio/Characteristic.c
2252-
#: ports/espressif/common-hal/_bleio/Descriptor.c
22532267
#: ports/nordic/common-hal/_bleio/Characteristic.c
22542268
#: ports/nordic/common-hal/_bleio/Descriptor.c
22552269
msgid "Value length > max_length"
@@ -3098,7 +3112,8 @@ msgstr ""
30983112
msgid "function missing required positional argument #%d"
30993113
msgstr ""
31003114

3101-
#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/time/__init__.c
3115+
#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c
3116+
#: shared-bindings/time/__init__.c
31023117
#, c-format
31033118
msgid "function takes %d positional arguments but %d were given"
31043119
msgstr ""
@@ -3250,7 +3265,7 @@ msgstr ""
32503265
msgid "input must be a dense ndarray"
32513266
msgstr ""
32523267

3253-
#: extmod/ulab/code/user/user.c
3268+
#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c
32543269
msgid "input must be an ndarray"
32553270
msgstr ""
32563271

ports/atmel-samd/common-hal/sdioio/SDCard.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ static void check_for_deinit(sdioio_sdcard_obj_t *self) {
153153

154154
static void check_whole_block(mp_buffer_info_t *bufinfo) {
155155
if (bufinfo->len % 512) {
156-
mp_raise_ValueError(MP_ERROR_TEXT("Buffer length must be a multiple of 512"));
156+
mp_raise_ValueError_varg(MP_ERROR_TEXT("Buffer must be a multiple of %d bytes"), 512);
157157
}
158158
}
159159

ports/cxd56/common-hal/sdioio/SDCard.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t *self) {
9191

9292
static void check_whole_block(mp_buffer_info_t *bufinfo) {
9393
if (bufinfo->len % 512) {
94-
mp_raise_ValueError(MP_ERROR_TEXT("Buffer length must be a multiple of 512"));
94+
mp_raise_ValueError_varg(MP_ERROR_TEXT("Buffer must be a multiple of %d bytes"), 512);
9595
}
9696
}
9797

ports/espressif/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16)
55
set(ENV{IDF_PATH} ${CMAKE_SOURCE_DIR}/esp-idf)
66

77
# The component list here determines what options we get in menuconfig and what the ninja file can build.
8-
set(COMPONENTS bt driver esp_driver_dac esp_driver_gpio esp_driver_gptimer esp_driver_i2s esp_driver_ledc esp_driver_pcnt esp_driver_rmt esp_driver_spi esp_driver_tsens esp_driver_uart esp-tls esp_adc_cal esp_event esp_netif esp_psram esp_wifi esptool_py freertos log lwip main mbedtls mdns soc ulp usb wpa_supplicant esp-camera esp_lcd vfs esp_vfs_console)
8+
set(COMPONENTS bt driver esp_driver_dac esp_driver_gpio esp_driver_gptimer esp_driver_i2s esp_driver_ledc esp_driver_pcnt esp_driver_rmt esp_driver_spi esp_driver_tsens esp_driver_uart esp-tls esp_adc_cal esp_event esp_netif esp_psram esp_wifi esptool_py freertos log lwip main mbedtls mdns soc ulp usb wpa_supplicant esp-camera esp_lcd vfs esp_vfs_console sdmmc)
99
set(EXTRA_COMPONENT_DIRS "esp-protocols/components/mdns" "esp-camera")
1010

1111
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

ports/espressif/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ INC += \
8787
-isystem esp-idf/components/esp_driver_ledc/include \
8888
-isystem esp-idf/components/esp_driver_pcnt/include \
8989
-isystem esp-idf/components/esp_driver_rmt/include \
90+
-isystem esp-idf/components/esp_driver_sdio/include \
91+
-isystem esp-idf/components/esp_driver_sdmmc/include \
9092
-isystem esp-idf/components/esp_driver_spi/include \
9193
-isystem esp-idf/components/esp_driver_tsens/include \
9294
-isystem esp-idf/components/esp_driver_uart/include \
@@ -128,6 +130,8 @@ INC += \
128130
-isystem esp-idf/components/mbedtls/port/include \
129131
-isystem esp-idf/components/newlib/platform_include \
130132
-isystem esp-idf/components/nvs_flash/include \
133+
-isystem esp-idf/components/sdio/include \
134+
-isystem esp-idf/components/sdmmc/include \
131135
-isystem esp-idf/components/soc/include \
132136
-isystem esp-idf/components/soc/$(IDF_TARGET)/include \
133137
-isystem esp-idf/components/spi_flash/include \
@@ -660,6 +664,9 @@ endif
660664
ifneq ($(CIRCUITPY_USB_DEVICE),0)
661665
ESP_IDF_COMPONENTS_LINK += usb
662666
endif
667+
ifneq ($(CIRCUITPY_SDIOIO),0)
668+
ESP_IDF_COMPONENTS_LINK += sdmmc esp_driver_sdmmc
669+
endif
663670

664671
ESP_IDF_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/$(component)/lib$(component).a)
665672

ports/espressif/boards/makerfabs_tft7/mpconfigboard.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m
1515

1616
CIRCUITPY_DOTCLOCKFRAMEBUFFER = 1
1717

18+
CIRCUITPY_SDIOIO = 1
19+
1820
# To build with USB disabled allowing access to I2S pins
1921
#CIRCUITPY_CREATOR_ID = 0x1A000000
2022
#CIRCUITPY_CREATION_ID = 0x005381BF

ports/espressif/boards/makerfabs_tft7/pins.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,9 @@ static const mp_rom_map_elem_t board_module_globals_table[] = {
121121

122122
// IO10 <> SD_CS is cut at factory (non-placed resistor position R34) and pulled up.
123123
// Permanent SDIO 1-bit mode?
124-
// Until SDIO 1-bit mode is support on Espressif ports these pins aren't useful
125-
// { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_GPIO11) },
126-
// { MP_ROM_QSTR(MP_QSTR_SDIO_D0), MP_ROM_PTR(&pin_GPIO13) },
127-
// { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO12) },
124+
{ MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_GPIO11) },
125+
{ MP_ROM_QSTR(MP_QSTR_SDIO_D0), MP_ROM_PTR(&pin_GPIO13) },
126+
{ MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO12) },
128127

129128
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) },
130129

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2024 Jacob Rigby
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#include <stdbool.h>
8+
#include "esp_err.h"
9+
10+
//#include "ports/espressif/esp-idf/components/esp_driver_sdmmc/include/driver/sdmmc_host.h"
11+
#include "driver/sdmmc_host.h"
12+
#include "ports/espressif/esp-idf/components/sdmmc/include/sdmmc_cmd.h"
13+
14+
#include "shared-bindings/microcontroller/Pin.h"
15+
#include "shared-bindings/util.h"
16+
#include "shared-bindings/sdioio/SDCard.h"
17+
#include "py/mperrno.h"
18+
#include "py/runtime.h"
19+
20+
#include "esp_log.h"
21+
static const char *TAG = "SDCard.c";
22+
23+
static bool sdio_host_init = false;
24+
25+
static void common_hal_sdioio_sdcard_check_for_deinit(sdioio_sdcard_obj_t *self) {
26+
if (common_hal_sdioio_sdcard_deinited(self)) {
27+
raise_deinited_error();
28+
}
29+
}
30+
31+
static int check_pins(const mcu_pin_obj_t *clock, const mcu_pin_obj_t *command, const uint8_t num_data, const mcu_pin_obj_t **data) {
32+
if (CONFIG_SOC_SDMMC_USE_GPIO_MATRIX) {
33+
// ESP32-S3 and P4 can use any pin for any SDMMC func in either slot
34+
// Default to SLOT_1 for SD cards
35+
ESP_LOGI(TAG, "Using chip with CONFIG_SOC_SDMMC_USE_GPIO_MATRIX");
36+
return SDMMC_HOST_SLOT_1;
37+
}
38+
if (command->number == GPIO_NUM_11 && clock->number == GPIO_NUM_6 && data[0]->number == GPIO_NUM_7) {
39+
// Might be slot 0
40+
if (num_data == 1 || (num_data == 4 && data[1]->number == GPIO_NUM_8 && data[2]->number == GPIO_NUM_9 && data[3]->number == GPIO_NUM_10)) {
41+
return SDMMC_HOST_SLOT_0;
42+
}
43+
} else if (command->number == GPIO_NUM_15 && clock->number == GPIO_NUM_14 && data[0]->number == 2) {
44+
// Might be slot 1
45+
if (num_data == 1 || (num_data == 4 && data[1]->number == GPIO_NUM_4 && data[2]->number == GPIO_NUM_12 && data[3]->number == GPIO_NUM_13)) {
46+
return SDMMC_HOST_SLOT_1;
47+
}
48+
}
49+
return -1;
50+
}
51+
52+
void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self,
53+
const mcu_pin_obj_t *clock, const mcu_pin_obj_t *command,
54+
uint8_t num_data, const mcu_pin_obj_t **data, uint32_t frequency) {
55+
if (num_data != 4 && num_data != 1) {
56+
mp_raise_ValueError(MP_ERROR_TEXT("SDIO: cards have either 1 or 4 data lines"));
57+
}
58+
59+
self->num_data = num_data;
60+
int sd_slot = check_pins(clock, command, num_data, data);
61+
if (sd_slot != SDMMC_HOST_SLOT_0 && sd_slot != SDMMC_HOST_SLOT_1) {
62+
// Bad pin combo
63+
raise_ValueError_invalid_pins();
64+
}
65+
66+
if (frequency > 40000000) {
67+
// Higher than max 40Mhz frequency
68+
mp_raise_ValueError(MP_ERROR_TEXT("SDIO: requested frequency out of range"));
69+
}
70+
71+
ESP_LOGI(TAG, "Using slot %d", sd_slot);
72+
self->slot = (uint8_t)sd_slot;
73+
esp_err_t err = ESP_OK;
74+
75+
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
76+
host.max_freq_khz = frequency / 1000;
77+
78+
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
79+
slot_config.width = 1;
80+
slot_config.clk = clock->number;
81+
claim_pin(clock);
82+
self->clock = clock->number;
83+
slot_config.cmd = command->number;
84+
claim_pin(command);
85+
self->command = command->number;
86+
slot_config.d0 = data[0]->number;
87+
self->data[0] = data[0]->number;
88+
claim_pin(data[0]);
89+
if (num_data == 4) {
90+
slot_config.width = 4;
91+
slot_config.d1 = data[1]->number;
92+
claim_pin(data[1]);
93+
self->data[1] = data[1]->number;
94+
slot_config.d2 = data[2]->number;
95+
claim_pin(data[2]);
96+
self->data[2] = data[2]->number;
97+
slot_config.d3 = data[3]->number;
98+
claim_pin(data[3]);
99+
self->data[3] = data[3]->number;
100+
}
101+
102+
ESP_LOGI(TAG, "slot_config:\nwidth: %d, clk: %d, cmd: %d\nd0: %d, d1: %d, d2: %d, d3: %d",
103+
slot_config.width, slot_config.clk, slot_config.cmd,
104+
slot_config.d0, slot_config.d1, slot_config.d2, slot_config.d3);
105+
106+
if (!sdio_host_init) {
107+
err = sdmmc_host_init();
108+
if (err != ESP_OK) {
109+
mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error %x"), err);
110+
}
111+
// sdio_host_init = true;
112+
}
113+
err = sdmmc_host_init_slot(sd_slot, &slot_config);
114+
if (err != ESP_OK) {
115+
ESP_LOGW(TAG, "Failed to initialize SDMMC slot: %x", err);
116+
mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error %x"), err);
117+
}
118+
// sdmmc_card_t card;
119+
// self->card = malloc(sizeof(sdmmc_card_t));
120+
err = sdmmc_card_init(&host, &self->card);
121+
if (err != ESP_OK) {
122+
ESP_LOGW(TAG, "Failed to initialize SDMMC card: %x", err);
123+
mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error %x"), err);
124+
}
125+
126+
common_hal_sdioio_sdcard_check_for_deinit(self);
127+
128+
ESP_LOGI(TAG, "Initialized SD card with ID %d:%d-%s",
129+
self->card.cid.mfg_id, self->card.cid.oem_id, self->card.cid.name);
130+
131+
ESP_LOGI(TAG, "Number of sectors: %d with sector_size: %d",
132+
self->card.csd.capacity, self->card.csd.sector_size);
133+
134+
self->frequency = self->card.real_freq_khz;
135+
ESP_LOGI(TAG, "Real frequency is %lu", self->frequency);
136+
self->capacity = self->card.csd.capacity; // Reported number of sectors
137+
ESP_LOGI(TAG, "Reported capacity is %lu", self->capacity);
138+
139+
return;
140+
}
141+
142+
uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t *self) {
143+
return self->capacity;
144+
}
145+
146+
uint32_t common_hal_sdioio_sdcard_get_frequency(sdioio_sdcard_obj_t *self) {
147+
return self->frequency;
148+
}
149+
150+
uint8_t common_hal_sdioio_sdcard_get_width(sdioio_sdcard_obj_t *self) {
151+
return self->num_data;
152+
}
153+
154+
static void check_whole_block(mp_buffer_info_t *bufinfo, int sector_size) {
155+
if (bufinfo->len % sector_size) {
156+
mp_raise_ValueError_varg(MP_ERROR_TEXT("Buffer must be a multiple of %d bytes"), sector_size);
157+
}
158+
}
159+
160+
int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
161+
common_hal_sdioio_sdcard_check_for_deinit(self);
162+
check_whole_block(bufinfo, self->card.csd.sector_size);
163+
esp_err_t err;
164+
ESP_LOGI(TAG, "in common_hal_sdioio_sdcard_writeblocks");
165+
// err = sdmmc_io_write_blocks(&self->card, 1, start_block, bufinfo->buf, bufinfo->len);
166+
err = sdmmc_write_sectors(&self->card, bufinfo->buf, start_block, bufinfo->len / self->card.csd.sector_size);
167+
if (err != ESP_OK) {
168+
ESP_LOGW(TAG, "Failed to write blocks with err 0x%X", err);
169+
}
170+
return 0;
171+
}
172+
173+
int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
174+
common_hal_sdioio_sdcard_check_for_deinit(self);
175+
check_whole_block(bufinfo, self->card.csd.sector_size);
176+
esp_err_t err;
177+
ESP_LOGI(TAG, "in common_hal_sdioio_sdcard_readblocks");
178+
// err = sdmmc_io_read_blocks(&self->card, 1, start_block, bufinfo->buf, bufinfo->len);
179+
err = sdmmc_read_sectors(&self->card, bufinfo->buf, start_block, bufinfo->len / self->card.csd.sector_size);
180+
if (err != ESP_OK) {
181+
ESP_LOGW(TAG, "Failed to read blocks with err 0x%X", err);
182+
}
183+
return 0;
184+
}
185+
186+
bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) {
187+
return true;
188+
}
189+
190+
bool common_hal_sdioio_sdcard_deinited(sdioio_sdcard_obj_t *self) {
191+
return self->command == COMMON_HAL_MCU_NO_PIN;
192+
}
193+
194+
void common_hal_sdioio_sdcard_deinit(sdioio_sdcard_obj_t *self) {
195+
if (common_hal_sdioio_sdcard_deinited(self)) {
196+
return;
197+
}
198+
sdmmc_host_deinit();
199+
reset_pin_number(self->command);
200+
self->command = COMMON_HAL_MCU_NO_PIN;
201+
reset_pin_number(self->clock);
202+
self->clock = COMMON_HAL_MCU_NO_PIN;
203+
reset_pin_number(self->data[0]);
204+
self->data[0] = COMMON_HAL_MCU_NO_PIN;
205+
if (self->num_data == 4) {
206+
reset_pin_number(self->data[1]);
207+
self->data[1] = COMMON_HAL_MCU_NO_PIN;
208+
reset_pin_number(self->data[2]);
209+
self->data[2] = COMMON_HAL_MCU_NO_PIN;
210+
reset_pin_number(self->data[3]);
211+
self->data[3] = COMMON_HAL_MCU_NO_PIN;
212+
}
213+
return;
214+
}
215+
216+
void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self) {
217+
if (common_hal_sdioio_sdcard_deinited(self)) {
218+
return;
219+
}
220+
}
221+
222+
void sdioio_reset() {
223+
return;
224+
}

0 commit comments

Comments
 (0)