Back to main page

STM32F10x Standard Peripherals Library: Coding rules and conventions

 

Copyright 2010 STMicroelectronics

 

 

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

Acronyms

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

Acronym

Peripheral/unit

 ADC

 Analog/digital converter

 BKP

 Backup registers

 CAN

 Controller area network

 CEC

 Consumer Electronics Control

 CRC

 CRC calculation unit

 DAC

 Digital to analog converter

 DBGMCU

 Debug MCU

 DMA

 DMA controller

 EXTI

 External interrupt/event controller

 FSMC

 Flexible static memory controller

FLASH

Flash memory

 GPIO

 General purpose I/O

 I2C

 Inter-integrated circuit

 I2S

 Inter-integrated sound

 IWDG

 Independent watchdog

 NVIC

 Nested vectored interrupt controller

 PWR

 Power controller

 RCC

 Reset and clock controller

 RTC

 Reset and clock controller

SDIO

SDIO interface

SPI

Serial peripheral interface

SysTick

System tick timer

TIM

Advanced-control, general-purpose or basic timer

USART

Universal synchronous asynchronous receiver transmitter

WWDG

Window watchdog

  Back to Top

Naming conventions

The STM32F10x 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 ‘stm32f10x_’.
  • 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 STM32F10x 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_PinRemapConfig.
  • 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.

  Back to Top

Coding rules

This section describes the coding rules used in the Standard Peripherals library.

Variable types

Specific variable types are already defined with a fixed type and size. These types are defined in the file stm32f10x.h

typedef enum
{
  FALSE = 0,
  TRUE = !FALSE
}
bool;

typedef enum {
  RESET = 0,
  SET = !RESET
}
FlagStatus, ITStatus, BitStatus;

typedef enum {
  DISABLE = 0,
  ENABLE = !DISABLE
}
FunctionalState;

typedef enum {
  ERROR = 0,
  SUCCESS = !ERROR
}
ErrorStatus;

Peripheral’s registers

Peripheral’s registers are accessed through a pointer of structure. Each peripheral has its own structure and pointer. All the structures and declarations are defined in the stm32f10x.h file.

Registers structure
The example below illustrates the Serial Peripheral Interface (SPI)  registers structure declaration:

/**
  * @brief Serial Peripheral Interface
  */

typedef struct
{
  __IO uint16_t CR1;
  uint16_t  RESERVED0;
  __IO uint16_t CR2;
  uint16_t  RESERVED1;
  __IO uint16_t SR;
  uint16_t  RESERVED2;
  __IO uint16_t DR;
  uint16_t  RESERVED3;
  __IO uint16_t CRCPR;
  uint16_t  RESERVED4;
  __IO uint16_t RXCRCR;
  uint16_t  RESERVED5;
  __IO uint16_t TXCRCR;
  uint16_t  RESERVED6;
  __IO uint16_t I2SCFGR;
  uint16_t  RESERVED7;
  __IO uint16_t I2SPR;
  uint16_t  RESERVED8; 
} SPI_TypeDef;

Register names are the register acronyms written in upper case for each peripheral.
RESERVED indicates a reserved field (i being an integer that indexes the reserved field).

Peripheral declaration
The following example shows the declaration of the SPI peripheral:

#define PERIPH_BASE ((u32)0x40000000)
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
...
/* SPI2 Base Address definition*/
#define SPI2_BASE (APB1PERIPH_BASE + 0x3800)

The peripheral registers are accessed as follows:

SPI1->CR1 = 0x0001;

Each peripheral has several dedicated registers which contain different flags. Registers are defined within a dedicated structure for each peripheral. Flags are defined as acronyms written in upper case and preceded by ‘PPP_FLAG_’. Flag definition is adapted to each peripheral case and defined in stm32f10x_ppp.h file.

Registers bits
All the peripheral registers bits are defined as constants in the stm32f10x.h file. They are defined as acronyms written in upper-case into the form:

PPP_<register_name>_<bit_name>

Example:

#define SPI_CR2_RXDMAEN                     ((uint8_t)0x01)  /*!<Rx Buffer DMA Enable */
#define SPI_CR2_TXDMAEN                     ((uint8_t)0x02)  /*!<Tx Buffer DMA Enable */
#define SPI_CR2_SSOE                        ((uint8_t)0x04)  /*!<SS Output Enable */
#define SPI_CR2_ERRIE                       ((uint8_t)0x20)  /*!<Error Interrupt Enable */
#define SPI_CR2_RXNEIE                     ((uint8_t)0x40)  /*!<RX buffer Not Empty Interrupt Enable */
#define SPI_CR2_TXEIE                       ((uint8_t)0x80)  /*!<Tx buffer Empty Interrupt Enable */

Bit-Banding


The Cortex-M3 memory map includes two bit-band memory regions. These regions map each word in an alias region of memory to a bit in a bit-band region of memory. Writing to a word in the alias region has the same effect as a read-modify-write operation on the targeted bit in the bit-band region.

All the STM32F10x peripheral registers are mapped in a bit-band region. This feature is consequently intensively used in functions which perform single bit set/reset in order to reduce and optimize code size.

  1. Mapping formula

The mapping formula shows how to link each word in the alias region to a corresponding target bit in the bit-band region. The mapping formula is given below:

bit_word_offset = (byte_offset x 32) + (bit_number + 4)
bit_word_addr = bit_band_base + bit_word_offse
t

where:

  • bit_word_offset is the position of the target bit in the bit-band memory region
  • bit_word_addr is the address of the word in the alias memory region that maps to the targeted bit.
  • bit_band_base is the starting address of the alias region
  • byte_offset is the number of the byte in the bit-band region that contains the targeted bit
  • bit_number is the bit position (0-7) of the targeted bit.

 

  1. Example of implementation

The following example shows how to map the PLLON[24] bit of RCC_CR register in the alias region:

/* Peripheral base address in the bit-band region */
#define PERIPH_BASE ((u32)0x40000000)
/* Peripheral address in the alias region */
#define PERIPH_BB_BASE ((u32)0x42000000)
/* ----- RCC registers bit address in the alias region ------ */
#define RCC_OFFSET (RCC_BASE - PERIPH_BASE)
/* --- CR Register ---*/
/* Alias word address of PLLON bit */
#define CR_OFFSET (RCC_OFFSET + 0x00)
#define PLLON_BitNumber 0x18
#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32
(PLLON_BitNumber * 4))
To code a function which enables/disables the PLL, the usual method is the following:
...
#define CR_PLLON_Set ((u32)0x01000000)
#define CR_PLLON_Reset ((u32)0xFEFFFFFF)
...
void RCC_PLLCmd(FunctionalState NewState)
{
if (NewState != DISABLE)
{ /* Enable PLL */
RCC->CR |= CR_PLLON_Set;
}
else
{ /* Disable PLL */
RCC->CR &= CR_PLLON_Reset;
}
}
Using bit-band access this function will be coded as follows:
void RCC_PLLCmd(FunctionalState NewState)
{
*(vu32 *) CR_PLLON_BB = (u32)NewState;
}

Back to Top

Run-time checking

The firmware library implements run-time failure detection by checking the input values of all library functions. The run-time checking is achieved by using an assert_param macro. This macro is used in all library functions which have at least an input parameter. It allows the user to check that the input value lies within the defined parameter values.

EXTI_Init function example

stm32f10x_exti.c
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
{
  /* Check the parameters */
  assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));
  assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));
  assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line)); 
  assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));
...
}

 

stm32f10x_exti.h
#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event))
#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \
                                  ((TRIGGER) == EXTI_Trigger_Falling) || \
                                  ((TRIGGER) == EXTI_Trigger_Rising_Falling))

#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFFF00000) == 0x00) && ((LINE) != (uint16_t)0x00))


If the expression passed to the assert_param macro is false, the assert_failed function is called, otherwise nothing happens.

Two implementation of assert_failed function are provided, depending on USE_FULL_ASSERT define (declared in stm32f10x_conf.h file).

  • "#define USE_FULL_ASSERT   1 " line is uncommented, if the expression passed to the assert_param macro is false, the assert_failed function  will have as input  the name of the source file and the source line number of the call that failed.
  • "#define FULL_ASSERT   1" line is commented, if the expression passed to the assert_param macro is true, the assert_failed function will have takes no does not returns the name of the source file and the source line number of the call that failed.


The assert_param macro is implemented in stm32f10x_conf.h as follows:

#ifdef  USE_FULL_ASSERT
/**
  * @brief  The assert_param macro is used for function's parameters check.
  * @param expr: If expr is false, it calls assert_failed function
  *   which reports the name of the source file and the source
  *   line number of the call that failed.
  *   If expr is true, it returns no value.
  * @retval : None
  */
  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
   void assert_failed(uint8_t* file, uint32_t line);
#else
   #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */

 

The assert_failed function is implemented in the main.c file or in any other user C files and can be modified by the user in order to take action when an error occurs.

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

It is recommended to use run-time checking during application code development and debugging, and to remove it from the final application to improve code size and speed (because of the overhead it introduces).
However if the user wants to keep this functionality in his final application, he can re-use the assert_param macro defined within the library to test the parameter values before calling the library functions.

  Back to Top

Previous                                                                                                                                                                                                               Next

For complete documentation on STM32 (CORTEX M3) 32-bit Microcontrollers platform visit www.st.com/STM32