STM32F4 Discovery, SPI and microSD

Posted on
  • I am trying to get my head around connecting up a microSD card using SPI and wouldn't mind a bit of guidance, especially since I am new to Espruino.

    Some background:

    I am using the following hardware

    1. STM32F4 Discovery board
    2. MikroElektronika STM32F4 Discovery shield
    3. MikroElektronika microSD click board

    which pretty much looks like this:

    I have the microSD click board (bottom left in the image above) in the mikroBUS port 1 on the Discovery shield which translates to the following pinout:

    mikroBUS port 1:
    SD card pin -----------> STM32F4 Pin
    2 (CS) -------------------> B12 (CS)
    3 (DI) -------------------> B15 (SPI2 MOSI)
    5 (SCK) -----------------> B13 (SPI2 SCK)
    7 (DO) ------------------> B14 (SPI2 MISO)

    Goal:

    Is obviously to read from and write to the SD card.

    I found the following conversation on the Espruino forum where @Gordon alludes how to go about using SPI to get this working but I am still a bit lost.

    I see that the filesystem module is only supported on boards with a SD card slot

    @Gordon says in his comment above to, "just stick with normal SPI"

    Getting the SPI setup seems very straight forward:

    SPI2.setup({mosi:B15, miso:B14, sck:B13, baud:?});
    

    SPI setup comments:

    • About the baud rate. Should it be half the clock speed, which is 168 MHz (max)?
    • Where does the chip select pin (CS, B12) come into play?

    Once the SPI is taken care of how does one deal with reading and writing files with normal SPI?

    Any help greatly appreciated!

  • Hi,

    Things have moved on a bit since that last post, but you'll still have to compile your own Espruino Binary... You'll have to:

    • Get a build environment set up - see https://github.com/espruino/Espruino for more info
    • Edit the Makefile and add USE_FILESYSTEM=1 for the F4 board
    • Edit boards/STM32F4DISCOVERY.py and add the pin definitions for the SD card (get them from ESPRUINOBOARD.py).
    • Recompile and flash it to your board

    and then the filesystem should work.

    Also, if you want something that 'just works', is cheaper than buying all that, and also helps to pay for all the time I spend on improving and supporting Espruino, you can always buy an Espruino board ;)

  • Thanks for the help @Gordon. Super snappy response :)

    Also, if you want something that 'just works', is cheaper than buying all that, and also helps to pay for all the time I spend on improving and supporting Espruino, you can always buy an Espruino board ;)

    I would love to support you but at the moment I am in the process of evaluating Espruino for much larger things. I'm starting my own company and have spent a lot of time looking for a hardware platform to base it on.

    So if things work out between Espruino and myself, you and I should talk some more about future collaboration ;)

  • Looks good - definitely if you're putting it into a product, doing your own compile with SD card support built in (and whatever else) probably makes a lot of sense anyway.

    One thing though: I was told (I'm not sure if it's true) that the licence for the Discovery boards forbids them to be used in anything commercial - I believe one of the reasons the board itself is so cheap is that ST basically sells it at cost.

    That means that you may have to look at another system anyway - or maybe MikroElektronika makes their own F4 board...

  • That means that you may have to look at another system anyway - or maybe MikroElektronika makes their own F4 board

    This is just the prototyping platform. The final product will have a different backplane board with more mikroBUS sockets and will have a processor board something like the MINI-M4 for STM32.

  • Okay @Gordon I went through the process and everything goes fine until I connect to the board in the webIDE. I get the following message in the console:

    >echo(0);
    Uncaught Error: Function "log" not found!
     at line 1 col 9
    console.log("<<"+"<<<"+JSON.stringify(pr­ocess.env)+">>>"+">>...
             ^
    

    I swear I didn't delete the log function :)

    Running something simple like 1+2 returns the correct answer.

    I put a simple text file on the SD card (text.txt) and then tried to read it out (it simply contains the word 'hello') like this:

    >var f = require("fs").readFile("test.txt");
    ERROR: Unable to mount SD card : NOT_READY
    

    Any tips?

    This is exactly what I did to get to this point:

    git clone -b RELEASE_1V69 https://github.com/espruino/Espruino.git­  espruino_1v69
    

    The relevant sections of my Makefile look like this:

    STM32F4DISCOVERY=1
    ...
    RELEASE=1
    ...
    else ifdef STM32F4DISCOVERY
    ...
    USE_FILESYSTEM=1
    

    and the boards/STM32F4DISCOVERY.py:

    devices = {
    ...
      'SD' :  { 'pin_cs' :  'B12',
                  'pin_di' :  'B15',
                  'pin_do' :  'B14',
                  'pin_clk':  'B13' },
    };
    

    I then just ran the command make and out popped espruino_1v70_stm32f4discovery.bin (I was expecting a file with a 1v69 version).

    I must say I can't figure out how to use stm32loader.py. With both USB cables plugged into the Discovery board, without jumpers on the GND-PB2 and BOOT0-VDD pin pairs the board is mounted on /dev/ttyACM2.

    Running the following command:

    python scripts/stm32loader.py -k -p /dev/ttyACM2 -evw espruino_1v70_stm32f4discovery.bin
    

    I end up with the following error:

    Reading data from espruino_1v70_stm32f4discovery.bin
    Can't init. Ensure BOOT0=1, BOOT1=0, and reset device
    Traceback (most recent call last):
      File "scripts/stm32loader.py", line 554, in <module>
        bootversion = cmd.cmdGet()
      File "scripts/stm32loader.py", line 140, in cmdGet
        if self.cmdGeneric(0x00):
      File "scripts/stm32loader.py", line 137, in cmdGeneric
        return self._wait_for_ack(hex(cmd))
      File "scripts/stm32loader.py", line 101, in _wait_for_ack
        raise CmdException("Unrecognised response 0x%x to %s" % (ask, info))
    __main__.CmdException: Unrecognised response 0xff to 0x0
    

    So instead I use the stlink application as follows:

    • Disconnect power and put jumpers across the GND-PB2 and BOOT0-VDD pin pairs.
    • Connect up the USB ST-Link cable.
    • Run the following command:

      sudo ./st-flash write espruino_1v70_stm32f4discovery.bin 0x08000000
      

    Everything flashes fine and I can remove the jumpers and restart the board.

  • Yes, that all seems good - stm32loader needs a serial connection to the chip, which you won't have.

    The short-hand to use st-flash to flash the board is just STM32F4DISCOVERY=1 make flash.

    The error you're getting is almost certainly because you haven't erased the chip first, so it's still got the 'old' code you saved in it. As it says in http://www.espruino.com/Other+Boards, just hold down Button1 while booting (which will stop Espruino automatically loading the saved program). Then type 'save()' to save a correct (but Empty) JavaScript program back into flash.

  • Sweet! So that solved the Uncaught Error: Function "log" not found! problem however the issue with the SD card is still there.

    This is what I did:

    • Created a text file on my Linux system (using vim) called, test.txt in the root of the microSD card which contains a single line of text, namely hello.
    • I then connect my hardware setup, as explained in my previous post, to the Web IDE and run the following line of code with the associated response:

      >var f = require("fs").readFile("test.txt");
      ERROR: Unable to mount SD card : NOT_READY
      

    Any ideas @Gordon?

  • All I could suggest is that you make sure you reformat the SD card in FAT32, and make sure that the connections you gave really are the right ones for where you've plugged in the SD card shield.

    Maybe try and stick a scope on the data pins and see if they really are working when you try and access the card.

    People definitely have had it working on the F4 though, so I'd imagine it's something relatively simple.

  • Unfortunately still not working.

    So I did the following:

    • double and triple checked my pinout in boards/STM32F4DISCOVERY.py. No problem there.
    • I reformatted both of my microSD cards as follows:

      sudo mkdosfs /dev/sdg1 -F 32 -I
      
    • I connected up my oscilloscope to pins PB15 (DI) and PB14 (DO) as suggested, ran the following command:

      var f = require("fs").readFile("test.txt");
      

    and captured this image where channel 2 (blue) is PB15 (DI):


    Figure 1: Oscilloscope image showing the DI (blue) and DO (yellow) pin states while attempting to read from the SD card.

    So it seems it is at least addressing the correct pins.

    Pinout differences:
    I then remembered comparing the pinouts of the Espruino board SD card holder schematic with those of the MikroElektronika microSD click board. Below is a side by side image of the two.

    My observations:

    • pin 9 (CD) is connected up on the MikroElektronika board. Initially I didn't know what this pin was for but after reading the Adafruit microSD breakout board tutorial I see it is the card detect pin which shorts to ground when a card is inserted. This pin is not connected on the Espruino schematic. No idea what the consequences are of this difference.
    • there are a number of differences with the ground connections (G2, G3, G4) on the Espruino board which the MikroElektronika doesn't show in as much detail.

    Any tips @Gordon?

    Once again many thanks.

    Roy

  • Have you tryed to put CS to GND, before you talk to the card.

  • Thanks for the suggestion @Frida. Unfortunately it still gives the same error:

    
    This is what I saw in my two attempts, this time monitoring the CS and DI pins.
    
    **First attempt**
    
    I started by executing the following command to set the CS pin low:
    
    

    B12.write(false);

    
    I then followed this up with the file read command:
    
    

    var f = require("fs").readFile("test.txt");
    ```

    and saw the following on the scope:

    Second attempt

    This time I just ran the file read command and saw the following on the scope:

    Conclusion

    From this it seems the chip select pin is being set correctly.

    Any other ideas?

  • Well what do you know, it is working! :)

    Wandering in the wilderness

    Since my last post I delved right down into the SD specification to try and figure out what should be happening. I found a few particularly helpful posts and documents that I'd like to share here for others having similar problems:

    1. SD Specifications - Part 1 - Physical Layer - Simplified Specification - Version 4.10
    2. Reading SD cards with the STM32F4-Discovery
    3. Micro SD Data Sheet
    4. Secure Digital Card Interface for the MSP430 - Dept. of Electrical and Computer Engineering, Michigan State University

    and it even got me ferreting through the C code ;)

    Thanks to reference #2 above I found out what should be happening with the card detect (CD) pin when the card is put into the slot. Everything was in order.

    Still no joy!

    For some reason I decided to use another set of pins and see what happened. This is the current standing of the SD definition block in boards/STM32F4DISCOVERY.py:

      'SD' :  { 'pin_cs' :  'D7',
                'pin_di' :  'B5',
                'pin_do' :  'B4',
                'pin_clk' :  'B3' },
    

    I connected her up, ran my command and this is what I got:

    >var f = require("fs").readFile("test.txt");
    ="hello\n\n"
    

    followed by a write just to make sure it really was working:

    >var f = require("fs").writeFile("blah.txt","hell­o");
    =true
    

    So I'm not quite sure what is wrong with the other set of pins but at least it is now working and I have learnt a bunch of stuff I never thought I'd have to!

    Thanks again for all your help @Gordon.

  • Just to properly complete this ticket I thought I would add some scope images of what things look like when everything is working.

    Read

    >var f = require("fs").readFile("test.txt");
    ="hello\n\n"
    

    produces:

    Write

    >var f = require("fs").writeFile("blah.txt","hell­o");
    =true
    

    produces:

  • Glad you got it sorted...

    I wonder what the issue was - whether it was a pin conflict, or some problem with SPI on those pins...

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

STM32F4 Discovery, SPI and microSD

Posted by Avatar for roy.emmerich @roy.emmerich

Actions