Hacking an SD-Card to Micro Python on STM32F4-Discovery

Some time ago, I wrote about how to install the amazin Micro Python on the STM32F4-Discovery. While this works very well, one might easily come to the point where the internal flash memory of the STM32 will be not enough. I guess, this is why the Micro Python board comes with an micro SD card slot. On the STM32F4 there is no such slot, and Micro Python does not enable SD card support for this board by default. But this could easily be changed by using an Micro SD to SD card adapter which could be connected to the STM32.

STM32 with SD Card

STM32 with SD Card

Btw.: Mirco Python accesses the SD Card through SDIO in 4-Bit mode which makes the access pretty fast …

Patch the Micro Python Sources

In general, build Micro Python for the STM32F4-Discovery as already described in this article. But since the original sources have no SD enabled for the STM, before compiling the following changes need to be made to the Micro Python source code:

To enable SD card support, and specify SD card detection switch, edit stmhal/boards/STM32F4DISC/mpconfigboard.h like this:

#define STM32F4DISC

#define MICROPY_HW_BOARD_NAME       "F4DISC"
#define MICROPY_HW_MCU_NAME         "STM32F407"

#define MICROPY_HW_HAS_SWITCH       (1)
#define MICROPY_HW_HAS_SDCARD       (1)
#define MICROPY_HW_HAS_MMA7660      (0)
#define MICROPY_HW_HAS_LIS3DSH      (1)
#define MICROPY_HW_HAS_LCD          (0)
#define MICROPY_HW_ENABLE_RNG       (1)
#define MICROPY_HW_ENABLE_RTC       (1)
#define MICROPY_HW_ENABLE_TIMER     (1)
#define MICROPY_HW_ENABLE_SERVO     (0)
#define MICROPY_HW_ENABLE_DAC       (0)
#define MICROPY_HW_ENABLE_I2C1      (1)
#define MICROPY_HW_ENABLE_SPI1      (1)
#define MICROPY_HW_ENABLE_SPI3      (0)
#define MICROPY_HW_ENABLE_CC3K      (0)

// USRSW is pulled low. Pressing the button makes the input go high.
#define MICROPY_HW_USRSW_PIN        (pin_A0)
#define MICROPY_HW_USRSW_PULL       (GPIO_NOPULL)
#define MICROPY_HW_USRSW_EXTI_MODE  (GPIO_MODE_IT_RISING)
#define MICROPY_HW_USRSW_PRESSED    (1)

// LEDs
#define MICROPY_HW_LED1             (pin_D14) // red
#define MICROPY_HW_LED2             (pin_D12) // green
#define MICROPY_HW_LED3             (pin_D13) // orange
#define MICROPY_HW_LED4             (pin_D15) // blue
#define MICROPY_HW_LED_OTYPE        (GPIO_MODE_OUTPUT_PP)
#define MICROPY_HW_LED_ON(pin)      (pin->gpio->BSRRL = pin->pin_mask)
#define MICROPY_HW_LED_OFF(pin)     (pin->gpio->BSRRH = pin->pin_mask)

// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN        (pin_A8)
#define MICROPY_HW_SDCARD_DETECT_PULL       (GPIO_PULLUP)
#define MICROPY_HW_SDCARD_DETECT_PRESENT    (GPIO_PIN_RESET)

Wiring the SD-Card to the STM32F4-Discovery

The SD card and the STM need to be wired as follows:

SD-Card       STM32F4-Discovery
-------------------------------
1 SDIO_D3     PC11
2 SDIO_CMD    PD2
3 VSS         GND
4 VDD         3V
5 SDIO_CLK    PC12
6 SDIO_SW     PA8
7 SDIO_D0     PC8
8 SDIO_D1     PC9
9 SDIO_D2     PC10

The pins on a SD card are numbered like this:

 ___________________
/   1 2 3 4 5 6 7 8 |
| 9                 |
|                   |

Note: PC10/PC12 are also connected to the CS43L22,but this seams not to be a problem as long as you don’t use both: SD and CS43L22. Also it is suggested to use some pull-ups (47k) on SDIO_CMD, SDIO_D0, SDIO_D1, SDIO_D2, SDIO_D3, but I decided not to care :-).

Prepare the SD Card

Not much to do here, Just make sure to format the SD card to use with FAT-FS. On Linux, this is done like so (instead of sdc1 use the partition of your SD card!!):

mkfs.fat /dev/sdc1

Use the SD Card

Now, with the new SD card attached, reset the STM32 Micro Python board. After some time, the SD card should show up on your Linux as a empty new drive (e.g. as 4.0 GB Volume). Next, let’s connect to the Python shell on the board (e.g. by „screen /dev/ttyACM0 115200“) and see if we could access the card.

Note: the Micro Python web page states, that if a SD card is present, booting will be done from this card. However, it seams that on the STM32 booting is still done from internal flash, but the SD card is accessible anyway.

First, lets write a file to the SD card. In Micro Python, the internal Flash has the paht „0:/“ and the SD card has „1:/“. Knowing this, it is pretty simple to write „Hello World“ into a file on the card:

f = open("1:/hello.txt", "w")
f.write("Hello World from Micro Python")
f.close()

After a reset, the new file „hello.txt“ should be shown on the SD card under Linux.

Ok, this is all fine, but how about storing and loading Python modules on the SD card? From Linux, let’s put the following sample (named „blink.py“) to the SD card:

import pyb

leds = [pyb.LED(i) for i in range(1,5)]
for l in leds: 
    l.off()

n = 0
try:
   while True:
      n = (n + 1) % 4
      leds[n].toggle()
      pyb.delay(50)
finally:
    for l in leds:
        l.off()

Reset Micro Python with „Ctrl-D“, and try the following:

import blink

Which will end in an erro:

Traceback (most recent call last):
  File "", line 0, in 
ImportError: No module named 'blink'

This is because Python is only searching „0:\“ and „0:\lib“ for modules by default. We could easily fix this by doing the following:

import sys 
sys.path.append("1:/")
import blink

It might be a good idea to put the above into „main.py“ on the internal flash …

Leave a Reply

You must be logged in to post a comment.