AN3422 STMICROELECTRONICS | Alldatasheet
Document overview
- Manufacturer or author: Provided By ALLDATASHEET.COM(FREE DATASHEET DOWNLOAD SITE)
- PDF pages: 52
Technical content
Datasheet sections
- 1 Introduction
- 2 STM32L1 family overview
- 3 Hardware migration
- 4 Peripheral migration
- 4.1 STM32 product cross-compatibility
- 4.2 System architecture
- 4.3 Memory mapping
- 4.4 RCC
- 4.5 DMA
- 4.6 Interrupts
- 4.7 GPIO
- 4.8 EXTI source selection
- 4.9 FLASH
- 4.10 ADC
- 4.11 PWR
- 4.12 RTC
- 5 Firmware migration using the library
- 5.1 Migration steps
- 5.2 RCC
- 5.3 FLASH
- 5.4 GPIO
- 5.4.1 Output mode
- 5.4.2 Input mode
- 5.4.3 Analog mode
- 5.4.4 Alternate function mode
- 5.5 EXTI
- 5.6 ADC
- 5.7 PWR
March 2012 Doc ID 018976 Rev 2 1/52 AN3422 Application note Migration of microcontroller applications from STM32F1 to STM32L1 series
1 Introduction
For designers of STM32 microcontroller applications, it is important to be able to easily replace one microcontroller type by another one in the same product family. Migrating an application to a different microcontroller is often needed, when product requirements grow, putting extra demands on memory size, or increasing the number of I/Os. On the other hand, cost reduction objectives may force you to switch to smaller components and shrink the PCB area. This application note is written to help you and analyze the steps you need to migrate from an existing STM32F1 devices based design to STM32L1 devices. It groups together all the most important information and lists the vital aspects that you need to address. To migrate your application from STM32F1 series to STM32L1 series, you have to analyze the hardware migration, the peripheral migration and the firmware migration. To benefit fully from the information in this application note, the user should be familiar with the STM32 microcontroller family. Y ou can refer to the following documents that are available from www.st.com.
- The STM32F1 family reference manuals (RM0008 and RM0041), the STM32F1 datasheets, and the STM32F1 Flash programming manuals (PM0075, PM0063 and PM0068).
- The STM32L1 family reference manual (RM0038), the STM32L1 datasheets, and the STM32F1 Flash and EEPROM programming manual (PM0062). For an overview of the whole STM32 series and a comparison of the different features of each STM32 product series, please refer to AN3364 Migration and compatibility guidelines for STM32 microcontroller applications.
2 STM32L1 family overview
STM32L1 High-density, all dedicated to ultra low power and low voltage applications.
- STM32L1: Designed for ultra-low-power applications that are energy-aware and seek to achieve the absolute lowest power consumption. The L1 series maintains compatibility with the F1 series. – Medium-density devices are STM32L151xx and STM32L152xx microcontrollers where the Flash memory density ranges between 64 and 128 Kbyte – Medium-density+ devices are STM32L151xx, STM32L152xx and STM32L162xx microcontrollers where the Flash memory density is 256 Kbyte – High-density devices are STM32L151xx, STM32L152xx and STM32L162xx microcontrollers where the Flash memory density is 384 Kbyte The ultralow power STM32L1 Medium-density, STM32L1 Medium-density+ and STM32L1 High-density are fully pin-to-pin, software and feature compatible.
Table 1. STM32L1 peripherals compatibility analysis
Table 1. STM32L1 peripherals compatibility analysis (continued)
3 Hardware migration
minor differences between packages. In fact, the STM32L1 series maintains a close compatibility with the whole STM32F1 series. in bold in the table below). Table 2. STM32F1 series and STM32L1 series pinout differences
Figure 1. Compatible board design: LQFP144
Figure 2. Compatible board design: LQFP100
Peripheral migration AN3422 12/52 Doc ID 018976 Rev 2
4 Peripheral migration
As shown in Table 3 on page 13, there are three categories of peripherals. The common peripherals are supported with the dedicated firmware library without any modification, except if the peripheral instance is no longer present, you can change the instance and of course all the related features (clock configuration, pin configuration, interrupt/DMA request). The modified peripherals such as: FLASH, ADC, RCC, PWR, GPIO and RTC are different from the F1 series ones and should be updated to take advantage of the enhancements and the new features in L1 series. All these modified peripherals in the L1 series are enhanced to obtain lower power consumption, with features designed to meet new market requirements and to fix some limitations present in the F1 series.
4.1 STM32 product cross-compatibility
The STM32 series embeds a set of peripherals which can be classed in three categories:
- The first category is for the peripherals which are by definition common to all products. Those peripherals are identical, so they have the same structure, registers and control bits. There is no need to perform any firmware change to keep the same functionality at the application level after migration. All the features and behavior remain the same.
- The second category is for the peripherals which are shared by all products but have only minor differences (in general to support new features), so migration from one product to another is very easy and does not need any significant new development effort.
- The third category is for peripherals which have been considerably changed from one product to another (new architecture, new features...). For this category of peripherals, migration will require new development at application level. Table 3 gives a general overview of this classification.
Table 3. STM32 peripheral compatibility analysis F1 versus L1 series
4.2 System architecture
STM32L Medium-density+ and STM32L High-density).
4.3 Memory mapping
allow them to operate at maximum speed. Table 3. STM32 peripheral compatibility analysis F1 versus L1 series (continued)
Table 4. IP bus mapping differences between STM32F1 and STM32L1 series
4.4 RCC
series vs. STM32F1 series are presented in the table below. Table 5. RCC differences between STM32F1 and STM32L1 series
2 PLLs for I2S, Ethernet and
8 MHz after reset using HSI
32 MHz
2 MHz after reset using MSI
Table 5. RCC differences between STM32F1 and STM32L1 series (continued)
- Performance versus VCORE ranges: The maximum system clock frequency and FLASH
- System clock configuration: when moving from F1 series to L1 series only a few
Table 6. Performance versus V CORE ranges
1 WS 0 WS
AN3422 Peripheral migration Doc ID 018976 Rev 2 21/52 enable/disable, 64-bit access enable/disable...) or/and the PLL parameters configuration: a) If the HSE or HSI is used directly as system clock source, in this case only the Flash parameters should be modified. b) If PLL (clocked by HSE or HSI) is used as system clock source, in this case the Flash parameters and PLL configuration need to be updated. Table 7 below provides an example of porting a system clock configuration from F1 to L1 series: – STM32F105/7 Connectivity Line running at maximum performance: system clock at 72 MHz (PLL, clocked by the HSE, used as system clock source), Flash with 2 wait states and Flash prefetch queue enabled. – L1 series running at maximum performance: system clock at 32 MHz (PLL, clocked by the HSE, used as system clock source), Flash with 1 wait state, Flash prefetch and 64-bit access enabled. As shown in the table below, only the Flash settings and PLL parameters (code in Bold Italic) need to be rewritten to run on L1 series. However, HSE, AHB prescaler and system clock source configuration are left unchanged, and APB prescalers are adapted to the maximum APB frequency in the L1 series. Note: 1 The source code presented in the table below is intentionally simplified (time-out in wait loop removed) and is based on the assumption that the RCC and Flash registers are at their reset values.
2 For STM32L1xx you can use the clock configuration tool,
STM32L1xx_Clock_Configuration.xls, to generate a customized system_stm32l1xx.c file containing a system clock configuration routine, depending on your application requirements. For more information, refer to AN3309 “Clock configuration tool for STM32L1xx microcontrollers”
Table 7. Example of migrating system clock configuration code from F1 to L1
- Peripheral access configuration: since the address mapping of some peripherals has
[enable/disable] or [enter/exit] the peripheral [clock] or [from reset mode].
- Peripheral clock configuration: some peripherals have a dedicated clock source
operating conditions. This configuration is done using ADC_CCR[ADCPRE] bits. Table 8. RCC registers used for pe ripheral access configuration
4.5 DMA
STM32F1 and STM32L1 series uses the same DMA controller fully compatible. more peripherals. It has an arbiter for handling the priority between DMA requests. in STM32F1 series and STM32L1 series. Table 9. DMA request differences between STM32F1 series and STM32L1 series
Table 9. DMA request differences between STM32F1 series and STM32L1 series (continued)
4.6 Interrupts
The table below presents the interrupt vectors in STM32L1 series vs. STM32F1 series.
- ADC: in the F1 series there are two interrupt vectors for the ADCs; ADC1_2 and ADC3.
However in L1 series there is a single interrupt vector for ADC1; ADC1_IRQ.
- As in STM32L1 series there are no CAN or TIM1 peripherals, their corresponding IRQs
are now mapped to new peripherals: COMP , DAC, TIM9, TIM10, TIM11 and LCD.
- For High-density value line devices, the DAC DMA r equests are mapped respectively on DMA1 Channel 3 and DMA1
Table 10. Interrupt vector differences between STM32F1 series and STM32L1 series
0 WWDG WWDG
1 PVD PVD
2 TAMPER TAMPER_ STAMP
4 FLASH FLASH
6 EXTI0 EXTI0
7 EXTI1 EXTI1
8 EXTI2 EXTI2
9 EXTI3 EXTI3
10 EXTI4 EXTI4
11 DMA1_Channel1 DMA1_Channel1
12 DMA1_Channel2 DMA1_Channel2
13 DMA1_Channel3 DMA1_Channel3
14 DMA1_Channel4 DMA1_Channel4
15 DMA1_Channel5 DMA1_Channel5
16 DMA1_Channel6 DMA1_Channel6
17 DMA1_Channel7 DMA1_Channel7
18 ADC1_2
19 CAN1_TX / USB_HP_CAN_TX ((1) USB_HP
20 CAN1_RX0 / USB_LP_CAN_RX0 (1) USB_LP
21 CAN1_RX1 DAC
22 CAN1_SCE COMP
23 EXTI9_5 EXTI9_5
24 TIM1_BRK / TIM1_BRK _TIM9 (1) TIM9
25 TIM1_UP / TIM1_UP_TIM10 (1) TIM10
26 TIM1_TRG_COM /
27 TIM1_CC LCD
28 TIM2 TIM2
29 TIM3 TIM3
30 TIM4 TIM4
31 I2C1_EV I2C1_EV
32 I2C1_ER I2C1_ER
33 I2C2_EV I2C2_EV
34 I2C2_ER I2C2_ER
35 SPI1 SPI1
36 SPI2 SPI2
37 USART1 USART1
38 USART2 USART2
39 USART3 USART3
40 EXTI15_10 EXTI15_10
41 RTC_Alarm RTC_Alarm
42 OTG_FS_WKUP / USBWakeUp
43 TIM8_BRK / TIM8_BRK_TIM12 (1) TIM6
44 TIM8_UP / TIM8_UP_TIM13 (1) TIM7
45 TIM8_TRG_COM /
46 TIM8_CC TIM5
47 ADC3 SPI3
48 FSMC UART4
49 SDIO UART5
50 TIM5 DMA2_Channel1
51 SPI3 DMA2_Channel2
52 UART4 DMA2_Channel3
53 UART5 DMA2_Channel4
54 TIM6 / TIM6_DAC (1) DMA2_Channel5
55 TIM7 AES
56 DMA2_Channel1 COMP_ACQ
57 DMA2_Channel2 NA
58 DMA2_Channel3 NA
59 DMA2_Channel4 / DMA2_Channel4_5(1) NA
60 DMA2_Channel5 NA
61 ETH NA
62 ETH_WKUP NA
63 CAN2_TX NA
64 CAN2_RX0 NA
65 CAN2_RX1 NA
66 CAN2_SCE NA
67 OTG_FS NA
- Depending on the product line used.
4.7 GPIO
- GPIO mapped on AHB bus for better performance
- I/O pin multiplexer and mapping: pins are connected to on-chip peripherals/modules through a multiplexer that allows only one peripheral alternate function (AF) connected to an I/O pin at a time. In this way, there can be no conflict between peripherals sharing the same I/O pin.
- More possibilities and features for I/O configuration The L1 GPIO peripheral is a new design and thus the architecture, features and registers are different from the GPIO peripheral in the F1 series, so any code written for the F1 series using the GPIO needs to be rewritten to run on L1 series. For more information about STM32L1’s GPIO programming and usage, please refer to the "I/O pin multiplexer and mapping" section in the GPIO chapter of the STM32L1xx Reference Manual (RM0038). The table below presents the differences between GPIOs in the STM32F1 series and STM32L1 series.
Table 11. GPIO differences between STM32F1 series and STM32L1 series
2 MHz
10 MHz
50 MHz
40 MHz
Table 11. GPIO differences between STM32F1 series and STM32L1 series (continued)
AN3422 Peripheral migration Doc ID 018976 Rev 2 31/52 Alternate function mode In STM32F1 series 1. The configuration to use an I/O as alternate function depends on the peripheral mode used, for example the USART Tx pin should be configured as alternate function push- pull while USART Rx pin should be configured as input floating or input pull-up. 2. To optimize the number of peripheral I/O functions for different device packages (especially with those with low pin count), it is possible to remap some alternate functions to other pins by software, for example the USART2_RX pin can be mapped on PA3 (default remap) or PD6 (by software remap). In STM32L1 series 1. Whatever the peripheral mode used, the I/O must be configured as alternate function, then the system can use the I/O in the proper way (input or output). 2. The I/O pins are connected to on-chip peripherals/modules through a multiplexer that allows only one peripheral’s alternate function to be connected to an I/O pin at a time. In this way, there can be no conflict between peripherals sharing the same I/O pin. Each I/O pin has a multiplexer with sixteen alternate function inputs (AF0 to AF15) that can be configured through the GPIOx_AFRL and GPIOx_AFRH registers: – After reset all I/Os are connected to the system’s alternate function 0 (AF0) – The peripheral alternate functions are mapped by configuring AF1 to AF13 – Cortex-M3 EVENTOUT is ma pped by configuring AF15 3. In addition to this flexible I/O multiplexing architecture, each peripheral has alternate functions mapped on different I/O pins to optimize the number of peripheral I/O functions for different device packages, for example the USART2_RX pin can be mapped on PA3 or PD6 pin Note: Please refer to the “Alternate function mapping” table in the STM32L15x datasheet for the detailed mapping of the system and the peripheral alternate function I/O pins. 4. Configuration procedure – Configure the desired I/O as an alternate function in the GPIOx_MODER register – Select the type, pull-up/pull-down and output speed via the GPIOx_OTYPER, GPIOx_PUPDR and GPIOx_OSPEEDER registers, respectively – Connect the I/O to the desired AFx in the GPIOx_AFRL or GPIOx_AFRH register
4.8 EXTI source selection
In STM32F1 the selection of EXTI line source is performed through EXTIx bits in AFIO_EXTICRx registers, while in L1 series this selection is done through EXTIx bits in SYSCFG_EXTICRx registers. Only the mapping of the EXTICRx registers has been changed, without any changes to the meaning of the EXTIx bits. However, the maximum range of EXTIx bits values is 0b0101 as only 6 GPIO ports are supported in L1 (in F1 series the maximum value is 0b0110).
4.9 FLASH
- New interface, new technology
- New architecture
- New read protection mechanism, 3 read protection levels with JTAG fuse Consequently the L1 Flash programming procedures and registers are different from the F1 series, and any code written for the Flash interface in the F1 series needs to be rewritten to run on L1 series. For more information on programming, erasing and protection of the L1 Flash memory, please refer to the STM32L1xx Flash programming manual (PM0062).
Table 12. FLASH differences between STM32F1 series and STM32L1 series
16 Pages of 256 bytes
4.10 ADC
- New digital interface
- New architecture and new features Program mode Half word Program memory: word/ half page DATA EEPROM memory: byte / half word / word / Double word Read Protection Unprotection Read protection disable RDP = 0xA55A Level 0 no protection RDP = 0xAA Protection Read protection enable RDP != 0xA55A Level 1 memory protection RDP != (Level 2 & Level 0) JTAG fuse NA Level 2 RDP = 0xCC (2) Write protection granularity Protection by 4 Kbyte block Protection by sector User Option bytes STOP STOP STANDBY STANDBY WDG WDG NA BOR level NA BFB2 1. For more details refer to “EEPROM emulat ion in STM32F10x microcontrollers (AN2594) 2. Memory read protection Level 2 is an irre versible operation. When Level 2 is activated, the level of protection cannot be decreased to Level 0 or Level 1.
Table 12. FLASH differences between STM32F1 series and STM32L1 series (continued) Table 13. ADC differences between STM32F1 series and STM32L1 series
Table 13. ADC differences between STM32F1 series and STM32L1 series (continued)
4.11 PWR
Table 14. PWR differences between STM32F1 series and STM32L1 series
- VDD = 2.0 to 3.6 V: external power
- VSSA, VDDA = 2.0 to 3.6 V: external
- VBAT = 1.8 to 3.6 V: power supply for
switch) when VDD is not present.
- VDD = 1.8 V (at power on) or 1.65 V (at power down)
3.6 V, when BOR is not available. regulator. It is provided externally through VDD pins.
- VSSA, VDDA = 1.8 V (at power on) or 1.65 V (at power
1.65 to 3.6 V, when BOR is not available. voltage generated by the embedded step-up converter. are integrated in the BKP peripheral.
executing the WFI or WFE instructions. time when exiting from low power modes. Wakeup Pin 2 and Wakeup Pin 3 Enable/Disable bits. Table 14. PWR differences between STM32F1 series and STM32L1 series (continued)
AN3422 Peripheral migration Doc ID 018976 Rev 2 37/52
4.12 RTC
The STM32L1 series embeds a new RTC peripheral vs. F1 series; the architecture, features and programming interface are different. As consequence the L1 RTC programming procedures and registers are different from the the F1 series, so any code written for the F1 series using the RTC needs to be rewritten to run on L1 series. The L1 RTC provides best-in-class features:
- BCD timer/counter
- Time-of-day clock/calendar with programmable daylight saving compensation
- Two programmable alarm interrupts
- Digital calibration circuit
- Time-stamp function for event saving
- Periodic programmable wakeup flag with interrupt capability
- Automatic wakeup unit to manage low power modes
- 32 backup registers (128 bytes) which are reset when a tamper detection event occurs For more information about STM32L1’s RTC features, please refer to RTC chapter of STM32L1xx Reference Manual (RM0038). For advanced information about the RTC programming, please refer to Application Note AN3371 Using the STM32 HW real-time clock (RTC).
Firmware migration using the library AN3422 38/52 Doc ID 018976 Rev 2
5 Firmware migration using the library
This section describes how to migrate an application based on STM32F1xx Standard Peripherals Library in order to use the STM32L1xx Standard Peripherals Library. The STM32F1xx and STM32L1xx libraries have the same architecture and are CMSIS compliant, they use the same driver naming and the same APIs for all compatible peripheral. Only a few peripheral drivers need to be updated to migrate the application from an F1 series to an L1 series product. Note: In the rest of this chapter (unless otherwise specified), the term “STM32L1xx Library” is used to refer to the STM32L1xx Standard Peripherals Library and the term of “STM32F10x Library” is used to refer to the STM32F10x Standard Peripherals Library.
5.1 Migration steps
To update your application code to run on STM32L1xx Library, you have to follow the steps listed below: 5. Update the toolchain startup files a) Project files: device connections and Flash memory loader. These files are provided with the latest version of your toolchain that supports STM32L1xxx devices. For more information please refer to your toolchain documentation. b) Linker configuration and vector table location files: these files are developed following the CMSIS standard and are included in the STM32L1xx Library install package under the following directory: Libraries\\CMSIS\\Device\\ST\\STM32L1xx. 6. Add STM32L1xx Library source files to the application sources a) Replace the stm32f10x_conf.h file of your application with stm32l1xx_conf.h provided in STM32L1xx Library. b) Replace the existing stm32f10x_it.c/stm32f10x_it.h files in your application with stm32l1xx_it.c/stm32l1xx_it.h provided in STM32L1xx Library. 7. Update the part of your application code that uses the RCC, PWR, GPIO, FLASH, ADC and RTC drivers. Further details are provided in the next section. Note: The STM32L1xx Library comes with a rich set of examples (87 in total) demonstrating how to use the different peripherals (under Project\\STM32L1xx_StdPeriph_Examples\\).
5.2 RCC
- System clock configuration: as presented in section 4.4: RCC the STM32L1 and F1 series have the same clock sources and configuration procedures. However, there are some differences related to the product voltage range, PLL configuration, maximum frequency and Flash wait state configuration. Thanks to the CMSIS layer, these differences are hidden from the application code; you only have to replace the system_stm32f10x.c file by system_stm32l1xx.c file. This file provides an
AN3422 Firmware migration using the library Doc ID 018976 Rev 2 39/52 implementation of SystemInit() function used to configure the microcontroller system at start-up and before branching to the main() program. Note: For STM32L1xx you can use the clock configuration tool, STM32L1xx_Clock_Configuration.xls, to generate a customized SystemInit() function depending on your application requirements. For more information, refer to AN3309 “Clock configuration tool for STM32L1xx microcontrollers” 2. Peripheral access configuration : as presented in section 4.4: RCC you need to call different functions to [enable/disable] or [enter/exit] the peripheral [clock] or [from reset mode]. For example, GPIOA is mapped on AHB bus on L1 series (APB2 bus on F1 series), to enable its clock you have to use the RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); function instead of: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); in the F1 series. Refer to T a b l e4 o n p a g e1 5 for the peripheral bus mapping changes between L1 and F1 series. Peripheral clock configuration a) USB FS Device: in STM32L1 series the USB FS Device require a frequency of 48 MHz to work correctly. The following is an example of the main PLL configuration to obtain 32 MHz as system clock frequency and 48 MHz for the USB FS Device. /* PLL_VCO = HSE_VALUE * PLL_MUL = 96 MHz */ /* USBCLK = PLL_VCO / 2= 48 MHz */ /* SYSCLK = PLL_VCO * PLL_DIV = 32 MHz */ RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL12 | RCC_CFGR_PLLDIV3); /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) ... /* Enable USB FS Device's APB1 interface clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); b) ADC: in STM32L1 series the ADC features two clock schemes: – Clock for the analog circuitry: ADCCLK. Th is clock is generated always from the HSI clock divided by a programmable prescaler that allows the ADC to work at fHSI/1, /2 or /4. This configuration is done using the ADC registers. – Clock for the digital interface (used for register read/write access). This clock is equal to the APB2 clock. The digital interface clock can be enabled/disabled through the RCC APB2 peripheral clock enable register (RCC_APB2ENR).
5.3 FLASH
STM32F10x functions by the corresponding function in STM32L1xx Library. Table 15. STM32F10x and STM32L1xx FLASH driver API correspondence
Table 15. STM32F10x and STM32L1xx FLASH driver API correspondence (continued)
Firmware migration using the library AN3422 44/52 Doc ID 018976 Rev 2
5.4 GPIO
This section explains how to update the configuration of the various GPIO modes when porting the application code from STM32F1 series to STM32L1 series.
5.4.1 Output mode
The example below shows how to configure an I/O in output mode (for example to drive a led) in STM32F1 series: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_xxMHz; /* 2, 10 or 50 MHz */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOy, &GPIO_InitStructure); In L1 series you have to update this code as follows: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* Push-pull or open drain */ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* None, Pull-up or pull-down */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_xxMHz; /* 400 KHz, 2, 10 or 40MHz */ GPIO_Init(GPIOy, &GPIO_InitStructure);
5.4.2 Input mode
The example below shows how to configure an I/O in input mode (for example to be used as an EXTI line) in STM32F1 series: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOy, &GPIO_InitStructure); In L1 series you have to update this code as follows: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; /* None, Pull-up or pull-down */ GPIO_Init(GPIOy, &GPIO_InitStructure);
5.4.3 Analog mode
The example below shows how to configure an I/O in analog mode (for example an ADC or DAC channel) in STM32F1 series: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOy, &GPIO_InitStructure); In L1 series you have to update this code as follows: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOy, &GPIO_InitStructure);
AN3422 Firmware migration using the library Doc ID 018976 Rev 2 45/52
5.4.4 Alternate function mode
- The configuration to use an I/O as alternate function depends on the peripheral mode used, for example the USART Tx pin should be configured as alternate function push- pull while the USART Rx pin should be configured as input floating or input pull-up. 2. To optimize the number of peripheral I/O functions for different device packages, it is possible by software to remap some alternate functions to other pins, for example the USART2_RX pin can be mapped on PA3 (default remap) or PD6 (by software remap). In STM32L1 series 1. Whatever the peripheral mode used, the I/O must be configured as alternate function, then the system can use the I/O in the proper way (input or output). 2. The I/O pins are connected to onboard peripherals/modules through a multiplexer that allows only one peripheral’s alternate function to be connected to an I/O pin at a time. In this way, there can be no conflict between peripherals sharing the same I/O pin. Each I/O pin has a multiplexer with sixteen alternate function inputs (AF0 to AF15) that can be configured through the GPIO_PinAFConfig () function: – After reset all I/Os are connected to the system’s alternate function 0 (AF0) – The peripherals’ alternate functions are mapped by configuring AF1 to AF13 – Cortex-M3 EVENTOUT is ma pped by configuring AF15 3. In addition to this flexible I/O multiplexing architecture, each peripheral has alternate functions mapped onto different I/O pins to optimize the number of peripheral I/O functions for different device packages, for example the USART2_RX pin can be mapped on PA3 or PD6 pin 4. Configuration procedure – Connect the pin to the desired peripherals' Alternate Function (AF) using GPIO_PinAFConfig() function – Use GPIO_Init() function to configure the I/O pin: - Configure the desired pin in alternate function mode using GPIO_InitStructure->GPIO_Mode = GPIO_Mode_AF; - Select the type, pull-up/pull-down and output speed via GPIO_PuPd, GPIO_OType and GPIO_Speed members The example below shows how to remap USART2 Tx/Rx I/Os on PD5/PD6 pins in STM32F1 series: /* Enable APB2 interface clock for GPIOD and AFIO (AFIO peripheral is used to configure the I/Os software remapping) */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE); /* Enable USART2 I/Os software remapping [(USART2_Tx,USART2_Rx):(PD5,PD6)] */ GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); /* Configure USART2_Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); /* Configure USART2_Rx as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOD, &GPIO_InitStructure);
Firmware migration using the library AN3422 46/52 Doc ID 018976 Rev 2 In L1 series you have to update this code as follows: /* Enable GPIOD's AHB interface clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); /* Select USART2 I/Os mapping on PD5/6 pins [(USART2_TX,USART2_RX):(PD5,PD6)] */ /* Connect PD5 to USART2_Tx */ GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2); /* Connect PD6 to USART2_Rx*/ GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2); /* Configure USART2_Tx and USART2_Rx as alternate function */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOD, &GPIO_InitStructure);
5.5 EXTI
The example below shows how to configure the PA0 pin to be used as EXTI Line0 in STM32F1 series: /* Enable APB interface clock for GPIOA and AFIO */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); /* Configure PA0 pin in input mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Connect EXTI Line0 to PA0 pin */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); /* Configure EXTI line0 */ EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); In L1 series the configuration of the EXTI line source pin is performed in the SYSCFG peripheral (instead of AFIO in F1 series). As result, the source code should be updated as follows: /* Enable GPIOA's AHB interface clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* Enable SYSCFG's APB interface clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); /* Configure PA0 pin in input mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Connect EXTI Line0 to PA0 pin */ SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0); /* Configure EXTI line0 */
AN3422 Firmware migration using the library Doc ID 018976 Rev 2 47/52 EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure);
5.6 ADC
This section gives an example of how to port existing code from STM32F1 series to STM32L1 series. The example below shows how to configure the ADC1 to convert continuously channel14 in STM32F1 series: ... /* ADCCLK = PCLK2/4 */ RCC_ADCCLKConfig(RCC_PCLK2_Div4); /* Enable ADC's APB interface clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* Configure ADC1 to convert continously channel14 */ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); /* Enable ADC1's DMA interface */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); ... In L1 series you have to update this code as follows: ... /* Enable the HSI oscillator */ RCC_HSICmd(ENABLE); /* Check that HSI oscillator is ready */ while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
Firmware migration using the library AN3422 48/52 Doc ID 018976 Rev 2 /* Enable ADC1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* ADCCLK = HSI/1 */ ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div1; ADC_CommonInit(&ADC_CommonInitStructure); /* ADC1 configuration */ ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_4Cycles); /* Enable the request after last transfer for DMA Circular mode */ ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Wait until the ADC1 is ready */ while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET) /* Start ADC1 Software Conversion */ ADC_SoftwareStartConv(ADC1); ... The main changes in the source code/procedure in L1 series vs. F1 are described below: 1. ADC configuration is made through two functions ADC_CommonInit() and ADC_Init(): ADC_CommonInit() function is used to configure the ADC analog clock prescaler. 2. To enable the generation of DMA requests continuously at the end of the last DMA transfer, the ADC_DMARequestAfterLastTransferCmd() function should be used. 3. No calibration is needed
5.7 PWR
The table below presents the PWR driver API correspondence between STM32F10x and STM32L1xx Libraries. Y ou can easily update your application code by replacing STM32F10x functions by the corresponding function in STM32L1xx Library.
Table 16. STM32F10x and STM32L1xx PWR driver API correspondence
Firmware migration using the library AN3422 50/52 Doc ID 018976 Rev 2
5.8 Backup data registers
In STM32F1 series the Backup data registers are managed through the BKP peripheral, while in L1 series they are a part of the RTC peripheral (there is no BKP peripheral). The example below shows how to write to/read from Backup data registers in STM32F1 series: uint16_t BKPdata = 0; ... /* Enable APB2 interface clock for PWR and BKP */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); /* Enable write access to Backup domain */ PWR_BackupAccessCmd(ENABLE); /* Write data to Backup data register 1 */ BKP_WriteBackupRegister(BKP_DR1, 0x3210); /* Read data from Backup data register 1 */ BKPdata = BKP_ReadBackupRegister(BKP_DR1); In L1 series you have to update this code as follows: uint16_t BKPdata = 0; ... /* PWR Clock Enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Enable write access to RTC domain */ PWR_RTCAccessCmd(ENABLE); /* Write data to Backup data register 1 */ RTC_WriteBackupRegister(RTC_BKP_DR1, 0x3220); /* Read data from Backup data register 1 */ BKPdata = RTC_ReadBackupRegister(RTC_BKP_DR1); The main changes in the source code in L1 series vs. F1 are described below: 1. There is no BKP peripheral 2. Write to/read from Backup data registers are done through RTC driver 3. Backup data register s naming changed from BKP_DRx to RTC_BKP_DRx, and numbering starts from 0 instead of 1
6 Revision history
Table 17. Document revision history