Skip to content

Commit 6c3fbf7

Browse files
committed
_sdcardio.SDIOSDCard: implement for STM32F405 Feather
This is hard coded to the bus specs of the Feather.
1 parent 8fccc76 commit 6c3fbf7

File tree

26 files changed

+747
-1
lines changed

26 files changed

+747
-1
lines changed

ports/atmel-samd/common-hal/_sdcardio/SDIOSDCard.c

Whitespace-only changes.

ports/atmel-samd/common-hal/_sdcardio/SDIOSDCard.h

Whitespace-only changes.

ports/cxd56/common-hal/_sdcardio/SDIOSDCard.c

Whitespace-only changes.

ports/cxd56/common-hal/_sdcardio/SDIOSDCard.h

Whitespace-only changes.

ports/esp32s2/common-hal/_sdcardio/SDIOSDCard.c

Whitespace-only changes.

ports/esp32s2/common-hal/_sdcardio/SDIOSDCard.h

Whitespace-only changes.

ports/litex/common-hal/_sdcardio/SDIOSDCard.c

Whitespace-only changes.

ports/litex/common-hal/_sdcardio/SDIOSDCard.h

Whitespace-only changes.

ports/mimxrt10xx/common-hal/_sdcardio/SDIOSDCard.c

Whitespace-only changes.

ports/mimxrt10xx/common-hal/_sdcardio/SDIOSDCard.h

Whitespace-only changes.

ports/nrf/common-hal/_sdcardio/SDIOSDCard.c

Whitespace-only changes.

ports/nrf/common-hal/_sdcardio/SDIOSDCard.h

Whitespace-only changes.

ports/stm/boards/feather_stm32f405_express/pins.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
1+
#include "py/objtuple.h"
12
#include "shared-bindings/board/__init__.h"
23

4+
STATIC const mp_rom_obj_tuple_t sdio_data_tuple = {
5+
{&mp_type_tuple},
6+
4,
7+
{
8+
MP_ROM_PTR(&pin_PC08),
9+
MP_ROM_PTR(&pin_PC09),
10+
MP_ROM_PTR(&pin_PC10),
11+
MP_ROM_PTR(&pin_PC11),
12+
}
13+
};
14+
315
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
416
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA04) },
517
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
@@ -31,5 +43,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
3143
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
3244
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
3345
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
46+
47+
{ MP_ROM_QSTR(MP_QSTR_SDIO_CLOCK), MP_ROM_PTR(&pin_PC11) },
48+
{ MP_ROM_QSTR(MP_QSTR_SDIO_COMMAND), MP_ROM_PTR(&pin_PD02) },
49+
{ MP_ROM_QSTR(MP_QSTR_SDIO_DATA), MP_ROM_PTR(&sdio_data_tuple) },
3450
};
3551
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
#include <stdbool.h>
27+
28+
#include "shared-bindings/_sdcardio/SDIOSDCard.h"
29+
#include "py/mperrno.h"
30+
#include "py/runtime.h"
31+
32+
#include "shared-bindings/microcontroller/__init__.h"
33+
#include "boards/board.h"
34+
#include "supervisor/shared/translate.h"
35+
#include "common-hal/microcontroller/Pin.h"
36+
37+
#ifndef DEBUG_SDIO
38+
#define DEBUG_SDIO (0)
39+
#endif
40+
41+
#if DEBUG_SDIO
42+
#define DEBUG_PRINT(...) ((void)mp_printf(&mp_plat_print, __VA_ARGS__))
43+
#else
44+
#define DEBUG_PRINT(...) ((void)0)
45+
#endif
46+
47+
void common_hal_sdcardio_sdio_construct(sdcardio_sdiosdcard_obj_t *self,
48+
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * command,
49+
uint8_t num_data, mcu_pin_obj_t ** data, uint32_t frequency) {
50+
// constructor arguments are ignored, and the hard-wired SD slot on the board is used.
51+
52+
GPIO_InitTypeDef GPIO_InitStruct;
53+
54+
// /* GPIOC and GPIOD Periph clock enable */
55+
// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | SD_DETECT_GPIO_CLK, ENABLE);
56+
57+
/* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */
58+
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11;
59+
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
60+
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
61+
GPIO_InitStruct.Pull = GPIO_PULLUP;
62+
GPIO_InitStruct.Alternate = 12; // is there an identifier for this?
63+
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
64+
65+
/* Configure PD.02 CMD line */
66+
GPIO_InitStruct.Pin = GPIO_PIN_2;
67+
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
68+
69+
/* Configure PC.12 pin: CLK pin */
70+
GPIO_InitStruct.Pin = GPIO_PIN_12;
71+
GPIO_InitStruct.Pull = GPIO_NOPULL;
72+
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
73+
74+
#define SD_DETECT_PIN GPIO_PIN_12
75+
#define SD_DETECT_GPIO_PORT GPIOB
76+
77+
/*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */
78+
GPIO_InitStruct.Pin = SD_DETECT_PIN;
79+
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
80+
GPIO_InitStruct.Pull = GPIO_PULLUP;
81+
HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStruct);
82+
83+
__HAL_RCC_SDIO_CLK_ENABLE();
84+
85+
self->handle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;
86+
self->handle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
87+
self->handle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
88+
self->handle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
89+
self->handle.Init.BusWide = SDIO_BUS_WIDE_1B;
90+
self->handle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
91+
self->handle.Instance = SDIO;
92+
93+
HAL_StatusTypeDef r = HAL_SD_Init(&self->handle);
94+
if (r != HAL_OK) {
95+
mp_raise_ValueError_varg(translate("SDIO Init Error %d"), (int)r);
96+
}
97+
98+
HAL_SD_CardInfoTypeDef info;
99+
r = HAL_SD_GetCardInfo(&self->handle, &info);
100+
if (r != HAL_OK) {
101+
mp_raise_ValueError_varg(translate("SDIO GetCardInfo Error %d"), (int)r);
102+
}
103+
104+
if ((r = HAL_SD_ConfigWideBusOperation(&self->handle, SDIO_BUS_WIDE_4B)) == HAL_SD_ERROR_NONE) {
105+
DEBUG_PRINT("Switched bus to 4B mode\n");
106+
self->handle.Init.BusWide = SDIO_BUS_WIDE_4B;
107+
self->width = 4;
108+
} else {
109+
DEBUG_PRINT("WideBus_Enable returned %r, leaving at 1B mode\n", (int)r);
110+
self->width = 1;
111+
}
112+
113+
self->capacity = info.BlockNbr * (info.BlockSize / 512);
114+
self->frequency = 25000000;
115+
116+
return;
117+
}
118+
119+
uint32_t common_hal_sdcardio_sdio_get_count(sdcardio_sdiosdcard_obj_t *self) {
120+
return self->capacity;
121+
}
122+
123+
uint32_t common_hal_sdcardio_sdio_get_frequency(sdcardio_sdiosdcard_obj_t *self) {
124+
return self->frequency; // self->frequency;
125+
}
126+
127+
uint8_t common_hal_sdcardio_sdio_get_width(sdcardio_sdiosdcard_obj_t *self) {
128+
return self->width; // self->width;
129+
}
130+
131+
STATIC void check_for_deinit(sdcardio_sdiosdcard_obj_t *self) {
132+
}
133+
134+
STATIC void check_whole_block(mp_buffer_info_t *bufinfo) {
135+
if (bufinfo->len % 512) {
136+
mp_raise_ValueError(translate("Buffer must be a multiple of 512 bytes"));
137+
}
138+
}
139+
140+
STATIC void wait_write_complete(sdcardio_sdiosdcard_obj_t *self) {
141+
if (self->state_programming) {
142+
HAL_SD_CardStateTypedef st = HAL_SD_CARD_PROGRAMMING;
143+
for (int i=0; i < 50000 && st == HAL_SD_CARD_PROGRAMMING; i++) {
144+
st = HAL_SD_GetCardState(&self->handle);
145+
HAL_Delay(10);
146+
};
147+
self->state_programming = false;
148+
}
149+
}
150+
151+
STATIC void debug_print_state(sdcardio_sdiosdcard_obj_t *self, const char *what) {
152+
#if DEBUG_SDIO
153+
HAL_SD_CardStateTypedef st = HAL_SD_GetCardState(&self->handle);
154+
DEBUG_PRINT("%s, st=0x%x State=0x%x ErrorCode=0x%x\n", what, (int)st, self->handle.State, self->handle.ErrorCode);
155+
#endif
156+
}
157+
158+
int common_hal_sdcardio_sdio_writeblocks(sdcardio_sdiosdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
159+
check_for_deinit(self);
160+
check_whole_block(bufinfo);
161+
wait_write_complete(self);
162+
self->state_programming = true;
163+
common_hal_mcu_disable_interrupts();
164+
HAL_StatusTypeDef r = HAL_SD_WriteBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, 1000);
165+
common_hal_mcu_enable_interrupts();
166+
if (r != HAL_OK) {
167+
debug_print_state(self, "after writeblocks error");
168+
return -EIO;
169+
}
170+
// debug_print_state(self, "after writeblocks OK");
171+
// debug_print_state(self, "after writeblocks complete");
172+
return 0;
173+
}
174+
175+
int common_hal_sdcardio_sdio_readblocks(sdcardio_sdiosdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
176+
check_for_deinit(self);
177+
check_whole_block(bufinfo);
178+
wait_write_complete(self);
179+
common_hal_mcu_disable_interrupts();
180+
HAL_StatusTypeDef r = HAL_SD_ReadBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, 1000);
181+
common_hal_mcu_enable_interrupts();
182+
if (r != HAL_OK) {
183+
debug_print_state(self, "after readblocks error");
184+
return -EIO;
185+
}
186+
return 0;
187+
}
188+
189+
bool common_hal_sdcardio_sdio_configure(sdcardio_sdiosdcard_obj_t *self, uint32_t frequency, uint8_t bits) {
190+
check_for_deinit(self);
191+
return true;
192+
}
193+
194+
bool common_hal_sdcardio_sdio_deinited(sdcardio_sdiosdcard_obj_t *self) {
195+
return false;
196+
}
197+
198+
void common_hal_sdcardio_sdio_deinit(sdcardio_sdiosdcard_obj_t *self) {
199+
}
200+
201+
void common_hal_sdcardio_sdio_never_reset(sdcardio_sdiosdcard_obj_t *self) {
202+
}
203+
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Scott Shawcroft
7+
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_BUSIO_SDIO_H
29+
#define MICROPY_INCLUDED_STM32_COMMON_HAL_BUSIO_SDIO_H
30+
31+
#include "common-hal/microcontroller/Pin.h"
32+
33+
#include "peripherals/periph.h"
34+
35+
#include "py/obj.h"
36+
37+
typedef struct {
38+
mp_obj_base_t base;
39+
SD_HandleTypeDef handle;
40+
bool has_lock;
41+
const mcu_periph_obj_t *cmd;
42+
const mcu_periph_obj_t *clock;
43+
const mcu_periph_obj_t *data[8];
44+
uint32_t frequency;
45+
uint8_t num_data:3, width:3, state_programming:1;
46+
uint32_t capacity;
47+
} sdcardio_sdiosdcard_obj_t;
48+
49+
void sdio_reset(void);
50+
51+
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_BUSIO_SDIO_H
52+

ports/stm/mpconfigport.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ USB_SERIAL_NUMBER_LENGTH = 24
66
ifeq ($(MCU_VARIANT),STM32F405xx)
77
CIRCUITPY_FRAMEBUFFERIO = 1
88
CIRCUITPY_RGBMATRIX = 1
9+
CIRCUITPY_SDCARDIO = 1
10+
CIRCUITPY_SDCARDIO_SDIO = 1
911
endif
1012

1113
ifeq ($(MCU_SERIES),F4)

ports/stm/supervisor/port.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,18 @@ void _init(void)
454454

455455
}
456456

457+
void HAL_Delay(uint32_t delay) {
458+
if (delay > 1000) {
459+
mp_hal_delay_ms(delay / 1000);
460+
delay %= 1000;
461+
}
462+
mp_hal_delay_us(delay);
463+
}
464+
465+
#if 0
466+
uint32_t HAL_GetTick() {
467+
uint8_t subticks;
468+
uint32_t result = (uint32_t)port_get_raw_ticks(&subticks);
469+
return (result * 1000) + (subticks * 1000 / 32);
470+
}
471+
#endif

ports/unix/common-hal/_sdcardio/SDIOSDCard.c

Whitespace-only changes.

ports/unix/common-hal/_sdcardio/SDIOSDCard.h

Whitespace-only changes.

py/circuitpy_defns.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ SRC_COMMON_HAL_ALL = \
302302
rotaryio/__init__.c \
303303
rtc/RTC.c \
304304
rtc/__init__.c \
305+
_sdcardio/SDIOSDCard.c \
305306
supervisor/Runtime.c \
306307
supervisor/__init__.c
307308

py/circuitpy_mpconfig.mk

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD)
8585
CIRCUITPY_BUSIO ?= 1
8686
CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO)
8787

88+
CIRCUITPY_BUSIO_SDIO ?= 0
89+
CFLAGS += -DCIRCUITPY_BUSIO_SDIO=$(CIRCUITPY_BUSIO_SDIO)
90+
8891
CIRCUITPY_DIGITALIO ?= 1
8992
CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO)
9093

@@ -166,6 +169,9 @@ CFLAGS += -DCIRCUITPY_SAMD=$(CIRCUITPY_SAMD)
166169
CIRCUITPY_SDCARDIO ?= $(CIRCUITPY_FULL_BUILD)
167170
CFLAGS += -DCIRCUITPY_SDCARDIO=$(CIRCUITPY_SDCARDIO)
168171

172+
CIRCUITPY_SDCARDIO_SDIO ?= 0
173+
CFLAGS += -DCIRCUITPY_SDCARDIO_SDIO=$(CIRCUITPY_SDCARDIO_SDIO)
174+
169175
# Currently always off.
170176
CIRCUITPY_STAGE ?= 0
171177
CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE)

0 commit comments

Comments
 (0)