Close
0%
0%

STM32F030F4P6 breakout board

Not as bulky as the nucleo boards, after all.

Similar projects worth following
A dead simple prototyping board for the STM32F030F4P6, BOM is about 3 euros including the PCB from OSH Park.

After the Teensy 3.0 took me to the world of ARMs I quickly wanted to try different chips. While the Teensy boards and tools are great, they are limited to a very specific set of Freescale chips.

ST sells ARM chips as well, so I got a nucleo board which can be used to program other targets as well. This breakout board has an SWD header, so it can be programmed through the nucleo's SWD header or by any other programmer with this interface.

This board is dead simple:

  • MCU
  • decoupling caps
  • an LED with a current limiting resistor for that first blinky program
  • reset button
  • SWD header
  • BOM on the bottom side so you can simply throw it into your box of PCBs for soldering later, and forget where the docs are.

MCU and LED polarity:

  • The MCU's pin 1 is marked with a longer silk screen line (towards the A0 pin)
  • The LED's cathode is on the extended side of the silk screen lines (towards the A6 pin)

  • 1 × PCB (see OSH Park link)
  • 1 × STM32F030F4P6 48 MHz Cortex-M0, 16 KB flash, 4 KB RAM, TSSOP20
  • 2 × 0603 cap, 100 nF
  • 1 × 0603 cap, 10 nF
  • 1 × 0603 LED Don't forget to pick a suitable current limiting resistor for your LED

View all 9 components

  • PlatformIO

    Christoph05/04/2019 at 19:23 0 comments

    I installed VSCode and the PlatformIO extension to see if this board can be used with pio. It works!

    Steps to reproduce:

    Project setup

    • in PlatformIO home tab, import Project Examples - stm32cube-hal-blink
    • modify platformio.ini to have the following content (it might be ok to omit some settings, I'm not sure):
      [env:demo_f030f4]
      ;platform = ststm32
      platform = https://github.com/platformio/platform-ststm32.git
      framework = stm32cube
      board = demo_f030f4
      build_flags = -DF0
      ; change microcontroller
      board_build.mcu = stm32f030f4p6
      ; change MCU frequency
      board_build.f_cpu = 48000000L
      upload_protocol = stlink
      Just using "ststm32" as platform doesn't work because there's a problem with the F030F4 startup code, see issue here: https://github.com/platformio/platform-ststm32/issues/234. So we need the github platform.
    • Main already has blink code, but this breakout board's LED is connected to GPIO port B, pin 1. So change the port settings to (also pay attention to the clock enable macro, which needs to be changed to port B, too):
      #define LED_PIN                                GPIO_PIN_1
      #define LED_GPIO_PORT                          GPIOB
      #define LED_GPIO_CLK_ENABLE()                  __HAL_RCC_GPIOB_CLK_ENABLE()
      
      (somewhere around line 24)

    Hardware setup

    Connect an ST-Link to the breakout board and supply 3.3 V to VDD (the ST-Link connection will not supply power!). See here: https://hackaday.io/project/4277/gallery#52043e53586461bb2bbb51046f9c2334

    Build and upload

    should work out of the box. If upload fails, check udev rules and dialout group stuff as described here: https://docs.platformio.org/en/latest/plus/debug-tools/stlink.html#debugging-tool-stlink

    Sometimes replugging the USB cable or a manual reset can also be helpful.

  • Updated repo

    Christoph12/02/2015 at 12:34 0 comments

    I added the current gerbers (pcb with BOOT0 pulldown) to the github repo

  • Layout revised

    Christoph11/09/2015 at 14:16 0 comments

    I added a BOOT0 pull-down resistor (10k) to the schematic and layout and also made some more minor layout tweaks. Silk screen type size could be increased a bit to 35 mil (was about 30 mil before) and I also increased the supply trace width as suggested in the comments.

    Not tested yet, but if you want to try it:

    https://oshpark.com/shared_projects/WwATL5iu


  • BOOT0 issue

    Christoph11/04/2015 at 09:10 0 comments

    As david pointed out in the comments, BOOT0 should be pulled low to boot the application. For now this has to be done on the breadboard because the PCB doesn't include a pull-down resistor. I hope to fix this in the next PCB revision without having to use smaller (0402) parts.

  • Added eagle files to repo

    Christoph07/13/2015 at 11:41 0 comments

    I uploaded to the eagle (6.6) brd and sch files to the repo. Happy whatevering!

  • Now on github

    Christoph06/30/2015 at 07:43 0 comments

    Yesterday's work is now on github:

    • Code::Blocks example project
    • initialization code for the systick timer
    • elapsedMillis class
    • blinky code example

    I'm thinking about writing a project wizard for creating libopencm3 based projects in Code::Blocks, which shouldn't be too hard.

  • This board, Code::Blocks and libopencm3

    Christoph06/29/2015 at 13:16 1 comment

    I tried to set up Code::Blocks to use libopencm3, which was not that hard, after all. It's just a lot of work, but it can be stored as a template! This post might appear to be very long, but about 90% of it are screenshots, and cut 'n paste code.

    Sources of information

    First of all I downloaded and compiled libopencm3 according to their instructions, with a custom destination directory. This left me with a set of chip libraries (opencm3_stm32f0 and many more for other chips) to be included in my project. I also have the compiler configured already. So here are a few screenshots of my C::B setup.

    Create an empty project (File->New->Project):

    Hit go and enter your project's title and filename. Select your arm-none-eabi-gcc when asked for a compiler, and hit finish (this automatically creates debug and release configurations):

    Fine, there's now an empty project in the workspace that we can fill with our source code and build info.

    Code

    Create a main.cpp (File->New->Empty File or CTRL-Shift-N) and add it to the project. Mine looks like this (based on code taken from one of the STM32F0 examples from https://github.com/libopencm3/libopencm3-examples/blob/master/examples/stm32/f0/stm32f0-discovery/systick_blink/systick_blink.c):

    #include <libopencm3/stm32/rcc.h>
    #include <libopencm3/stm32/gpio.h>
    #include <libopencm3/cm3/nvic.h>
    #include <libopencm3/cm3/systick.h>
    
    /* PB1 is connected to the onboard LED on the STM32F030F4P6 breakout board. */
    #define PORT_LED_ONBOARD GPIOB
    #define PIN_LED_ONBOARD GPIO1
    
    /* Called when systick fires */
    void sys_tick_handler(void)
    {
    	gpio_toggle(PORT_LED_ONBOARD, PIN_LED_ONBOARD);
    }
    
    /* Set up timer to fire freq times per second */
    static void systick_setup(int freq)
    {
    	systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
    	/* clear counter so it starts right away */
    	STK_CVR = 0;
    
    	systick_set_reload(rcc_ahb_frequency / freq);
    	systick_counter_enable();
    	systick_interrupt_enable();
    }
    
    /* set STM32 to clock by 48MHz from HSI oscillator */
    static void clock_setup(void)
    {
    	rcc_clock_setup_in_hsi_out_48mhz();
    
    	/* Enable clocks to the GPIO subsystems */
    	rcc_periph_clock_enable(RCC_GPIOB);
    }
    
    static void gpio_setup(void)
    {
    	gpio_mode_setup(PORT_LED_ONBOARD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED_ONBOARD);
    }
    
    int main(void)
    {
    	clock_setup();
    	gpio_setup();
    
    	/* setup systick to generate 2 LED flashes per second */
    	systick_setup(4);
    
    	/* Do nothing in main loop */
    	while (1);
    }
    

    Compiler and Linker flags

    Now comes the trickier part: Set up flags for the compiler and the linker. Go to Project->Build options and select the top-level entry, which has options for all sub-targets (debug and release):

    My compiler flags in the "Compiler Settings" tab, combined from the tabs "Compiler Flags" and "Other options", are:

    -Wall
    -pedantic
    -mlittle-endian
    -msoft-float
    -mthumb
    -mcpu=cortex-m0
    -ffunction-sections
    -fdata-sections
    -fno-exceptions
    
    and one define in the "#defines" tab:
    STM32F0
    Now for the linker ("Linker settings" tab):

    That is in the "Link libraries" list:

    c_nano
    nosys
    opencm3_stm32f0
    and in the "Other linker options":
    -mcpu=cortex-m0
    -mthumb
    -Wl,--gc-sections
    --specs=nano.specs
    --specs=nosys.specs
    -Tstm32f030f4p6.ld
    -Wl,-Map=$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).map,--cref
    
    Search Directories for the compiler:

    (this requires libopencm3 to be in the project root directory)

    For the linker:

    The first entry in the search directory list is just a dot, so the linker will find a linker script in the project root directory. The other entry is a relative path to the pre-built libraries for all chips.

    We're almost there, just some fine-tuning after the build is finished:

    arm-none-eabi-size $(TARGET_OUTPUT_FILE)
    arm-none-eabi-objcopy -O binary $(TARGET_OUTPUT_FILE) $(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).bin
    
    Now you can also add extra flags for debug and release builds (generate... Read more »

  • SSD1351 Display and uGFX

    Christoph06/18/2015 at 21:45 0 comments

    This was fairly easy - I added the uGFX sources to my project and after rearranging some include directives it actually compiled fine. uGFX also comes with some pre-written display drivers, including one for the SSD1351. The only thing I had to customize was the board file template:

    #include "gpio.h" // <- generated by CubeMX
    #include "spi.h"// <- generated by CubeMX
    
    #define PORT_OLED_RESET GPIOA
    #define PIN_OLED_RESET GPIO_PIN_3
    #define PORT_OLED_CS GPIOA
    #define PIN_OLED_CS GPIO_PIN_4
    #define PORT_OLED_DC GPIOB
    #define PIN_OLED_DC GPIO_PIN_1
    
    static inline void init_board(GDisplay *g) {
      (void) g;
      HAL_GPIO_WritePin(PORT_OLED_RESET, PIN_OLED_RESET, GPIO_PIN_SET);
      HAL_GPIO_WritePin(PORT_OLED_CS, PIN_OLED_CS, GPIO_PIN_SET);
      HAL_GPIO_WritePin(PORT_OLED_DC, PIN_OLED_DC, GPIO_PIN_SET);
    }
    
    static inline void setpin_reset(GDisplay *g, bool_t state) {
      (void) g;
      if (state)
        HAL_GPIO_WritePin(PORT_OLED_RESET, PIN_OLED_RESET, GPIO_PIN_RESET);
      else
        HAL_GPIO_WritePin(PORT_OLED_RESET, PIN_OLED_RESET, GPIO_PIN_SET);
    }
    
    static inline void acquire_bus(GDisplay *g) {
      HAL_GPIO_WritePin(PORT_OLED_CS, PIN_OLED_CS, GPIO_PIN_RESET);
    }
    
    static inline void release_bus(GDisplay *g) {
      HAL_GPIO_WritePin(PORT_OLED_CS, PIN_OLED_CS, GPIO_PIN_SET);
    }
    
    static inline void write_cmd(GDisplay *g, uint8_t index) {
      (void) g;
      HAL_GPIO_WritePin(PORT_OLED_DC, PIN_OLED_DC, GPIO_PIN_RESET);
      HAL_SPI_Transmit(&hspi1, &index, 1, HAL_MAX_DELAY);
      HAL_GPIO_WritePin(PORT_OLED_DC, PIN_OLED_DC, GPIO_PIN_SET);
    }
    
    static inline void write_data(GDisplay *g, uint8_t data) {
      (void) g;
      HAL_SPI_Transmit(&hspi1, &data, 1, HAL_MAX_DELAY);
    }
    
    There are some other empty functions in there, which are not needed and omitted in the above snippet. As you can see it's just a matter of setting the display's control pins and sending single bytes via SPI, which is easily done with ST's HAL. GPIO and SPI initialization code was generated by CubeMX and is called by main(), but it could also be added to the init_board() function.

    And it actually works:

    uGFX without widgets (and everything that would come with them) takes about 6kB flash and a few hundred bytes (something between 300 and 400) of RAM. That includes one of uGFX's fonts stored in flash.

  • CubeMX 4.8.0

    Christoph06/17/2015 at 19:00 0 comments

    I just noticed that ST released CubeMX 4.8.0, so I gave it a try. I'm still running ubuntu 14.04, which already worked for CubeMX 4.6.0. The software is zipped when you download it, so I just unzipped the installer (an exe archive) and ran it:

    sudo java -jar SetupSTM32CubeMX-4.8.0.exe
    Unfortunately, root permissions are necessary for running the installer.

    Then I selected a directory somewhere in my home folder and finished the installation without any problems. To run the installed program:

    java -jar ~/path/to/CubeMX/installation/STM32CubeMX.exe
    As already noted in my previous log, this line can be added as an alias (~/.bash_aliases):
    alias cubemx-4.6.0='java -jar ~/builds/STM32CubeMX_4.6.0/STM32CubeMX.exe'
    alias cubemx-4.8.0='java -jar ~/builds/STM32CubeMX_4.8.0/STM32CubeMX.exe'
    alias cubemx='cubemx-4.8.0'
    Code generation still has two problems:
    • No startup code is included in the generated code and
    • the included linker script is empty.

    Those two are not terribly difficult to overcome, though, because both startup and linker scripts can be copied from the "repository" (a bunch of folders on your disk where CubeMX is taking all the source files from).

  • Just a small update

    Christoph06/16/2015 at 20:13 0 comments

    I actually found time to redesign my reflow oven controller and to assemble a test board with the new layout:

    The extra clearance between the 0603 parts to the right really helps during assembly. The LED (an Osram SmartLED LA L296) is still a bit too bright with a 330 Ohm resistor.

    I also updated the link to OSH Park.

View all 17 project logs

Enjoy this project?

Share

Discussions

Ben Hencke wrote 02/09/2018 at 19:41 point

Thank you! I was trying to figure out how to wire up SWD making my first ARM board using this same chip, and this project helped a lot! 

  Are you sure? yes | no

alpha_ninja wrote 12/07/2015 at 00:26 point

[verified: no design files missing]

  Are you sure? yes | no

alpha_ninja wrote 12/02/2015 at 00:47 point

This is your one-week reminder to upload design documents: https://hackaday.io/project/7813-the-square-inch-project/log/28566-design-deadline

  Are you sure? yes | no

trimarco232 wrote 11/07/2015 at 14:25 point

Hallo Christoph,

I've just modified the design in order to add the 10k resistor

... but don't now how to share it

  Are you sure? yes | no

Christoph wrote 11/07/2015 at 16:22 point

You can create a fork on github and make modifications there, then just share the link so I can have a look

  Are you sure? yes | no

trimarco232 wrote 11/09/2015 at 20:02 point

It's not necessary anymore because your new design is better

the only things I might suggest are to make the diagonal VCC track wider, and to leave the warnish on the vias 

  Are you sure? yes | no

Christoph wrote 11/09/2015 at 21:09 point

good point on widening the VCC track, will do that in the next revision.

  Are you sure? yes | no

David wrote 10/30/2015 at 08:57 point

Superb! just mounted my PCB and it blinks :D Thank you very much for sharing. I only have a suggestion for the next round: I noticed that occasionally the MCU is not booting the application as the core jumps in System memory (0x1FFFEC00). Just add a 10k pull-down to BOOT0 pin to solve the issue.

  Are you sure? yes | no

Christoph wrote 10/31/2015 at 21:26 point

Sounds great! Thanks for trying the board. I've also noticed flaky boot behavior, but I couldn't really look out for the real reason. Does adding a pull-down rule out any options for later use? I guess not, because it could be overrun by a stronger external input, but I don't have a lot of experience with these chips.

  Are you sure? yes | no

David wrote 11/02/2015 at 09:27 point

Hi! BOOT0 pin is only used to enable System Memory boot option so it is safe to tie it to GND with no loss of functionalities. Then, you can set it to Vdd in case you want to boot to System Memory and exploit STM32 internal UART/I2C flasher feature.

  Are you sure? yes | no

Christoph wrote 11/02/2015 at 12:27 point

Adding another resistors will be a challenge but I'll try. Some of the silk screen text is probably not necessary or can be rearranged

  Are you sure? yes | no

Brian wrote 07/14/2015 at 03:12 point

I built it and it blinks! Thanks for all of your excellent documentation of how you built your tool chain. I'm happily using emacs and make files but I got there much faster because of your example. 

Funny first time incident: I installed the led upside down (as in correct polarity but package face down). It looks kind of cool so I'm keeping it that way but I've never screwed up that way before

  Are you sure? yes | no

Christoph wrote 07/14/2015 at 08:42 point

Congratulations! The upside down LED might even be good because it's surely not too bright now.

  Are you sure? yes | no

Brian wrote 07/15/2015 at 00:32 point

yeah! Totally solves that problem  

  Are you sure? yes | no

abf149 wrote 07/11/2015 at 04:56 point

Hi Christoph,

Did you make this board in Eagle or Altium? I am interested in making some modifications to the board and I am wondering if you could share/post the original board files (not the Gerbers).

Best,

abf149

  Are you sure? yes | no

Christoph wrote 07/13/2015 at 08:06 point

I made the board in eagle 6.6 and added the brd and sch files to the github repo (find it in the project links). Does that work for you?

  Are you sure? yes | no

Adam Fabio wrote 06/19/2015 at 02:11 point

Awesome work! I love having these kinds of boards for micros I'm familiar with, as I can drop them in to any project/hack I'm working on. A board like this combined with a pre-setup toolchain is also a slam-dunk at hackathons

I just ordered 3 boards from OSHPark - total price including shipping was $3!

  Are you sure? yes | no

Christoph wrote 06/19/2015 at 07:06 point

Thank you! There are still some things about this board that I don't like, though:

 - The top silk screen should clearly indicate that the top left pin belongs to the SWD header and should not point towards the bottom (I almost got that wrong twice)

- an extra ground pin should be placed next to F0/F1, because those are the pins an external crystal would be connected to

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates