Organize and Share your Electronics the way you want. Sign-Up for a free account now. It takes only 30 seconds!

A development board for the STM32F042 TSSOP package

A development board for the STM32F042 TSSOP package

It’s been a while since I posted a new article, a delay at least partly due to me herniating a disc in my neck which left me completely unable to look downwards for any length of time and as you’ll know all too well you can’t work on circuit boards without peering down at them. Look after your neck and back folks, and I mean that seriously.

Well I’m back now and I’ve got a lot of ideas for articles spinning around in my head that will hopefully come to fruition over the next few months. First off the block is this one in which I’m going to present a simple development board for the STM32F042 in the easy(ish) to work with TSSOP20 package.

STM32F042 TSSOP20 0.65mm pitch package

This project came about because I’m using the STM32F042F6P6 (32Kb flash, 6Kb SRAM) in another project where I’m creating a USB device and the first thing I did is try to obtain a development board for it. I was hopeful that ST would have created one of their ‘discovery’ boards but no, there was only a ‘nucleo’ board available and that had one of the QFP packages on it.

The F042 nucleo board

The nucleo board would have probably been sufficient for my needs but I do prefer to work on the actual device that’s going to be used in the real project and I had a few ideas for features that I’d include that I wish would be included in other development boards but never seem to be.

Development board features

  • USB. The 042 series supports USB and although 32Kb is not a lot of space to include a USB driver and your application logic it does make sense to hook up those USB data lines and thereby enable USB device development.
  • Switching regulator. All the development boards that I’ve seen seem to use a low dropout regulator (LDO) to supply power to the MCU which means that they’re unable to supply much current to any peripherals that you’re prototyping. The discovery boards warn you not to draw more than 100mA and many of the 3rd party boards use one of the 1117 regulators which, with up to a 1A limit, look great on paper but the universally chosen SOT-223 package will burn up in smoke long before you get anywhere near that figure.
  • VDDA control.The discovery boards allow you to supply VDDA externally if required. I’d like to keep this ability.
  • Onboard 8MHz crystal. All the F0 series can be clocked from the internal high speed internal (HSI) 8MHz oscillator with an option to use an external 8Mhz crystal. I’ll include such a crystal on my board.
  • Onboard NPN transistor. I often need to use an NPN transistor as a low-side switch to control a load either requires too much current to power from a GPIO or is running from a different voltage level (e.g. 5V). I’ll include a simple transistor on this board configured ready to function as a switch.
  • A LED. Because, well, you know, blinky.
  • Schematic

    Click for a PDF

    The schematic is rather modular so let’s take a look at each section in detail.

    The power supply

    The 3.3V voltage for the board is supplied by a Texas Instruments LMR10515 adjustable switching buck (step-down) regulator. I’ve used this regulator a few times before and have found it to be a solid and reliable device that doesn’t require many external components and only costs about 50 pence from Farnell.

    This regulator is capable of supplying up to 1.5A with an efficiency level of over 90% throughout most of its range. The input will be the 5V VBUS line from the USB plug after I’ve sanitised it to remove the gremlins that lurk therein.

    It’s this efficiency level that allows switching regulators to deliver their peak current rating without burning up in a puff of smoke. The output inductor and schottky diode must both be chosen to match the desired peak current from the regulator. For the inductor I’ve chosen the Murata LQH44PN3R3MP0L (2.1A maximum current) and for the schottky I’m using an ST Micro STPS0520Z (0.5A maximum current).

    In practice this means that my development board is limited to 500mA but you can use any schottky that will fit the SOD-123 footprint if you need a higher current supply up to the 1.5A maximum that the regulator can deliver.

    The MCU

    The MCU power and reset scheme is wired up according to ST’s recommendations. VDD gets a pair of 100nF and 4.7µF capacitors and VDDA gets a 10nF and 1µF pair. P3, a 4 pin header, receives a jumper across pins 1 and 2 to connect VDDA to the onboard 3.3V supply or the jumper can be removed to allow an external VDDA to be connected to pin 3.

    C4 decouples the active-low reset pin to prevent any spurious resets from ruining your day. There’s no need for a pull-up to VDD because ST supply one internally.

    The crystal is connected to the MCU via a pair of 0R ‘resistor’ bridges that can be removed if you’ve fitted a crystal but want to use the PF0 and PF1 pins as GPIO without fear of interference from the crystal itself.

    If you’re considering USB device development and you’ve done this before then you may think that you’re going to need the external crystal to generate the accurate 48MHz clock required by USB to stay in sync with the host, but this is not the case. ST supply an internal ‘HSI48’ 48MHz clock specifically for use with the USB peripheral and with a bit of software configuration you can not only clock the MCU core from it but you can also constantly trim its accuracy from the USB Start of Frame (SOF) packets sent by the host to the device every 1ms. I’ll show you how to set up this crystal-less configuration later on.

    Upon startup the MCU can boot from flash, SRAM or system memory (that’s where the boot loader is). The most common option is to boot from flash directly into your code and you select that by holding BOOT0 low during the exit from reset and standy modes.

    But wait, doesn’t this waste the PB8 GPIO pin? No it doesn’t. If you always want to boot from flash then you can program the BOOT_SEL and nBOOT0 bits of the FLASH_OBR register to 0 and 1 respectively and then the MCU will ignore BOOT0 and you can use it as a GPIO pin.

    Programming and debugging

    ST include an embedded ST-Link/v2 chip on their discovery boards implemented within an STM32F1 series MCU that allows you to program and debug over the same USB line that you use to supply power.

    That’s neat, and it means that you don’t have to buy a programmer for your board. It is, however, proprietary which means I can’t include it on this board. Instead, I include the standard 20-pin ST-Link/v2 header that you can attach a programming cable to.

    I’ve already written an article about how to set up and use the ST-Link/v2 programmer using only free software.

    The USB interface

    I’ve opted to include an ST Micro USBLC6-2SC6 ESD protection device between the USB lines and the MCU. Without this the MCU would be vulnerable to ESD events on the line caused by handling of the plug or cable and could easily be damaged or destroyed.

    Chances are you don’t even have the ID signal line in your cable (it’s for OTG cables only) but in common with ST’s configuration on their discovery boards I’m grounding it through a 100kΩ resistor.

    C1, C2, C3 and FB1 form a filtering network to remove noise from the VBUS line before it becomes an input to the switching regulator. If you’ve never seen how much noise you can get on VBUS then I recommend that you take a look at this article that I wrote.

    If you’re powering this board from a computer’s USB port then be mindful of the maximum amount of power that you can draw. This wikipedia article explains it well. Of course if you’re powering this board from a USB wall charger then the limit is set by that charger.

    The USB socket itself is a mini-B size and has a very common standard footprint. Search ebay for these mini-B PCB sockets and you’ll see that they all have this footprint.

    Power output

    P4 is a pin header that can be used to access the power supplies on the board along with a generous helping of ground pins. You can’t have too many ground pins on a development board and I find it really frustrating when you receive a board to find it’s only got one or two ground pins. I’ve included four here and another one on the GPIO header.

    NPN transistor

    The base of the MMBT3904 transistor is connected via a 1kΩ resistor to PA7 so you can control it as a switch from the MCU. The maximum collector current for the MMBT3904 is 200mA. If you need more than that then you should substitute this part for another one in the SOT23-3 package that has a higher rating.

    R9, a 100kΩ resistor, pulls the base down to ground so you don’t get spurious switching events during any periods when the gate is floating. The idea is that you connect your load to be driven to the LOAD pin.


    All the GPIO pins exposed by the TSSOP20 package are included here as well as the LOAD pin for the NPN transistor and an additional ground pin.

    Bill of materials

    Here’s the full bill-of-materials for this board, along with Farnell product code numbers to help you put together an order basket.

    Identifiers Value Quantity Description Footprint Farnell code
    C1, C9 10n 2 Ceramic capacitors 0603 1709947
    C2, C4, C7 100n 3 Ceramic capacitors 0603 1759122
    C5, C6 22p 2 Ceramic capacitors 0603 2309012
    C3, C8 4.7µ 2 Ceramic capacitors 0603 2320811
    C10 1 Ceramic capacitors 0603 1759399
    C11, C12 22µ 2 Ceramic capacitors 0805 2309030
    D1 STPS0520Z 1 Schottky diode[1] SOD123 1467545
    D2, D3 green , red 2 LEDs 0603 [2]
    FB1 BLM18PG221SN1D 1 Ferrite bead[1] 0603 1515740
    L1 LQH44PN3R3MP0L 1 Inductor[1] 4x4mm 1782797
    P1 USB Mini B 1 USB connector custom [3]
    P2 1 Header, 9-Pin, Dual row 2.54mm [4]
    P3 1 Header, 2-Pin, Dual row 2.54mm [4]
    P4 1 Header, 5-Pin, Dual row 2.54mm [4]
    P5 1 Header, 10-Pin, Dual row 2.54mm [4]
    P6 1 Header, 2-Pin, Dual row 2.54mm [4]
    Q1 MMBT3904 1 NPN transistor SOT23-3 1773602
    R1, R4, R9 100k 3 Chip SMD resistor 0603 2447226
    R2, R3 0 2 Chip SMD resistor 0603 2309106
    R5 45.3k 1 Chip SMD resistor 0603 2059468
    R6 10k 1 Chip SMD resistor 0603 9238603
    R7, R17 330 2 Chip SMD resistor 0603 2331995
    R8 1k 1 Chip SMD resistor 0603 2447272
    U1 USBLC6-2SC6 1 USB ESD protection SOT23-6 1269406
    U2 STM32F042F6P6 1 MCU TSSOP-20 2469549
    U3 LMR10515 1 Switching regulator SOT23-5 2064682
    Y1 FOXSLF/080-20 1 8MHz crystal HC49 2063945

    [1] These components must be rated in excess of the current that you plan to draw. My recommendations support a maximum of 500mA.

    [2] 0603 SMD resistors are so cheap on ebay that I recommend you buy some there. I used green for the power LED and amber for the GPIO LED.

    [3] The USB mini-B PCB connector is a common footprint that’s very cheaply available on ebay. See the high-resolution photograph in this article and compare to ebay auction photographs.

    [4] Dual-row 2.54mm pin headers are very cheap on ebay.

    Building the board

    The board was laid out to fit within a 50mm square so that it could be manufactured by one of the discount Chinese prototyping houses such as Seeed, ITead, PCBWay and Elecrow. For this size of board I choose Elecrow and for US$9.90 plus delivery I can get ten copies in about two or three weeks.

    Time passes. Two or three weeks worth of time as it happens…

    I made a small mistake on the Gerbers for the USB connector. On the footprint I include a guideline on one of the mech layers to aid positioning of the connector at the board edge and I mistakenly included that mech layer on the Gerber export with the result being a small sliver of exposed copper at the board edge on both sides under the USB connector. It makes no difference to the viability of the board but I find it annoying because I know it shouldn’t be there!

    I’ve included M3 sized screw holes that can be used for adding ‘feet’ to the board so it’s lifted above my work surface and if you look at the back you can see that there are some handy quick-reference tables that identify which pins are connected to the commonly used peripherals.

    Now it’s time to build it. I don’t have a paste stencil for this board so I opted to build it in several stages. Firstly I tinned all the surface mount pads with solder. Secondly, I reflowed the larger surface mount components such as all the ICs, the inductor and the USB connector using my bluetooth reflow oven. Thirdly I attached all the smaller 0603 and 0805 components using hot air and tweezers and finally the through-hole components were soldered into place using an iron. A quick wash with hot water and fairy liquid followed by drying overnight and she’s ready to test.

    Looking pretty sweet I think. But does it work? Let’s run through some tests to see what it can do.

    Testing the functionality

    The first test is simply to connect the USB cable from the board to a computer and then test the voltages to make sure the regulator is working. My multimeter read bang on 3.30V from the regulator output and the green power LED, D2, was lit at a nice subtle brightness. Another bugbear of mine is dev boards that include power LEDs configured at retina-burning levels.

    Before moving on to a programming test let’s have a look at the residual noise on the board’s 3.3V supply.

    It looks reasonable. Noise levels are within +/- 100mV. Let’s get on with some programming tests. I started up OpenOCD from a Cygwin terminal and got the expected output:

    Open On-Chip Debugger 0.9.0 (2015-05-19-12:09)
    Licensed under GNU GPL v2
    For bug reports, read
    Info : The selected transport took over low-level target control. The results might differ
           compared to plain JTAG/SWD
    adapter speed: 1000 kHz
    adapter_nsrst_delay: 100
    none separate
    srst_only separate srst_nogate srst_open_drain connect_deassert_srst
    Info : Unable to match requested speed 1000 kHz, using 950 kHz
    Info : Unable to match requested speed 1000 kHz, using 950 kHz
    Info : clock speed 950 kHz
    Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
    Info : using stlink api v2
    Info : Target voltage: 3.243836
    Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints

    This means that the MCU is responding to the SWD debugging commands and is ready to program. Now to test the onboard features. I’ll use my stm32plus library for all these tests. Even though it does not directly support the F042 series it does support the F051 and with a few adjustments to startup code and linker scripts we should be able to get things going.


    The first thing we need to do is modify the linker script designed for the F051 to be compatible with the F042. The section at the top needs to be changed to reflect the 32Kb of flash and the 6Kb of SRAM in the F042. These are the changes:

    /* End of 6Kb SRAM */
    _estack = 0x20001800;
    /* Generate a link error if heap and stack don't fit into RAM */
    _Min_Heap_Size = 0;      /* required amount of heap  */
    _Min_Stack_Size = 0x400; /* required amount of stack */
    /* Specify the memory areas */
      FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 32K
      RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 6K
      MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K

    For now we do not need to modify the code where the core clock is set System.c because it’s already set up to use the PLL fed by the 8MHz HSI. The core clock will be 48MHz.

    The onboard LED, D3, is hooked up to PB1. It’s a simple modification to the source code to flash this LED at 1Hz.

    void run() {
      // initialise the pin for output
      GpioB<DefaultDigitalOutputFeature<1> > pb;
      // loop forever switching it on and off with a 1 second
      // delay in between each cycle
      for(;;) {

    I fired it up and… success! The amber LED was flashing away at 1Hz. Programming, basic GPIO and the Systick peripheral are all working fine.

    The transistor switch

    This test is closely related to the basic blinky except this time I connected an external LED and series resistor to the LD (load) pin and change the code to control the blinking to use pin PA7.

    It’s working as expected which validates that the NPN transistor is connected up correctly.

    What about the external crystal?

    I’m not done with the blinkenled just yet. Before I can move on I need to know if the external 8MHz crystal is working which means configuring it as the MCU clock source. Luckily this is really simple.

    If you look inside the System.c startup file you’ll see that ST have provided a simple #define to select the clock source. To configure the HSE as the clock source we merely have to change the code to read like this:

    //#define PLL_SOURCE_HSI   // HSI (~8MHz) used to clock the PLL, and the PLL is used as system clock source
    #define PLL_SOURCE_HSE           // HSE (8MHz) used to clock the PLL, and the PLL is used as system clock source
    //#define PLL_SOURCE_HSE_BYPASS  // HSE bypassed with an external clock (8MHz, coming from ST-Link) used to clock
                                     // the PLL, and the PLL is used as system clock source

    Testing a timer

    The pin that I’ve attached to the LED, PB1, is also the GPIO output for channel 4 of timer 3. It’s a simple task to set up that timer in PWM mode and then to create a quick demo that pulses the LED as smooth ‘heartbeat’.

    void run() {
        Timer3InternalClockFeature,       // the timer clock source is APB1
        TimerChannel4Feature<>,           // we're going to use channel 4
        Timer3GpioFeature<                // we want to output something to GPIO
          TIMER_REMAP_NONE,               // the GPIO output will not be remapped
          TIM3_CH4_OUT                    // we will output channel 4 to GPIO
      > timer;
       * Set an up-timer up to tick at 12MHz with an auto-reload value of 1999
       * The timer will count from 0 to 1999 inclusive then reset back to 0.
       * It's all running automatically now, use the main CPU to vary the duty cycle up
       * to 100% and back down again
      for(;;) {
        // fade up to 100% in 4ms steps
        for(int8_t i=0;i<=100;i++) {
        // fade down to 0% in 4ms steps
        for(int8_t i=100;i>=0;i--) {

    This worked as planned and you can see the pulsating heartbeat LED in the video linked in at the end of this article.

    Testing USB

    stm32plus currently only has support for USB on the F4 which means that to test the USB interface I’m going to have to hold my nose and dive into that horrendous unreadable mess that’s otherwise known as the STM32 HAL. Taking the ‘custom HID’ example as a starting point, I proceeded to adapt it from the F072 target to the F042 and here’s some lessons I picked up along the way.

    Remap PA11 and PA12 to USB_DP and USB_DM

    When the MCU starts up PA11 and PA12 are configured for GPIO. The USB D+ and D- lines are actually on PA9 and PA10 and you need to map these two pins in place of PA11 or PA12. If you fail to do this then the USB interrupt will never fire. Here’s how:

    // Remap PA11-12 to PA9-10 for USB

    Way back in this article I promised to show you how to clock the MCU from the internal HSI48 oscillator and then use the SOF frames sent every 1ms by the host to continuously trim the clock to stay in sync with the host. Clocking your MCU like this means that you don’t have to use an external crystal which cuts costs and reduces board space.

    Here’s the replacement SetSysClock() function that you can plug into System.c.

    void SetSysClock() {
      // enable flash prefetch buffer
      // enable HSI48
      RCC->CR2 |= RCC_CR2_HSI48ON;
      while((RCC->CR2 & RCC_CR2_HSI48RDY)==0);
      // disable the PLL
      RCC->CR &=~ RCC_CR_PLLON;
      while((RCC->CR & RCC_CR_PLLRDY)!=0);
      // select HSI48 as the USB clock source
      // set flash latency = 1
      // AHB
      // HCLK source = HSI48
      while((RCC->CFGR & RCC_CFGR_SWS)!=RCC_CFGR_SWS_HSI48);
      // PCLK1
      // enable clock recovery system from USB SOF frames
      // Before configuration, reset CRS registers to their default values
      // Configure Synchronization input */
      // Clear SYNCDIV[2:0], SYNCSRC[1:0] & SYNCSPOL bits */
      // Set the CRS_CFGR_SYNCDIV[2:0] bits according to Prescaler value
      // CRS->CFGR |= 0;
      // Set the SYNCSRC[1:0] bits according to Source value
      // Set the SYNCSPOL bits according to Polarity value
      // CRS->CFGR |= 0;
      // Configure Frequency Error Measurement
      // Clear RELOAD[15:0] & FELIM[7:0] bits
      // Set the RELOAD[15:0] bits according to ReloadValue value
      CRS->CFGR |= 47999;     // (48MHz/1000) -1
      // Set the FELIM[7:0] bits according to ErrorLimitValue value
      CRS->CFGR |= (0x22 << 16);
      // Adjust HSI48 oscillator smooth trimming
      // Clear TRIM[5:0] bits
      CRS->CR &= ~CRS_CR_TRIM;
      // Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value
      CRS->CR |= (0x20 << 8);
      // Enable Automatic trimming
      // Enable Frequency error counter
      CRS->CR |= CRS_CR_CEN;

    With those modifications in place I was able to hack together a build for the ‘custom HID’ example and after a bit of gentle persuasion it actually worked. Here’s the device descriptor dump as reported by the ‘USBView’ Windows debugging utility:

    Device Descriptor:
    bcdUSB:             0x0200
    bDeviceClass:         0x00
    bDeviceSubClass:      0x00
    bDeviceProtocol:      0x00
    bMaxPacketSize0:      0x40 (64)
    idVendor:           0x0483 (STMicroelectronics)
    idProduct:          0x5750
    bcdDevice:          0x0200
    iManufacturer:        0x01
    iProduct:             0x02
    iSerialNumber:        0x03
    bNumConfigurations:   0x01

    When a USB device is inserted there is a flurry of very fast interrupt-driven data exchange between the host and the device as the host first queries for the device descriptor and then, based on what it receives, comes back with a sequence of further queries for the other standard descriptors. Only if all that goes well will the host accept the device and allow its descriptors to be queried in tools like ‘USBView’.

    So now I know that everything on the board works. All the features have been tested and I can happily use it for development and testing on the F042 platform going forward.

    Watch the video

    There’s a short video to go with this article where I just walk through the board features and then briefly show the programming and demo code.

    Lessons learned

    When a project comes to a close and you have time to reflect then there’s always one or two things that you’d do differently and this one’s no different. Here are a few things that I’d do differently.

    The ‘boot’ selector header is too close to the SWD header. With the SWD cable connected it would be a very tight fit to get a jumper across to select the RAM boot option.

    If I were to shuffle a few components around I think I could probably stretch to a push-button on the board. It’s always nice to have a button.

    The VDDA selection is a bit clunky. Selecting the internal 3.3V supply as the VDDA source with a jumper is obvious enough but it’s not obvious that to use an external VDDA you have to remove the jumper and connect your external supply to pin 3 in that header block. Pin 4 is effectively redundant.

    Breadboard compatibility. If I increased the board size to the 10x5cm format then I’d have enough space to make the pin headers single row and thereby plug directly into a breadboard.

    Get the Gerbers

    Want to build this board yourself? If you can handle a 0.65mm pitch IC and a generous sprinkling of 0603 passives then you should find this a breeze to build. Head on over to my downloads page to get yourself a copy of gerbers that can be directly uploaded to Elecrow, ITead, Seeed or any other of your favourite prototyping houses.

    Bare PCBs for sale

    I’ve got quite a few of these blank boards left over from the batch that I received from Elecrow and I’m happy to sell them on a first-come-first-served basis.


    Final words

    That’s all for now, I hope you’ve enjoyed this article and if you’d like to leave a comment then please do so in the comments section below. Alternatively if you got a bit more to say then please head over to the forum and speak your mind!

    Read more Here


    More Articles to Read

    #FreePCB via Twitter to 2 random RTs
    #FreePCB via Twitter to 2 random RTs
    Estimating Power for ADSP-BF561 Blackfin® Processors
    Estimating Power for ADSP-BF561 Blackfin® Processors
    Teach Your Arduino to Switch Itself Off!
    Teach Your Arduino to Switch Itself Off!
    Control a tracked robot with your mind (or joystick)
    Control a tracked robot with your mind (or joystick)
    A 400W (1kW Peak) 100A electronic load using linear MOSFETs
    A 400W (1kW Peak) 100A electronic load using linear MOSFETs
    Shirt Pocket Transceiver with the Si5351 and OLED
    Shirt Pocket Transceiver with the Si5351 and OLED
    All metal C930e webcam
    All metal C930e webcam
    The Soldering Tools That Make Your Life Easier
    The Soldering Tools That Make Your Life Easier
    App note: Operation evaluation of ultra low ON resistance MOSFET supporting quick charge for 1 c ...
    App note: Operation evaluation of ultra low ON resistance MOSFET supporting quick charge for 1 cell Lithium ion battery protection
    Synthesized Sidetone
    Synthesized Sidetone