STM32L1xx Standard Peripheral Library

From EdWiki

The STM32 parts are well supported by the Standard Peripheral Library which provides firmware to support all of the peripherals on the various STM32 parts. There are currently five families of STM32 MCUs – STM32 F0, STM32 F1, STM32 F2, STM32 L1 and STM32 F4 supported by different, but structurally similar, firmware libraries. While these families share many peripherals, some care is needed when moving projects between these families.

The STM32L1xx Standard Peripherals Library distributed by STMicroelectronics is a complete package, consisting of device drivers for all of the standard device peripherals, for STM32L Ultra Low Power High-, Medium-Density and Medium-Density Plus Devices 32-bit Flash microcontrollers. This library is a firmware package which contains a collection of routines, data structures and macros covering the features of STM32L peripherals. It includes a description of the device drivers plus a set of examples for each peripheral. The firmware library allows any device to be used in the user application without the need for in-depth study of each peripheral’s specifications.

The STM32L1xx Standard Peripherals Library covers 3 abstraction levels, and includes:

  • A complete register address mapping with all bits, bit fields and registers declared in C. This avoids a cumbersome task and more important, it brings the benefits of a bug free reference mapping file, speeding up the early project phase.
  • A collection of routines and data structures which covers all peripheral functions (drivers with common API). It can directly be used as a reference framework, since it also includes macros for supporting core-related intrinsic features and common constants and data types definition.
  • A set of examples covering all available peripherals with template projects for the most common development toolchains. With the appropriate hardware evaluation board, this allows to get started with a brand new micro within few hours.

The STM32L1xx Standard Peripherals Library, which provide low-level access to all of the peripherals of the STM32L1 series. While these libraries are relatively complicated, this article will provide a road map to their use as well some initial short-cuts. The advantages of using these firmware libraries are that they abstract much of the bit-level detail required to program the STM32, they are relatively mature and have been thoroughly tested, and they enable the development of application code that is portable across the STM32 family.

The STM32L1xx Standard Peripherals Library, while easy to install, can be quite challenging to use. There are many separate modules (one for each peripheral) as well as large numbers of definitions and functions for each module. Furthermore, compiling with these modules requires appropriate compiler flags as well as a few external files (a linker script file, and a start-up code). The approach taken in this documentation is to provide a basic Eclipse based build environment which can be easily extended as we explore the various peripherals. Rather than attempt to fully describe this peripheral library, we present modules as needed and then only the functions/definitions we require.

Stm32l1xx stdperiph lib.png

It is helpful to understand the layout of STM32L1xx Standard Peripherals Software Library. The following figure provides a simplified view of the directory structure. The library consists of two major sub-directories – STM32L1xx_StdPeriph_Driver and CMSIS. CMSIS stands for Cortex Micro-controller Software Interface Standard and provides the common low-level software required for all ARM Cortex parts. For example, the core_cm3.* files provide access to the interrupt controller, the system tick timer, and the debug and trace modules. The STM32L1xx_StdPeriph_Driver directory provides roughly one module for each of the peripherals available in the STM32 L1xx family.

All of the peripherals are memory-mapped which means that the core interacts with the peripheral hardware by reading and writing peripheral registers using load and store instructions. All of the various peripheral registers are documented in the various STM32 reference manuals. The reference manual for ultra low power STM32L1xx device is RM0038. The documentation include bit-level definitions of the various registers and text to help interpret those bits. The actual physical addresses are also found in the reference manuals.

Typically, each peripheral will have control registers to configure the peripheral, status registers to determine the current peripheral status, and data registers to read data from and write data to the peripheral. Each GPIO port (GPIOA, GPIOB, etc.) has seven registers. Two are used to configure the sixteen port bits individually, two are used to read/write the sixteen port bits in parallel.

In addition to providing the addresses of the peripherals, stm32l1xx.h also provides C language level structures that can be used to access each peripherals. For example, the GPIO ports are defined by the following register structure.

typedef struct
  __IO uint32_t MODER;        /* GPIO port mode register,                     Address offset: 0x00      */
  __IO uint16_t OTYPER;       /* GPIO port output type register,              Address offset: 0x04      */
  uint16_t RESERVED0;         /* Reserved,                                    0x06                      */
  __IO uint32_t OSPEEDR;      /* GPIO port output speed register,             Address offset: 0x08      */
  __IO uint32_t PUPDR;        /* GPIO port pull-up/pull-down register,        Address offset: 0x0C      */
  __IO uint16_t IDR;          /* GPIO port input data register,               Address offset: 0x10      */
  uint16_t RESERVED1;         /* Reserved,                                    0x12                      */
  __IO uint16_t ODR;          /* GPIO port output data register,              Address offset: 0x14      */
  uint16_t RESERVED2;         /* Reserved,                                    0x16                      */
  __IO uint16_t BSRRL;        /* GPIO port bit set/reset low registerBSRR,    Address offset: 0x18      */
  __IO uint16_t BSRRH;        /* GPIO port bit set/reset high registerBSRR,   Address offset: 0x1A      */
  __IO uint32_t LCKR;         /* GPIO port configuration lock register,       Address offset: 0x1C      */
  __IO uint32_t AFR[2];       /* GPIO alternate function low register,        Address offset: 0x20-0x24 */
  __IO uint16_t BRR;          /* GPIO bit reset register,                     Address offset: 0x28      */
  uint16_t RESERVED3;         /* Reserved,                                    0x2A                      */
} GPIO_TypeDef;

The register addresses of the various ports are defined in the library as (the following defines are from stm32l1xx.h)

#define PERIPH_BASE           ((uint32_t)0x40000000) /* Peripheral base address in the alias region */
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
#define GPIOA_BASE            (AHBPERIPH_BASE + 0x0000)
#define GPIOB_BASE            (AHBPERIPH_BASE + 0x0400)
#define GPIOC_BASE            (AHBPERIPH_BASE + 0x0800)

The Standard Peripheral Library provides modules for each peripheral that can greatly simplify the task of reading, and writing. For example, the following is a subset of the procedures available for managing GPIO ports:

void GPIO_Init(GPIO_TypeDef* GPIOx , GPIO_InitTypeDef* GPIO_InitStruct);
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); 
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin , BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx , uint16_t PortVal);

The initialization function (GPIO_Init) provides an interface for configuring individual port bits. The remaining functions provide interfaces for reading and writing (also setting and resetting) both individual bits and the 16 port bits in parallel.

The following figure provides a global view of the STM32L1xx Standard Peripherals Library usage and interaction with other firmware components.

Stm32l1xx stdperiph lib interaction.png

The STM32L1xx Standard Peripherals Library uses rules and conventions described in the sections below.

The Table below describes the acronyms used in the firmware library.

Analog/digital converter
Analog Comparators
CRC calculation unit
Digital to analog converter
Debug MCU
DMA controller
External interrupt/event controller
Flash memory
General purpose I/O
Inter-integrated circuit
Independent watchdog
LCD Glass Controller
Nested vectored interrupt controller
Power controller
Reset and clock controller
Routing Interface
Reset and clock controller
Serial peripheral interface
System Configuration
System tick timer
Advanced-control, general-purpose or basic timer
Universal synchronous asynchronous receiver transmitter
Window watchdog
Flexible static memory controller
AES hardware accelerator
Secure digital input/output interface
Integrated Interchip Sound
Operational amplifiers

The STM32L1xx Standard Peripherals Library uses the following naming conventions:

  • PPP refers to any peripheral acronym, for example ADC.
  • System and source/header file names are preceded by the prefix stm32l1xx_.
  • Constants used in one file are defined within this file. A constant used in more than one file is defined in a header file. All constants are written in upper case.
  • Registers are considered as constants. Their names are in upper case. In most cases, the same acronyms as in the STM32L1xx reference manual document are used.
  • Names of peripheral’s functions are preceded by the corresponding peripheral acronym in upper case followed by an underscore. The first letter in each word is in upper case, for example USART_SendData. Only one underscore is allowed in a function name to separate the peripheral acronym from the rest of the function name.
  • Functions used to initialize the PPP peripheral according to parameters specified in PPP_InitTypeDef are named PPP_Init, for example TIM_Init.
  • Functions used to reset the PPP peripheral registers to their default values are named PPP_DeInit, for example TIM_DeInit.
  • Functions used to fill the 'PPP_InitTypeDef structure with the reset values of each member are named 'PPP_StructInit, for example USART_StructInit.
  • Functions used to enable or disable the specified PPP peripheral are named PPP_Cmd, for example USART_Cmd.
  • Functions used to enable or disable an interrupt source of the specified PPP peripheral are named PPP_ITConfig, for example RCC_ITConfig.
  • Functions used to enable or disable the DMA interface of the specified PPP peripheral are named PPP_DMAConfig, for example TIM_DMAConfig.
  • Functions used to configure a peripheral function always end with the string Config, for example GPIO_PinAFConfig.
  • Functions used to check whether the specified PPP flag is set or reset are named PPP_GetFlagStatus, for example I2C_GetFlagStatus.
  • Functions used to clear a PPP flag are named PPP_ClearFlag, for example I2C_ClearFlag.
  • Functions used to check whether the specified PPP interrupt has occurred or not are named PPP_GetITStatus, for example I2C_GetITStatus.
  • Functions used to clear a PPP interrupt pending bit are named PPP_ClearITPendingBit, for example I2C_ClearITPendingBit.

Each peripheral has a source code file stm32l1xx_ppp.c and a header file stm32l1xx_ppp.h. The stm32l1xx_ppp.c file contains all the firmware functions required to use the PPP peripheral. A single memory mapping file, stm32l1xx.h, is supplied for all peripherals. It contains all the register declarations and bits definition. This is the only file that needs to be included in the user application to interface with the library. The stm32l1xx_conf.h file is used to specify the set of parameters to interface with the library drivers before running any application. The table bellow lists and describes the different files used by the Standard Peripherals library:

File Name
Peripheral’s drivers configuration file

The user can enable or disable peripheral header file inclusion by using the template This file can also be used to enable or disable the Library run-time failure detection before compiling the firmware library drivers, through the preprocessor define USE_FULL_ASSERT

Header file of PPP peripheral

This file includes the PPP peripheral function and variable definitions used within these functions.

Driver source code file of PPP peripheral written in C language
Header file including all interrupt handlers prototypes
Template source file containing the interrupt service routine (ISR) for CortexM3 exceptions. User can add additional ISR(s) for the used peripheral(s) (for the available peripheral interrupt handler's name, please refer to the startup file startup_stm32l1xx_md.s).

The table below lists and describes the different STM32L1xx CMSIS files:

File name
CMSIS Cortex-M3 STM32L1xxxx device peripheral access layer header file.

The file is the unique include file that the application programmer is using in the C source code, usually in main.c. This file contains:

  • configuration section that allows to select:
    the device used in the target application
    to use or not the peripheral’s drivers in application code (i.e. code will be based on direct access to peripheral’s registers rather than drivers API) , this option is controlled by the
  • to change few application-specific parameters such as the HSE crystal frequency
    data structures and the address mapping for all peripherals
    peripheral's registers declarations and bits definition
    macros to access peripheral’s registers hardware
CMSIS Cortex-M3 STM32F10xxx device peripheral access layer system header file.
CMSIS Cortex-M3 STM32F10xxx device peripheral access layer system source file.
Ultra Low Power Medium density devices startup file.
Ultra Low Power Medium density Plus devices startup file.
Ultra Low Power High density devices startup file.

The Standard Peripherals library file inclusions relationship is shown in the following figure:

Stm32l1xxxx stdperiph lib relationship.png

Since the Standard Peripherals Library is generic and covers all peripheral functionalities, the size and/or execution speed of the application code may not be optimized. For many applications, the library may be used as is. However, for applications having tough constraints in terms of code size and/or execution speed, the library drivers should be used as a reference on how to configure the peripheral and tailor them to specific application requirements.