[NUCLEO-L476RG] Configure SDMMC peripheral

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
vinz-uts
Posts: 22
Joined: Fri Sep 10, 2021 9:22 am

[NUCLEO-L476RG] Configure SDMMC peripheral

Post by vinz-uts » Fri Sep 10, 2021 9:42 am

Hi All,
I'm using a STM32 NUCLEO-L476RG board with an external SDCARD shield (that is wired using only CMD, CLK and D0 pins). I've tested this configuration using STM32CubeIDE and C programming (without using micropython) and it works. Next I've cloned micropython from git repo and I've compiled it as it's write in the ports/stm32/readme.md file, and all works fine (REPL, import modules, etc.). Now I'm trying to enable SDMMC periph that it's wired to the external SD shield but I don't understand how I can configure it, I've tried to add the lines:

Code: Select all

#define MICROPY_HW_ENABLE_SDCARD (1)
#define MICROPY_HW_SDCARD_SDMMC (1)

// SD card detect switch
#define MICROPY_HW_SDMMC_D0                 (pin_C8)
#define MICROPY_HW_SDMMC_D1                 (pin_C9)
#define MICROPY_HW_SDMMC_D2                 (pin_C10)
#define MICROPY_HW_SDMMC_D3                 (pin_C11)
#define MICROPY_HW_SDMMC_CK                 (pin_C12)
#define MICROPY_HW_SDMMC_CMD                (pin_D2)
in the mpconfigboard.h in boards/NUCLEO_L476RG folder, but when the board runs, it waits long time (I think it tries to mount the SD Card) and the message MPY: can't mount SD card is shown before starting the REPL:

Code: Select all

MPY: sync filesystems
MPY: soft reboot
MPY: can't mount SD card
MicroPython v1.17-8-gbbbdef4cc-dirty on 2021-09-09; NUCLEO-L476RG with STM32L476RG
Type "help()" for more information.
>>>
I also obtain a OSError: [Errno 19] ENODEV if I try to use the os module to mount a pyb.SDCard object. Can anyone help me to understand how what steps I've to follow to enable the SDMMC peripheral on micropython? Thanks for your support...

JohnieBraaf
Posts: 9
Joined: Mon Jan 06, 2020 12:08 am

Re: [NUCLEO-L476RG] Configure SDMMC peripheral

Post by JohnieBraaf » Sat Sep 11, 2021 9:46 pm

You probably need to define the detect pin on a gpio of your choice.

Code: Select all

>>> import pyb
>>> import os
>>> pyb.SDCard().present()
False
>>> from machine import Pin
>>> sd_sw = Pin(pyb.Pin.board.SD_SW, Pin.OUT)
>>> sd_sw.value()
0
>>> pyb.SDCard().present()
True
>>> sd_sw.value(1)
>>> pyb.SDCard().present()
False
>>> sd_sw.value(0)
>>> pyb.SDCard().present()
True
>>> os.mount(pyb.SDCard(), '/sd')
>>> os.listdir('/sd')
['bmp.py']
See here for more info https://github.com/koendv/micropython/t ... _STM32H743

vinz-uts
Posts: 22
Joined: Fri Sep 10, 2021 9:22 am

Re: [NUCLEO-L476RG] Configure SDMMC peripheral

Post by vinz-uts » Mon Sep 13, 2021 8:36 am

Hi, thanks for your reply. I've tried to do what you suggest. When I start to check if SD is present, the result is already True, but the SD isn't monuted.

Code: Select all

>>> import pyb
>>> import os
>>> pyb.SDCard().present()
True
>>> from machine import Pin
pyb.SDCard().present()
True
>>> sd_sw = Pin(pyb.Pin.board.SD_SW, Pin.OUT)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'board' has no attribute 'SD_SW'
>>> sd_sw = Pin(pyb.Pin.board.SW, Pin.OUT)
>>> sd_sw.value()
0
>>> pyb.SDCard().present()
True
>>> os.mount(pyb.SDCard(),'/sd')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 19] ENODEV
The 'SD_SW' pin is not defined in the pyb.Pin.board, is maybe 'SW' for NUCLEO-L476RG board?
Is correct my configuration in 'mpconfigboard.h'?

Code: Select all

#define MICROPY_HW_ENABLE_SDCARD    (1)
#define MICROPY_HW_SDCARD_SDMMC		(1)

#define MICROPY_HW_SDMMC_D0                 (pin_C8)
#define MICROPY_HW_SDMMC_D1                 (pin_C9)
#define MICROPY_HW_SDMMC_D2                 (pin_C10)
#define MICROPY_HW_SDMMC_D3                 (pin_C11)
#define MICROPY_HW_SDMMC_CK                 (pin_C12)
#define MICROPY_HW_SDMMC_CMD                (pin_D2)
I've not defined the MICROPY_HW_SDCARD_DETECT_PIN, MICROPY_HW_SDCARD_DETECT_PULL, MICROPY_HW_SDCARD_DETECT_PRESENT pins because my shield doesn't use it (I neither use the D1,D2,D3 pins but they are defined, I think this is not a problem).

@edit
From micropython/ports/stm32/sdcard.c:

Code: Select all

bool sdcard_is_present(void) {
    #if MICROPY_HW_ENABLE_MMCARD
    if (pyb_sdmmc_flags & PYB_SDMMC_FLAG_MMC) {
        return false;
    }
    #endif
    #if defined(MICROPY_HW_SDCARD_DETECT_PIN)
    return HAL_GPIO_ReadPin(MICROPY_HW_SDCARD_DETECT_PIN->gpio, MICROPY_HW_SDCARD_DETECT_PIN->pin_mask) == MICROPY_HW_SDCARD_DETECT_PRESENT;
    #else
    return true;
    #endif
}
So, I think that is right that the pyb.SDCard().present() already return True if MICROPY_HW_SDCARD_DETECT_PIN is not defined.

vinz-uts
Posts: 22
Joined: Fri Sep 10, 2021 9:22 am

Re: [NUCLEO-L476RG] Configure SDMMC peripheral

Post by vinz-uts » Fri Sep 17, 2021 10:13 am

I found the problem, then the solution. From default the pyb.SDCard class uses 4 Pin to communicate with the SD Card Reader. I had not defined the #define MICROPY_HW_SDCARD_BUS_WIDTH (1) in mpconfigboard.h, and analyzing the sdcard.c file in stm32 folder I thought that from default it's used bus width to 1. On the contrary in the mpconfigboard_common.h file the bus width is defined from default to 4 if MICROPY_HW_SDCARD_BUS_WIDTH was not defined. So it's required to define #define MICROPY_HW_SDCARD_BUS_WIDTH (1) in mpconfigboard.h, so it works.
Thanks all for previous support!

Post Reply