STM32 and the standard peripheral libraries

I recently acquired a number of the ST discovery boards, each is an evaluation boards with an stlink programmer and a target controller. The three I have are the stm32f1xx with a value line stm32f100 cortex m3 cpu, The stm32f0xx with an stm32f051 cortex M0 CPU and the stm32l1xx with a low power stm32l152 cortex m3 CPU.

I hate duplicating effort so built my own startup repository with the standard CMSIS based library for all 3 of these families and started with the ubiquitous blink program. The ST approach to the standard libraries is to build the necessary code at the same time as building your application. I prefer to build a link library for them, or should that be a number of link libraries as each supports a range of members of each CPU. For example the stm32f1xx can be built for low density (LD), medium density (MD), high density (HD), extreme density (XD), Communication line (CL) and value line versions of LD, MD and HD. Along with the use of asserts to check the parameters (Debug versions). I did the same for the same for the stm32f0xx library (LD and MD) and the stm32l1xx library (LD,MD,HD).

Then I put together a blink program but using the systick and an interrupt callback to handle the output toggle. For a future projects I wanted a way to set up periodic calls. This means the main() function consists of while 1 { WFI();}.

Got it working on the value line chip. Lets rebuild for the stm32l1xx low power board. This is where I started feeling the friction in the ST libraries.

Every include file is named for the CPU family, great idea if you throw them all into the same directory. I would like to change an include location in the makefile and get the relevant files for the alternate chip. At least there is consistency, i.e. stm32f1xx_gpio.h -> stm32l1xx_gpio.h.

The function names are the generally the same so I did not have to change them but the init structure contents are different, this is where it comes obvious that the library is a very thin wrapper over the underlying cpu. Great for getting something going with a good debug point for catching errors, the assert handler, but with a large code size penalty for setting devices up. It would be nice if the stm32f1xx library was updated to CMSIS v3 and made more consistent with the other two.

Then come the functions for enabling the peripheral clocks, could we not abstract this away and just have an enable clock on USART1 or whatever peripheral device and then let the library update AHB, AHB2, APB, APB2 as required. Then the code overhead becomes valuable.

The libraries also have value in that you do not need to read too much of the datasheet to get a project started but I can see when optimising code size replacing calls to device init to be 3 or 4 simple register updates.

On a positive note the stm32f0xx and stm32lxx libraries are much more in step. I think when building for the stm32f051 I only had to change the clock enables and the alternate function select for the GPIO pin. This was another friction point, GPIO_AF_USART1 is obvious GPIO_AF_1 is not.

At least I now have a single git repo with the 3 libraries and a way of switching the build from one target to another now I can get on with my DMX controller project. To drive 32 mimics LEDs from a DMX extension on a Loxone home automation controller.